1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-03-11 14:49:24 +02:00

refactor of fish_defender

This commit is contained in:
Gerkiz 2020-07-06 23:21:11 +02:00
parent f3a9d0e85e
commit 445cd97532
16 changed files with 1759 additions and 1227 deletions

View File

@ -1,83 +1,99 @@
local FDT = require 'maps.fish_defender.table'
local boss_biter = {}
local math_random = math.random
local radius = 6
local targets = {}
local acid_splashes = {
["big-biter"] = "acid-stream-worm-medium",
["behemoth-biter"] = "acid-stream-worm-big",
["big-spitter"] = "acid-stream-worm-medium",
["behemoth-spitter"] = "acid-stream-worm-big"
['big-biter'] = 'acid-stream-worm-medium',
['behemoth-biter'] = 'acid-stream-worm-big',
['big-spitter'] = 'acid-stream-worm-medium',
['behemoth-spitter'] = 'acid-stream-worm-big'
}
local acid_lines = {
["big-spitter"] = "acid-stream-spitter-medium",
["behemoth-spitter"] = "acid-stream-spitter-big"
['big-spitter'] = 'acid-stream-spitter-medium',
['behemoth-spitter'] = 'acid-stream-spitter-big'
}
for x = radius * -1, radius, 1 do
for y = radius * -1, radius, 1 do
if math.sqrt(x^2 + y^2) <= radius then
targets[#targets + 1] = {x = x, y = y}
end
end
for y = radius * -1, radius, 1 do
if math.sqrt(x ^ 2 + y ^ 2) <= radius then
targets[#targets + 1] = {x = x, y = y}
end
end
end
local function acid_nova(event)
for _ = 1, math.random(16, 32) do
local i = math.random(1, #targets)
event.entity.surface.create_entity({
name = acid_splashes[event.entity.name],
position = event.entity.position,
force = event.entity.force.name,
source = event.entity.position,
target = {x = event.entity.position.x + targets[i].x, y = event.entity.position.y + targets[i].y},
max_range = radius,
speed = 0.001
})
end
for _ = 1, math.random(16, 32) do
local i = math.random(1, #targets)
event.entity.surface.create_entity(
{
name = acid_splashes[event.entity.name],
position = event.entity.position,
force = event.entity.force.name,
source = event.entity.position,
target = {x = event.entity.position.x + targets[i].x, y = event.entity.position.y + targets[i].y},
max_range = radius,
speed = 0.001
}
)
end
end
boss_biter.died = function(event)
if acid_splashes[event.entity.name] then acid_nova(event) end
if global.acid_lines_delay[event.entity.unit_number] then global.acid_lines_delay[event.entity.unit_number] = nil end
global.boss_biters[event.entity.unit_number] = nil
local this = FDT.get()
if acid_splashes[event.entity.name] then
acid_nova(event)
end
if this.acid_lines_delay[event.entity.unit_number] then
this.acid_lines_delay[event.entity.unit_number] = nil
end
this.boss_biters[event.entity.unit_number] = nil
end
local function acid_line(surface, name, source, target)
local distance = math.sqrt((source.x - target.x) ^ 2 + (source.y - target.y) ^ 2)
if distance > 16 then return false end
local modifier = {(target.x - source.x) / distance, (target.y - source.y) / distance}
local position = {source.x, source.y}
for i = 1, distance + 4, 1 do
if math_random(1,3) == 1 then
surface.create_entity({
name = name,
position = source,
force = "enemy",
source = source,
target = position,
max_range = 25,
speed = 1
})
end
position = {position[1] + modifier[1], position[2] + modifier[2]}
end
return true
local distance = math.sqrt((source.x - target.x) ^ 2 + (source.y - target.y) ^ 2)
if distance > 16 then
return false
end
local modifier = {(target.x - source.x) / distance, (target.y - source.y) / distance}
local position = {source.x, source.y}
for i = 1, distance + 4, 1 do
if math_random(1, 3) == 1 then
surface.create_entity(
{
name = name,
position = source,
force = 'enemy',
source = source,
target = position,
max_range = 25,
speed = 1
}
)
end
position = {position[1] + modifier[1], position[2] + modifier[2]}
end
return true
end
boss_biter.damaged_entity = function(event)
if acid_lines[event.cause.name] then
if not global.acid_lines_delay[event.cause.unit_number] then global.acid_lines_delay[event.cause.unit_number] = 0 end
if global.acid_lines_delay[event.cause.unit_number] < game.tick then
if acid_line(event.cause.surface, acid_lines[event.cause.name], event.cause.position, event.entity.position) then
global.acid_lines_delay[event.cause.unit_number] = game.tick + 180
end
end
end
if acid_lines[event.cause.name] then
local this = FDT.get()
if not this.acid_lines_delay[event.cause.unit_number] then
this.acid_lines_delay[event.cause.unit_number] = 0
end
if this.acid_lines_delay[event.cause.unit_number] < game.tick then
if acid_line(event.cause.surface, acid_lines[event.cause.name], event.cause.position, event.entity.position) then
this.acid_lines_delay[event.cause.unit_number] = game.tick + 180
end
end
end
end
return boss_biter
return boss_biter

View File

@ -3,61 +3,75 @@ local math_random = math.random
local math_sqrt = math.sqrt
local ammo_to_projectile_translation = {
["shotgun-shell"] = "shotgun-pellet",
["piercing-shotgun-shell"] = "piercing-shotgun-pellet"
['shotgun-shell'] = 'shotgun-pellet',
['piercing-shotgun-shell'] = 'piercing-shotgun-pellet'
}
local function create_projectile(surface, position, target, name)
surface.create_entity({
name = name,
position = position,
force = force,
source = position,
target = target,
max_range = 16,
speed = 0.3
})
surface.create_entity(
{
name = name,
position = position,
force = force,
source = position,
target = target,
max_range = 16,
speed = 0.3
}
)
end
local function bounce(surface, position, ammo)
if math_random(1,3) ~= 1 then return end
local valid_entities = {}
for _, e in pairs(surface.find_entities_filtered({area = {{position.x - radius, position.y - radius},{position.x + radius, position.y + radius}}})) do
if e.health then
if e.force.name ~= "player" then
--local distance_from_center = math_sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
--if distance_from_center <= radius then
valid_entities[#valid_entities + 1] = e
--end
end
end
end
if not valid_entities[1] then return end
if math_random(1, 3) ~= 1 then
return
end
local valid_entities = {}
for _, e in pairs(
surface.find_entities_filtered(
{area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}}
)
) do
if e.health then
if e.force.name ~= 'player' then
--local distance_from_center = math_sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
--if distance_from_center <= radius then
valid_entities[#valid_entities + 1] = e
--end
end
end
end
for c = 1, math_random(3,6), 1 do
create_projectile(surface, position, valid_entities[math_random(1, #valid_entities)].position, ammo)
end
if not valid_entities[1] then
return
end
for c = 1, math_random(3, 6), 1 do
create_projectile(surface, position, valid_entities[math_random(1, #valid_entities)].position, ammo)
end
end
local function bouncy_shells(event)
if event.damage_type.name ~= "physical" then return false end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then return false end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon.name ~= "combat-shotgun" and selected_weapon.name ~= "shotgun" then return false end
local selected_ammo = player.get_inventory(defines.inventory.character_ammo)[player.selected_gun_index]
if not selected_ammo then return end
if not ammo_to_projectile_translation[selected_ammo.name] then return end
bounce(
player.surface,
event.entity.position,
ammo_to_projectile_translation[selected_ammo.name]
)
if event.damage_type.name ~= 'physical' then
return false
end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then
return false
end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon.name ~= 'combat-shotgun' and selected_weapon.name ~= 'shotgun' then
return false
end
local selected_ammo = player.get_inventory(defines.inventory.character_ammo)[player.selected_gun_index]
if not selected_ammo then
return
end
if not ammo_to_projectile_translation[selected_ammo.name] then
return
end
bounce(player.surface, event.entity.position, ammo_to_projectile_translation[selected_ammo.name])
end
return bouncy_shells

View File

@ -1,15 +1,27 @@
local event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local math_random = math.random
local rock_raffle = {"sand-rock-big", "rock-big", "rock-big", "rock-big", "rock-huge"}
local rock_raffle = {'sand-rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-huge'}
local function on_entity_died(event)
if not global.crumbly_walls_unlocked then return end
local entity = event.entity
if not entity.valid then return end
if entity.name ~= "stone-wall" then return end
if math_random(1,4) == 1 then return end
entity.surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = entity.position, force = "player"})
local crumbly_walls_unlocked = FDT.get('crumbly_walls_unlocked')
if not crumbly_walls_unlocked then
return
end
local entity = event.entity
if not entity.valid then
return
end
if entity.name ~= 'stone-wall' then
return
end
if math_random(1, 4) == 1 then
return
end
entity.surface.create_entity(
{name = rock_raffle[math_random(1, #rock_raffle)], position = entity.position, force = 'player'}
)
end
event.add(defines.events.on_entity_died, on_entity_died)

View File

@ -1,36 +1,46 @@
local radius = 3
local function splash_damage(surface, position, final_damage_amount)
local damage = math.random(math.floor(final_damage_amount * 3), math.floor(final_damage_amount * 4))
for _, e in pairs(surface.find_entities_filtered({area = {{position.x - radius, position.y - radius},{position.x + radius, position.y + radius}}})) do
if e.valid and e.health then
local distance_from_center = math.sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
if distance_from_center <= radius then
local damage_distance_modifier = 1 - distance_from_center / radius
if damage > 0 then
if math.random(1, 3) == 1 then surface.create_entity({name = "explosion", position = e.position}) end
e.damage(damage * damage_distance_modifier, "player", "explosion")
end
end
end
end
local damage = math.random(math.floor(final_damage_amount * 3), math.floor(final_damage_amount * 4))
for _, e in pairs(
surface.find_entities_filtered(
{area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}}
)
) do
if e.valid and e.health then
local distance_from_center = math.sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
if distance_from_center <= radius then
local damage_distance_modifier = 1 - distance_from_center / radius
if damage > 0 then
if math.random(1, 3) == 1 then
surface.create_entity({name = 'explosion', position = e.position})
end
e.damage(damage * damage_distance_modifier, 'player', 'explosion')
end
end
end
end
end
local function explosive_bullets(event)
if math.random(1, 3) ~= 1 then return false end
if event.damage_type.name ~= "physical" then return false end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then return false end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon.name ~= "submachine-gun" and selected_weapon.name ~= "pistol" then return false end
if math.random(1, 3) ~= 1 then
return false
end
if event.damage_type.name ~= 'physical' then
return false
end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then
return false
end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon.name ~= 'submachine-gun' and selected_weapon.name ~= 'pistol' then
return false
end
player.surface.create_entity({name = "explosion", position = event.entity.position})
player.surface.create_entity({name = 'explosion', position = event.entity.position})
splash_damage(
player.surface,
event.entity.position,
event.final_damage_amount
)
splash_damage(player.surface, event.entity.position, event.final_damage_amount)
end
return explosive_bullets

View File

@ -1,40 +1,52 @@
local event = require 'utils.event'
local math_random = math.random
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local function on_player_changed_position(event)
if not global.flame_boots then return end
local player = game.players[event.player_index]
if not player.character then return end
if player.character.driving then return end
if not global.flame_boots[player.index] then global.flame_boots[player.index] = {} end
if not global.flame_boots[player.index].fuel then return end
if global.flame_boots[player.index].fuel < 0 then
player.print("Your flame boots have worn out.", {r = 0.22, g = 0.77, b = 0.44})
global.flame_boots[player.index] = {}
return
end
if global.flame_boots[player.index].fuel % 500 == 0 then player.print("Fuel remaining: " .. global.flame_boots[player.index].fuel, {r = 0.22, g = 0.77, b = 0.44}) end
if not global.flame_boots[player.index].step_history then global.flame_boots[player.index].step_history = {} end
local elements = #global.flame_boots[player.index].step_history
global.flame_boots[player.index].step_history[elements + 1] = {x = player.position.x, y = player.position.y}
if elements < 50 then return end
player.surface.create_entity({name = "fire-flame", position = global.flame_boots[player.index].step_history[elements - 2]})
global.flame_boots[player.index].fuel = global.flame_boots[player.index].fuel - 1
local flame_boots = FDT.get('flame_boots')
if not flame_boots then
return
end
local player = game.players[event.player_index]
if not player.character then
return
end
if player.character.driving then
return
end
if not flame_boots[player.index] then
flame_boots[player.index] = {}
end
if not flame_boots[player.index].fuel then
return
end
if flame_boots[player.index].fuel < 0 then
player.print('Your flame boots have worn out.', {r = 0.22, g = 0.77, b = 0.44})
flame_boots[player.index] = {}
return
end
if flame_boots[player.index].fuel % 500 == 0 then
player.print('Fuel remaining: ' .. flame_boots[player.index].fuel, {r = 0.22, g = 0.77, b = 0.44})
end
if not flame_boots[player.index].step_history then
flame_boots[player.index].step_history = {}
end
local elements = #flame_boots[player.index].step_history
flame_boots[player.index].step_history[elements + 1] = {x = player.position.x, y = player.position.y}
if elements < 50 then
return
end
player.surface.create_entity({name = 'fire-flame', position = flame_boots[player.index].step_history[elements - 2]})
flame_boots[player.index].fuel = flame_boots[player.index].fuel - 1
end
local function on_init()
if not global.flame_boots then global.flame_boots = {} end
end
event.on_init(on_init)
event.add(defines.events.on_player_changed_position, on_player_changed_position)
Event.add(defines.events.on_player_changed_position, on_player_changed_position)

View File

@ -1,31 +1,37 @@
local event = require 'utils.event'
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local radius = 32
local function on_player_used_capsule(event)
if not global.laser_pointer_unlocked then return end
local player = game.players[event.player_index]
local position = event.position
local used_item = event.item
if used_item.name ~= "artillery-targeting-remote" then return end
local laser_pointer_unlocked = FDT.get('laser_pointer_unlocked')
if not laser_pointer_unlocked then
return
end
for _, unit in pairs(player.surface.find_enemy_units(position, radius, "player")) do
if math.random(1,2) == 1 then
unit.set_command({
type = defines.command.go_to_location,
destination = position,
radius = 2,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = false
}
})
end
end
local player = game.players[event.player_index]
local position = event.position
local used_item = event.item
if used_item.name ~= 'artillery-targeting-remote' then
return
end
for _, unit in pairs(player.surface.find_enemy_units(position, radius, 'player')) do
if math.random(1, 2) == 1 then
unit.set_command(
{
type = defines.command.go_to_location,
destination = position,
radius = 2,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = false
}
}
)
end
end
end
event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)

View File

@ -2,28 +2,31 @@
--require "modules.rpg"
require 'maps.fish_defender.terrain'
require 'maps.fish_defender.market'
require 'maps.fish_defender.shotgun_buff'
require 'maps.fish_defender.on_entity_damaged'
require 'modules.rocket_launch_always_yields_science'
require 'modules.launch_fish_to_win'
require 'modules.biters_yield_coins'
require 'modules.dangerous_goods'
require 'modules.custom_death_messages'
local Terrain = require 'maps.fish_defender.terrain'
local Unit_health_booster = require 'modules.biter_health_booster'
local Difficulty = require 'modules.difficulty_vote'
local Map = require 'modules.map_info'
local event = require 'utils.event'
local Reset = require 'functions.soft_reset'
local Server = require 'utils.server'
local Poll = require 'comfy_panel.poll'
local boss_biter = require 'maps.fish_defender.boss_biters'
local FDT = require 'maps.fish_defender.table'
local Score = require 'comfy_panel.score'
local math_random = math.random
local insert = table.insert
local enable_start_grace_period = true
map_height = 96
local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['raw-fish'] = 3, ['iron-plate'] = 32}
local biter_count_limit = 1024 --maximum biters on the east side of the map, next wave will be delayed if the maximum has been reached
local boss_waves = {
@ -66,15 +69,16 @@ local function create_wave_gui(player)
if player.gui.top['fish_defense_waves'] then
player.gui.top['fish_defense_waves'].destroy()
end
local this = FDT.get()
local frame = player.gui.top.add({type = 'frame', name = 'fish_defense_waves', tooltip = 'Click to show map info'})
frame.style.maximal_height = 38
local wave_count = 0
if global.wave_count then
wave_count = global.wave_count
if this.wave_count then
wave_count = this.wave_count
end
if not global.wave_grace_period then
if not this.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'
@ -83,17 +87,16 @@ local function create_wave_gui(player)
label.style.minimal_width = 68
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
local next_level_progress = game.tick % global.wave_interval / global.wave_interval
local next_level_progress = game.tick % this.wave_interval / this.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)
local time_remaining = math.floor(((this.wave_grace_period - (game.tick % this.wave_grace_period)) / 60) / 60)
if time_remaining <= 0 then
global.wave_grace_period = nil
this.wave_grace_period = nil
return
end
@ -105,7 +108,7 @@ local function create_wave_gui(player)
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
if not enable_start_grace_period then
global.wave_grace_period = nil
this.wave_grace_period = nil
return
end
end
@ -114,6 +117,7 @@ end
local function show_fd_stats(player)
local gui_id = 'fd-stats'
local table_id = gui_id .. 'table'
local entity_limits = FDT.get('entity_limits')
if player.gui.left[gui_id] then
player.gui.left[gui_id].destroy()
@ -137,7 +141,7 @@ local function show_fd_stats(player)
h.style.font = 'heading-2'
end
for k, v in pairs(global.entity_limits) do
for k, v in pairs(entity_limits) do
local name = v.str
local placed = v.placed
local limit = v.limit
@ -204,15 +208,16 @@ local threat_values = {
}
local function get_biter_initial_pool()
local biter_pool = {}
if global.wave_count > 1750 then
local wave_count = FDT.get('wave_count')
local biter_pool
if wave_count > 1750 then
biter_pool = {
{name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2},
{name = 'behemoth-spitter', threat = threat_values.behemoth_spitter, weight = 1}
}
return biter_pool
end
if global.wave_count > 1500 then
if wave_count > 1500 then
biter_pool = {
{name = 'big-biter', threat = threat_values.big_biter, weight = 1},
{name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2},
@ -220,7 +225,7 @@ local function get_biter_initial_pool()
}
return biter_pool
end
if global.wave_count > 1250 then
if wave_count > 1250 then
biter_pool = {
{name = 'big-biter', threat = threat_values.big_biter, weight = 2},
{name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2},
@ -228,7 +233,7 @@ local function get_biter_initial_pool()
}
return biter_pool
end
if global.wave_count > 1000 then
if 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},
@ -336,7 +341,6 @@ local function get_biter_initial_pool()
end
local function get_biter_pool()
local surface = game.surfaces['fish_defender']
local biter_pool = get_biter_initial_pool()
local biter_raffle = {}
for _, biter_type in pairs(biter_pool) do
@ -348,12 +352,14 @@ local function get_biter_pool()
end
local function spawn_biter(pos, biter_pool)
if global.attack_wave_threat < 1 then
local this = FDT.get()
if this.attack_wave_threat < 1 then
return false
end
local surface = game.surfaces['fish_defender']
local surface = this.active_surface
biter_pool = shuffle(biter_pool)
global.attack_wave_threat = global.attack_wave_threat - biter_pool[1].threat
this.attack_wave_threat = this.attack_wave_threat - biter_pool[1].threat
local valid_pos = surface.find_non_colliding_position(biter_pool[1].name, pos, 100, 2)
local biter = surface.create_entity({name = biter_pool[1].name, position = valid_pos})
biter.ai_settings.allow_destroy_when_commands_fail = false
@ -383,8 +389,9 @@ local attack_group_count_thresholds = {
local function get_number_of_attack_groups()
local n = 1
local this = FDT.get()
for _, entry in pairs(attack_group_count_thresholds) do
if global.wave_count >= entry[1] then
if this.wave_count >= entry[1] then
n = entry[2]
end
end
@ -392,14 +399,16 @@ local function get_number_of_attack_groups()
end
local function clear_corpses(surface)
if not global.wave_count then
local wave_count = FDT.get('wave_count')
if not wave_count then
return
end
local chance = 4
if global.wave_count > 250 then
if wave_count > 250 then
chance = 3
end
if global.wave_count > 500 then
if wave_count > 500 then
chance = 2
end
for _, entity in pairs(surface.find_entities_filtered {type = 'corpse'}) do
@ -409,52 +418,10 @@ local function clear_corpses(surface)
end
end
local boss_wave_names = {
[50] = 'The Big Biter Gang',
[100] = 'Biterzilla',
[150] = 'The Spitter Squad',
[200] = 'The Wall Nibblers',
[250] = 'Conveyor Munchers',
[300] = 'Furnace Freezers',
[350] = 'Cable Chewers',
[400] = 'Power Pole Thieves',
[450] = 'Assembler Annihilators',
[500] = 'Inserter Crunchers',
[550] = 'Engineer Eaters',
[600] = 'Belt Unbalancers',
[650] = 'Turret Devourers',
[700] = 'Pipe Perforators',
[750] = 'Desync Bros',
[800] = 'Ratio Randomizers',
[850] = 'Wire Chompers',
[900] = 'The Bus Mixers',
[950] = 'Roundabout Deadlockers',
[1000] = 'Happy Tree Friends',
[1050] = 'Uranium Digesters',
[1100] = 'Bot Banishers',
[1150] = 'Chest Crushers',
[1200] = 'Cargo Wagon Scratchers',
[1250] = 'Transport Belt Surfers',
[1300] = 'Pumpjack Pulverizers',
[1350] = 'Radar Ravagers',
[1400] = 'Mall Deconstrutors',
[1450] = 'Lamp Dimmers',
[1500] = 'Roboport Disablers',
[1550] = 'Signal Spammers',
[1600] = 'Brick Tramplers',
[1650] = 'Drill Destroyers',
[1700] = 'Gearwheel Grinders',
[1750] = 'Silo Seekers',
[1800] = 'Circuit Breakers',
[1850] = 'Bullet Absorbers',
[1900] = 'Oil Guzzlers',
[1950] = 'Belt Rotators',
[2000] = 'Bluescreen Factor'
}
local function send_unit_group(unit_group)
local commands = {}
for x = unit_group.position.x, global.market.position.x, -48 do
local market = FDT.get('market')
for x = unit_group.position.x, market.position.x, -48 do
local destination =
unit_group.surface.find_non_colliding_position('stone-wall', {x = x, y = unit_group.position.y}, 32, 4)
if destination then
@ -468,13 +435,13 @@ local function send_unit_group(unit_group)
end
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = global.market.position.x, y = unit_group.position.y},
destination = {x = market.position.x, y = unit_group.position.y},
radius = 16,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.attack,
target = global.market,
target = market,
distraction = defines.distraction.by_enemy
}
@ -489,42 +456,43 @@ end
local function spawn_boss_units(surface)
local Diff = Difficulty.get()
if global.wave_count <= 2000 then
local this = FDT.get()
if this.wave_count <= 2000 then
game.print(
{'fish_defender.boss_message', global.wave_count, {'fish_defender.' .. global.wave_count}},
{'fish_defender.boss_message', this.wave_count, {'fish_defender.' .. this.wave_count}},
{r = 0.8, g = 0.1, b = 0.1}
)
else
game.print({'fish_defender.boss_message', global.wave_count}, {r = 0.8, g = 0.1, b = 0.1})
game.print({'fish_defender.boss_message', this.wave_count}, {r = 0.8, g = 0.1, b = 0.1})
end
if not boss_waves[global.wave_count] then
local amount = global.wave_count
if not boss_waves[this.wave_count] then
local amount = this.wave_count
if amount > 1000 then
amount = 1000
end
boss_waves[global.wave_count] = {
boss_waves[this.wave_count] = {
{name = 'behemoth-biter', count = math.floor(amount / 20)},
{name = 'behemoth-spitter', count = math.floor(amount / 40)}
}
end
local health_factor = difficulties_votes[Diff.difficulty_vote_index].boss_modifier
if global.wave_count == 100 then
if this.wave_count == 100 then
health_factor = health_factor * 2
end
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 _, entry in pairs(boss_waves[this.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.ai_settings.allow_destroy_when_commands_fail = false
biter.ai_settings.allow_try_return_to_spawner = false
global.boss_biters[biter.unit_number] = biter
Unit_health_booster.add_boss_unit(biter, global.biter_health_boost * health_factor, 0.55)
this.boss_biters[biter.unit_number] = biter
Unit_health_booster.add_boss_unit(biter, this.biter_health_boost * health_factor, 0.55)
biter_group.add_member(biter)
end
end
@ -534,7 +502,8 @@ local function spawn_boss_units(surface)
end
local function wake_up_the_biters(surface)
if not global.market then
local market = FDT.get('market')
if not market then
return
end
@ -579,7 +548,7 @@ local function wake_up_the_biters(surface)
{
command = {
type = defines.command.attack,
target = global.market,
target = market,
distraction = defines.distraction.none
},
unit_count = 16,
@ -616,14 +585,15 @@ end
local function biter_attack_wave()
local Diff = Difficulty.get()
local this = FDT.get()
if not global.market then
if not this.market then
return
end
if global.wave_grace_period then
if this.wave_grace_period then
return
end
local surface = game.surfaces['fish_defender']
local surface = this.active_surface
clear_corpses(surface)
wake_up_the_biters(surface)
@ -633,50 +603,50 @@ local function biter_attack_wave()
return
end
if not global.wave_count then
global.wave_count = 1
if not this.wave_count then
this.wave_count = 1
else
global.wave_count = global.wave_count + 1
this.wave_count = this.wave_count + 1
end
local m = 0.0015
if Diff.difficulty_vote_index then
m = m * difficulties_votes[Diff.difficulty_vote_index].strength_modifier
end
game.forces.enemy.set_ammo_damage_modifier('melee', global.wave_count * m)
game.forces.enemy.set_ammo_damage_modifier('biological', global.wave_count * m)
global.biter_health_boost = 1 + (global.wave_count * (m * 2))
game.forces.enemy.set_ammo_damage_modifier('melee', this.wave_count * m)
game.forces.enemy.set_ammo_damage_modifier('biological', this.wave_count * m)
this.biter_health_boost = 1 + (this.wave_count * (m * 2))
local m = 4
if Diff.difficulty_vote_index then
m = m * difficulties_votes[Diff.difficulty_vote_index].amount_modifier
end
if global.wave_count % 50 == 0 then
global.attack_wave_threat = math.floor(global.wave_count * (m * 1.5))
if this.wave_count % 50 == 0 then
this.attack_wave_threat = math.floor(this.wave_count * (m * 1.5))
spawn_boss_units(surface)
if global.attack_wave_threat > 10000 then
global.attack_wave_threat = 10000
if this.attack_wave_threat > 10000 then
this.attack_wave_threat = 10000
end
else
global.attack_wave_threat = math.floor(global.wave_count * m)
if global.attack_wave_threat > 10000 then
global.attack_wave_threat = 10000
this.attack_wave_threat = math.floor(this.wave_count * m)
if this.attack_wave_threat > 10000 then
this.attack_wave_threat = 10000
end
end
local evolution = global.wave_count * 0.00125
local evolution = this.wave_count * 0.00125
if evolution > 1 then
evolution = 1
end
game.forces.enemy.evolution_factor = evolution
--if game.forces.enemy.evolution_factor == 1 then
-- if not global.endgame_modifier then
-- global.endgame_modifier = 1
-- if not this.endgame_modifier then
-- this.endgame_modifier = 1
-- game.print("Endgame enemy evolution reached.", {r = 0.7, g = 0.1, b = 0.1})
-- else
-- global.endgame_modifier = global.endgame_modifier + 1
-- this.endgame_modifier = this.endgame_modifier + 1
-- end
--end
@ -687,7 +657,7 @@ local function biter_attack_wave()
local y_raffle = get_y_coord_raffle_table()
local unit_groups = {}
if global.wave_count > 50 and math_random(1, 8) == 1 then
if this.wave_count > 50 and math_random(1, 8) == 1 then
for i = 1, 10, 1 do
unit_groups[i] = surface.create_unit_group({position = {x = 256, y = y_raffle[i]}})
end
@ -701,7 +671,7 @@ local function biter_attack_wave()
--local spawners = surface.find_entities_filtered({type = "unit-spawner", area = {{160, -196},{512, 196}}})
--table.shuffle_table(spawners)
while global.attack_wave_threat > 0 do
while this.attack_wave_threat > 0 do
for i = 1, #unit_groups, 1 do
--local biter
--if spawners[i] then
@ -786,10 +756,13 @@ local function get_mvps()
end
local function is_game_lost()
if global.market then
local market = FDT.get('market')
if market then
return
end
local this = FDT.get()
for _, player in pairs(game.connected_players) do
if player.gui.left['fish_defense_game_lost'] then
return
@ -810,19 +783,19 @@ local function is_game_lost()
l.style.font = 'default-listbox'
l.style.font_color = {r = 0.22, g = 0.77, b = 0.44}
if global.market_age >= 216000 then
if this.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'
caption = math.floor(((this.market_age / 60) / 60) / 60) ..
' hours ' .. math.ceil((this.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'})
local l = t.add({type = 'label', caption = math.ceil((this.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
@ -857,7 +830,7 @@ local function is_game_lost()
l.style.font = 'default-bold'
l.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
if not global.results_sent then
if not this.results_sent then
local result = {}
insert(result, 'MVP Defender: \\n')
insert(result, mvp.killscore.name .. ' with a score of ' .. mvp.killscore.score .. '\\n')
@ -869,7 +842,7 @@ local function is_game_lost()
insert(result, mvp.deaths.name .. ' died ' .. mvp.deaths.score .. ' times')
local message = table.concat(result)
Server.to_discord_embed(message)
global.results_sent = true
this.results_sent = true
end
end
@ -910,13 +883,14 @@ local function damage_entities_in_radius(surface, position, radius, damage)
end
local function market_kill_visuals()
local market = FDT.get('market')
local m = 32
local m2 = m * 0.005
for i = 1, 1024, 1 do
global.market.surface.create_particle(
market.surface.create_particle(
{
name = 'branch-particle',
position = global.market.position,
position = market.position,
frame_speed = 0.1,
vertical_speed = 0.1,
height = 0.1,
@ -927,24 +901,24 @@ local function market_kill_visuals()
for x = -5, 5, 0.5 do
for y = -5, 5, 0.5 do
if math_random(1, 2) == 1 then
global.market.surface.create_trivial_smoke(
market.surface.create_trivial_smoke(
{
name = 'smoke-fast',
position = {global.market.position.x + (x * 0.35), global.market.position.y + (y * 0.35)}
position = {market.position.x + (x * 0.35), market.position.y + (y * 0.35)}
}
)
end
if math_random(1, 3) == 1 then
global.market.surface.create_trivial_smoke(
market.surface.create_trivial_smoke(
{
name = 'train-smoke',
position = {global.market.position.x + (x * 0.35), global.market.position.y + (y * 0.35)}
position = {market.position.x + (x * 0.35), market.position.y + (y * 0.35)}
}
)
end
end
end
global.market.surface.spill_item_stack(global.market.position, {name = 'raw-fish', count = 1024}, true)
market.surface.spill_item_stack(market.position, {name = 'raw-fish', count = 1024}, true)
end
local biter_splash_damage = {
@ -976,10 +950,12 @@ local function on_entity_died(event)
return
end
local this = FDT.get()
if event.entity.force.name == 'enemy' then
local surface = event.entity.surface
if global.boss_biters[event.entity.unit_number] then
if this.boss_biters[event.entity.unit_number] then
boss_biter.died(event)
end
@ -1016,21 +992,23 @@ local function on_entity_died(event)
return
end
if event.entity == global.market then
if event.entity == this.market then
market_kill_visuals()
global.market = nil
global.market_age = game.tick
this.market = nil
this.market_age = game.tick - this.last_reset
is_game_lost()
end
if global.entity_limits[event.entity.name] then
global.entity_limits[event.entity.name].placed = global.entity_limits[event.entity.name].placed - 1
if this.entity_limits[event.entity.name] then
this.entity_limits[event.entity.name].placed = this.entity_limits[event.entity.name].placed - 1
update_fd_stats()
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
local show_floating_killscore = FDT.get('show_floating_killscore')
local active_surface = FDT.get('active_surface')
if player.online_time == 0 then
player.insert({name = 'pistol', count = 1})
@ -1038,12 +1016,12 @@ local function on_player_joined_game(event)
player.insert({name = 'raw-fish', count = 3})
player.insert({name = 'firearm-magazine', count = 16})
player.insert({name = 'iron-plate', count = 32})
if global.show_floating_killscore then
global.show_floating_killscore[player.name] = false
if show_floating_killscore then
FDT.get().show_floating_killscore[player.name] = false
end
end
local surface = game.surfaces['fish_defender']
local surface = active_surface
if player.online_time < 2 and surface.is_chunk_generated({0, 0}) then
player.teleport(
surface.find_non_colliding_position('character', game.forces['player'].get_spawn_position(surface), 50, 1),
@ -1062,30 +1040,30 @@ local function on_player_joined_game(event)
is_game_lost()
end
--if global.charting_done then return end
--if this.charting_done then return end
--game.forces.player.chart(game.surfaces["fish_defender"], {{-256, -512},{768, 512}})
--global.charting_done = true
--this.charting_done = true
end
local function on_built_entity(event)
local get_score = Score.get_table().score_table
local this = FDT.get()
local entity = event.created_entity
if not entity.valid then
return
end
if global.entity_limits[entity.name] then
if this.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
if this.entity_limits[entity.name].placed < this.entity_limits[entity.name].limit then
this.entity_limits[entity.name].placed = this.entity_limits[entity.name].placed + 1
surface.create_entity(
{
name = 'flying-text',
position = entity.position,
text = global.entity_limits[entity.name].placed ..
text = this.entity_limits[entity.name].placed ..
' / ' ..
global.entity_limits[entity.name].limit ..
' ' .. global.entity_limits[entity.name].str .. 's',
this.entity_limits[entity.name].limit .. ' ' .. this.entity_limits[entity.name].str .. 's',
color = {r = 0.98, g = 0.66, b = 0.22}
}
)
@ -1095,7 +1073,7 @@ local function on_built_entity(event)
{
name = 'flying-text',
position = entity.position,
text = global.entity_limits[entity.name].str .. ' limit reached.',
text = this.entity_limits[entity.name].str .. ' limit reached.',
color = {r = 0.82, g = 0.11, b = 0.11}
}
)
@ -1116,18 +1094,17 @@ end
local function on_robot_built_entity(event)
local entity = event.created_entity
if global.entity_limits[entity.name] then
local entity_limits = FDT.get('entity_limits')
if 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
if entity_limits[entity.name].placed < entity_limits[entity.name].limit then
entity_limits[entity.name].placed = 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',
text = entity_limits[entity.name].placed ..
' / ' .. entity_limits[entity.name].limit .. ' ' .. entity_limits[entity.name].str .. 's',
color = {r = 0.98, g = 0.66, b = 0.22}
}
)
@ -1137,7 +1114,7 @@ local function on_robot_built_entity(event)
{
name = 'flying-text',
position = entity.position,
text = global.entity_limits[entity.name].str .. ' limit reached.',
text = entity_limits[entity.name].str .. ' limit reached.',
color = {r = 0.82, g = 0.11, b = 0.11}
}
)
@ -1148,130 +1125,17 @@ local function on_robot_built_entity(event)
end
end
local function on_tick()
local function on_init()
local Diff = Difficulty.get()
if game.tick % 30 == 0 then
if global.market then
for _, player in pairs(game.connected_players) do
if game.surfaces['fish_defender'].peaceful_mode == false then
create_wave_gui(player)
end
end
end
if game.tick % 180 == 0 then
if game.surfaces['fish_defender'] then
game.forces.player.chart(game.surfaces['fish_defender'], {{-160, -128}, {192, 128}})
if Diff.difficulty_vote_index then
global.wave_interval = difficulties_votes[Diff.difficulty_vote_index].wave_interval
end
end
end
local get_score = Score.get_table()
if global.market_age then
if not global.game_restart_timer then
global.game_restart_timer = 10800
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 % 1800 == 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)
local this = FDT.get()
local message = 'Map is restarting! '
Server.to_discord_bold(table.concat {'*** ', message, ' ***'})
Server.start_scenario('Fish_Defender')
end
end
end
end
FDT.reset_table()
Poll.reset()
if game.tick % global.wave_interval == global.wave_interval - 1 then
if game.surfaces['fish_defender'].peaceful_mode == true then
return
end
biter_attack_wave()
end
end
local function on_player_changed_position(event)
local player = game.players[event.player_index]
if player.position.x + player.position.y < 0 then
return
end
if player.position.x < player.position.y then
return
end
if player.position.x >= 160 then
player.teleport({player.position.x - 1, player.position.y}, game.surfaces['fish_defender'])
if player.position.y > map_height or player.position.y < map_height * -1 then
player.teleport({player.position.x, 0}, game.surfaces['fish_defender'])
end
if player.character then
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
end
end
end
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
update_fd_stats()
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
update_fd_stats()
end
end
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
local function on_player_respawned(event)
if not global.market_age then
return
end
local player = game.players[event.player_index]
player.character.destructible = false
end
local function on_init(event)
local Diff = Difficulty.get()
global.wave_interval = 3600 --interval between waves in ticks
global.wave_grace_period = 3600 * 20
Diff.difficulty_poll_closing_timeout = global.wave_grace_period
global.boss_biters = {}
global.acid_lines_delay = {}
global.entity_limits = {
['gun-turret'] = {placed = 1, limit = 1, str = 'gun turret', slot_price = 75},
['laser-turret'] = {placed = 0, limit = 1, str = 'laser turret', slot_price = 300},
['artillery-turret'] = {placed = 0, limit = 1, str = 'artillery turret', slot_price = 500},
['flamethrower-turret'] = {placed = 0, limit = 0, str = 'flamethrower turret', slot_price = 50000},
['land-mine'] = {placed = 0, limit = 1, str = 'mine', slot_price = 1}
}
Diff.difficulty_poll_closing_timeout = this.wave_grace_period
get_score.score_table = {}
local map_gen_settings = {}
map_gen_settings.height = 2048
@ -1288,8 +1152,19 @@ local function on_init(event)
['trees'] = {frequency = 2, size = 1, richness = 1},
['enemy-base'] = {frequency = 'none', size = 'none', richness = 'none'}
}
game.create_surface('fish_defender', map_gen_settings)
local surface = game.surfaces['fish_defender']
if not this.active_surface_index then
this.active_surface_index = game.create_surface('fish_defender', map_gen_settings).index
this.active_surface = game.surfaces[this.active_surface_index]
else
this.active_surface_index =
Reset.soft_reset_map(game.surfaces[this.active_surface_index], map_gen_settings, starting_items).index
this.active_surface = game.surfaces[this.active_surface_index]
end
local surface = this.active_surface
surface.peaceful_mode = false
game.map_settings.enemy_expansion.enabled = false
game.map_settings.enemy_evolution.destroy_factor = 0
@ -1297,27 +1172,156 @@ local function on_init(event)
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.pollution.enabled = false
Difficulty.reset_difficulty_poll()
Difficulty.set_poll_closing_timeout(game.tick + 35 * 60 * 60)
game.forces['player'].technologies['atomic-bomb'].enabled = false
--game.forces["player"].technologies["landfill"].enabled = false
game.create_force('decoratives')
if not game.forces.decoratives then
game.create_force('decoratives')
end
game.forces['decoratives'].set_cease_fire('enemy', true)
game.forces['enemy'].set_cease_fire('decoratives', true)
game.forces['player'].set_cease_fire('decoratives', true)
global.comfylatron_habitat = {
left_top = {x = -1500, y = -1500},
right_bottom = {x = -80, y = 1500}
}
Terrain.fish_eye(surface, {x = -2150, y = -300})
fish_eye(surface, {x = -2150, y = -300})
global.chunk_queue = {}
game.map_settings.enemy_expansion.enabled = false
game.forces['player'].technologies['artillery'].researched = false
game.reset_time_played()
local T = Map.Pop_info()
T.localised_category = 'fish_defender'
T.main_caption_color = {r = 0.11, g = 0.8, b = 0.44}
T.sub_caption_color = {r = 0.33, g = 0.66, b = 0.9}
for _, player in pairs(game.connected_players) do
if player.gui.left['fish_defense_game_lost'] then
player.gui.left['fish_defense_game_lost'].destroy()
end
end
local mgs = game.surfaces['nauvis'].map_gen_settings
mgs.width = 16
mgs.height = 16
game.surfaces['nauvis'].map_gen_settings = mgs
game.surfaces['nauvis'].clear()
end
local function on_tick()
local Diff = Difficulty.get()
local active_surface = FDT.get('active_surface')
local this = FDT.get()
local surface = active_surface
if game.tick % 30 == 0 then
if this.market then
for _, player in pairs(game.connected_players) do
if surface.peaceful_mode == false then
create_wave_gui(player)
end
end
end
if game.tick % 180 == 0 then
if surface then
game.forces.player.chart(surface, {{-160, -128}, {192, 128}})
if Diff.difficulty_vote_index then
this.wave_interval = difficulties_votes[Diff.difficulty_vote_index].wave_interval
end
end
end
if this.market_age then
if not this.game_restart_timer then
this.game_restart_timer = 10800
else
if this.game_restart_timer < 0 then
return
end
this.game_restart_timer = this.game_restart_timer - 30
end
if this.game_restart_timer % 1800 == 0 then
if this.game_restart_timer > 0 then
this.game_reset = true
this.game_has_ended = true
game.print(
'Map will restart in ' .. this.game_restart_timer / 60 .. ' seconds!',
{r = 0.22, g = 0.88, b = 0.22}
)
end
if this.game_restart_timer == 0 then
on_init()
end
end
end
end
if game.tick % this.wave_interval == this.wave_interval - 1 then
if surface.peaceful_mode == true then
return
end
biter_attack_wave()
end
end
local function on_player_changed_position(event)
local player = game.players[event.player_index]
local active_surface = FDT.get('active_surface')
local map_height = FDT.get('map_height')
local surface = active_surface
if player.position.x + player.position.y < 0 then
return
end
if player.position.x < player.position.y then
return
end
if player.position.x >= 160 then
player.teleport({player.position.x - 1, player.position.y}, surface)
if player.position.y > map_height or player.position.y < map_height * -1 then
player.teleport({player.position.x, 0}, surface)
end
if player.character then
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
end
end
end
local function on_player_mined_entity(event)
local this = FDT.get()
if this.entity_limits[event.entity.name] then
this.entity_limits[event.entity.name].placed = this.entity_limits[event.entity.name].placed - 1
update_fd_stats()
end
end
local function on_robot_mined_entity(event)
local this = FDT.get()
if this.entity_limits[event.entity.name] then
this.entity_limits[event.entity.name].placed = this.entity_limits[event.entity.name].placed - 1
update_fd_stats()
end
end
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
local function on_player_respawned(event)
local market_age = FDT.get('market_age')
if not market_age then
return
end
local player = game.players[event.player_index]
player.character.destructible = false
end
event.add(defines.events.on_gui_click, on_gui_click)
@ -1334,4 +1338,4 @@ event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity)
event.add(defines.events.on_tick, on_tick)
event.on_init(on_init)
require 'modules.difficulty_vote'
return on_init

View File

@ -5,263 +5,347 @@ require 'maps.fish_defender.crumbly_walls'
require 'maps.fish_defender.vehicle_nanobots'
require 'maps.fish_defender.laser_pointer'
local event = require 'utils.event'
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local Server = require 'utils.server'
local slot_upgrade_offers = {
[1] = {"gun-turret", "gun turret"},
[2] = {"laser-turret", "laser turret"},
[3] = {"artillery-turret", "artillery turret"},
[4] = {"flamethrower-turret", "flamethrower turret"},
[5] = {"land-mine", "land mine"}
}
[1] = {'gun-turret', 'gun turret'},
[2] = {'laser-turret', 'laser turret'},
[3] = {'artillery-turret', 'artillery turret'},
[4] = {'flamethrower-turret', 'flamethrower turret'},
[5] = {'land-mine', 'land mine'}
}
local special_descriptions = {
["flame-boots"] = "Flame Boots - Get yourself some hot boots.",
["explosive-bullets"] = "Unlock Explosive Bullets - Submachine-Gun and Pistol gains a chance to deal splash damage.",
["bouncy-shells"] = "Unlock Bouncy Shells - Shotgun projectiles may bounce to multiple targets.",
["trapped-capsules"] = "Unlock Trapped Capsules - Combat robots will send a last deadly projectile to a nearby enemy when killed.",
["ultra-mines"] = "Unlock Ultra Mines - Careful with these...",
["railgun-enhancer"] = "Unlock Railgun Enhancer - Turns the railgun into a powerful forking gun.",
["crumbly-walls"] = "Unlock Crumbly Walls - Fortifications which crumble, may turn into rocks.",
["vehicle-nanobots"] = "Unlock Vehicle Nanobots - Vehicles repair rapidly while driving.",
["laser-pointer"] = "Unlock Laser Pointer - The biters are on a quest to slay the red (artillery) dot."
['flame-boots'] = 'Flame Boots - Get yourself some hot boots.',
['explosive-bullets'] = 'Unlock Explosive Bullets - Submachine-Gun and Pistol gains a chance to deal splash damage.',
['bouncy-shells'] = 'Unlock Bouncy Shells - Shotgun projectiles may bounce to multiple targets.',
['trapped-capsules'] = 'Unlock Trapped Capsules - Combat robots will send a last deadly projectile to a nearby enemy when killed.',
['ultra-mines'] = 'Unlock Ultra Mines - Careful with these...',
['railgun-enhancer'] = 'Unlock Railgun Enhancer - Turns the railgun into a powerful forking gun.',
['crumbly-walls'] = 'Unlock Crumbly Walls - Fortifications which crumble, may turn into rocks.',
['vehicle-nanobots'] = 'Unlock Vehicle Nanobots - Vehicles repair rapidly while driving.',
['laser-pointer'] = 'Unlock Laser Pointer - The biters are on a quest to slay the red (artillery) dot.'
}
function place_fish_market(surface, position)
local market = surface.create_entity({name = "market", position = position, force = "player"})
market.minable = false
return market
local market = surface.create_entity({name = 'market', position = position, force = 'player'})
market.minable = false
return market
end
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
local this = FDT.get()
if not this.market then
return
end
for i = 1, 100, 1 do
local a = this.market.remove_market_item(1)
if a == false then
break
end
end
local str1 =
'Gun Turret Slot for ' ..
tostring(this.entity_limits['gun-turret'].limit * this.entity_limits['gun-turret'].slot_price)
str1 = str1 .. ' Coins.'
local str2 =
'Laser Turret Slot for ' ..
tostring(this.entity_limits['laser-turret'].limit * this.entity_limits['laser-turret'].slot_price)
str2 = str2 .. ' Coins.'
local str3 =
'Artillery Slot for ' ..
tostring(this.entity_limits['artillery-turret'].limit * this.entity_limits['artillery-turret'].slot_price)
str3 = str3 .. ' Coins.'
local current_limit = 1
if this.entity_limits['flamethrower-turret'].limit ~= 0 then
current_limit = current_limit + this.entity_limits['flamethrower-turret'].limit
end
local str4 =
'Flamethrower Turret Slot for ' ..
tostring(current_limit * this.entity_limits['flamethrower-turret'].slot_price)
str4 = str4 .. ' Coins.'
local str5 =
'Landmine Slot for ' ..
tostring(math.ceil((this.entity_limits['land-mine'].limit / 3) * this.entity_limits['land-mine'].slot_price))
str5 = str5 .. ' Coins.'
local market_items = {
{price = {}, offer = {type = 'nothing', effect_description = str1}},
{price = {}, offer = {type = 'nothing', effect_description = str2}},
{price = {}, offer = {type = 'nothing', effect_description = str3}},
{price = {}, offer = {type = 'nothing', effect_description = str4}},
{price = {}, offer = {type = 'nothing', effect_description = str5}},
{price = {{'coin', 5}}, offer = {type = 'give-item', item = 'raw-fish', count = 1}},
{price = {{'coin', 1}}, offer = {type = 'give-item', item = 'wood', count = 8}},
{price = {{'coin', 8}}, offer = {type = 'give-item', item = 'grenade', count = 1}},
{price = {{'coin', 32}}, offer = {type = 'give-item', item = 'cluster-grenade', count = 1}},
{price = {{'coin', 1}}, offer = {type = 'give-item', item = 'land-mine', count = 1}},
{price = {{'coin', 80}}, offer = {type = 'give-item', item = 'car', count = 1}},
{price = {{'coin', 1200}}, offer = {type = 'give-item', item = 'tank', count = 1}},
{price = {{'coin', 3}}, offer = {type = 'give-item', item = 'cannon-shell', count = 1}},
{price = {{'coin', 7}}, offer = {type = 'give-item', item = 'explosive-cannon-shell', count = 1}},
{price = {{'coin', 50}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
{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', 10}}, offer = {type = 'give-item', item = 'artillery-shell', count = 1}},
{price = {{'coin', 25}}, offer = {type = 'give-item', item = 'artillery-targeting-remote', count = 1}},
{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}},
{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}},
{price = {{'coin', 30}}, offer = {type = 'give-item', item = 'submachine-gun', count = 1}},
{price = {{'coin', 250}}, offer = {type = 'give-item', item = 'combat-shotgun', count = 1}},
{price = {{'coin', 450}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
{price = {{'coin', 25}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 1}},
{price = {{'coin', 125}}, offer = {type = 'give-item', item = 'rocket-launcher', count = 1}},
{price = {{'coin', 2}}, offer = {type = 'give-item', item = 'rocket', count = 1}},
{price = {{'coin', 7}}, offer = {type = 'give-item', item = 'explosive-rocket', count = 1}},
{price = {{'coin', 7500}}, offer = {type = 'give-item', item = 'atomic-bomb', count = 1}},
{price = {{'coin', 325}}, offer = {type = 'give-item', item = 'railgun', count = 1}},
{price = {{'coin', 8}}, offer = {type = 'give-item', item = 'railgun-dart', count = 1}},
{price = {{'coin', 40}}, offer = {type = 'give-item', item = 'poison-capsule', count = 1}},
{price = {{'coin', 4}}, offer = {type = 'give-item', item = 'defender-capsule', count = 1}},
{price = {{'coin', 10}}, offer = {type = 'give-item', item = 'light-armor', count = 1}},
{price = {{'coin', 125}}, offer = {type = 'give-item', item = 'heavy-armor', count = 1}},
{price = {{'coin', 350}}, offer = {type = 'give-item', item = 'modular-armor', count = 1}},
{price = {{'coin', 1500}}, offer = {type = 'give-item', item = 'power-armor', count = 1}},
{price = {{'coin', 12000}}, offer = {type = 'give-item', item = 'power-armor-mk2', count = 1}},
{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}},
{price = {{'coin', 200}}, offer = {type = 'give-item', item = 'energy-shield-equipment', count = 1}},
{price = {{'coin', 850}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment', count = 1}},
{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}},
{price = {{'coin', 200}}, offer = {type = 'give-item', item = 'belt-immunity-equipment', count = 1}},
{price = {{'coin', 250}}, offer = {type = 'give-item', item = 'personal-roboport-equipment', count = 1}},
{price = {{'coin', 35}}, offer = {type = 'give-item', item = 'construction-robot', count = 1}},
{price = {{'coin', 25}}, offer = {type = 'give-item', item = 'cliff-explosives', count = 1}},
{price = {{'coin', 80}}, offer = {type = 'nothing', effect_description = special_descriptions['flame-boots']}}
}
for _, item in pairs(market_items) do
this.market.add_market_item(item)
end
if not this.railgun_enhancer_unlocked then
this.market.add_market_item(
{
price = {{'coin', 1500}},
offer = {type = 'nothing', effect_description = special_descriptions['railgun-enhancer']}
}
)
end
if not this.trapped_capsules_unlocked then
this.market.add_market_item(
{
price = {{'coin', 3500}},
offer = {type = 'nothing', effect_description = special_descriptions['trapped-capsules']}
}
)
end
if not this.explosive_bullets_unlocked then
this.market.add_market_item(
{
price = {{'coin', 4500}},
offer = {type = 'nothing', effect_description = special_descriptions['explosive-bullets']}
}
)
end
if not this.bouncy_shells_unlocked then
this.market.add_market_item(
{
price = {{'coin', 10000}},
offer = {type = 'nothing', effect_description = special_descriptions['bouncy-shells']}
}
)
end
if not this.vehicle_nanobots_unlocked then
this.market.add_market_item(
{
price = {{'coin', 15000}},
offer = {type = 'nothing', effect_description = special_descriptions['vehicle-nanobots']}
}
)
end
--[[
if not this.crumbly_walls_unlocked then
this.market.add_market_item({price = {{"coin", 35000}}, offer = {type = 'nothing', effect_description = special_descriptions["crumbly-walls"]}})
end
local str1 = "Gun Turret Slot for " .. tostring(global.entity_limits["gun-turret"].limit * global.entity_limits["gun-turret"].slot_price)
str1 = str1 .. " Coins."
local str2 = "Laser Turret Slot for " .. tostring(global.entity_limits["laser-turret"].limit * global.entity_limits["laser-turret"].slot_price)
str2 = str2 .. " Coins."
local str3 = "Artillery Slot for " .. tostring(global.entity_limits["artillery-turret"].limit * global.entity_limits["artillery-turret"].slot_price)
str3 = str3 .. " Coins."
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)
str4 = str4 .. " Coins."
local str5 = "Landmine Slot for " .. tostring(math.ceil((global.entity_limits["land-mine"].limit / 3) * global.entity_limits["land-mine"].slot_price))
str5 = str5 .. " Coins."
local market_items = {
{price = {}, offer = {type = 'nothing', effect_description = str1}},
{price = {}, offer = {type = 'nothing', effect_description = str2}},
{price = {}, offer = {type = 'nothing', effect_description = str3}},
{price = {}, offer = {type = 'nothing', effect_description = str4}},
{price = {}, offer = {type = 'nothing', effect_description = str5}},
{price = {{"coin", 5}}, offer = {type = 'give-item', item = "raw-fish", count = 1}},
{price = {{"coin", 1}}, offer = {type = 'give-item', item = 'wood', count = 8}},
{price = {{"coin", 8}}, offer = {type = 'give-item', item = 'grenade', count = 1}},
{price = {{"coin", 32}}, offer = {type = 'give-item', item = 'cluster-grenade', count = 1}},
{price = {{"coin", 1}}, offer = {type = 'give-item', item = 'land-mine', count = 1}},
{price = {{"coin", 80}}, offer = {type = 'give-item', item = 'car', count = 1}},
{price = {{"coin", 1200}}, offer = {type = 'give-item', item = 'tank', count = 1}},
{price = {{"coin", 3}}, offer = {type = 'give-item', item = 'cannon-shell', count = 1}},
{price = {{"coin", 7}}, offer = {type = 'give-item', item = 'explosive-cannon-shell', count = 1}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
{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", 10}}, offer = {type = 'give-item', item = 'artillery-shell', count = 1}},
{price = {{"coin", 25}}, offer = {type = 'give-item', item = 'artillery-targeting-remote', count = 1}},
{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}},
{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}},
{price = {{"coin", 30}}, offer = {type = 'give-item', item = "submachine-gun", count = 1}},
{price = {{"coin", 250}}, offer = {type = 'give-item', item = 'combat-shotgun', count = 1}},
{price = {{"coin", 450}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
{price = {{"coin", 25}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 1}},
{price = {{"coin", 125}}, offer = {type = 'give-item', item = 'rocket-launcher', count = 1}},
{price = {{"coin", 2}}, offer = {type = 'give-item', item = 'rocket', count = 1}},
{price = {{"coin", 7}}, offer = {type = 'give-item', item = 'explosive-rocket', count = 1}},
{price = {{"coin", 7500}}, offer = {type = 'give-item', item = 'atomic-bomb', count = 1}},
{price = {{"coin", 325}}, offer = {type = 'give-item', item = 'railgun', count = 1}},
{price = {{"coin", 8}}, offer = {type = 'give-item', item = 'railgun-dart', count = 1}},
{price = {{"coin", 40}}, offer = {type = 'give-item', item = 'poison-capsule', count = 1}},
{price = {{"coin", 4}}, offer = {type = 'give-item', item = 'defender-capsule', count = 1}},
{price = {{"coin", 10}}, offer = {type = 'give-item', item = 'light-armor', count = 1}},
{price = {{"coin", 125}}, offer = {type = 'give-item', item = 'heavy-armor', count = 1}},
{price = {{"coin", 350}}, offer = {type = 'give-item', item = 'modular-armor', count = 1}},
{price = {{"coin", 1500}}, offer = {type = 'give-item', item = 'power-armor', count = 1}},
{price = {{"coin", 12000}}, offer = {type = 'give-item', item = 'power-armor-mk2', count = 1}},
{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}},
{price = {{"coin", 200}}, offer = {type = 'give-item', item = 'energy-shield-equipment', count = 1}},
{price = {{"coin", 850}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment', count = 1}},
{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}},
{price = {{"coin", 200}}, offer = {type = 'give-item', item = 'belt-immunity-equipment', count = 1}},
{price = {{"coin", 250}}, offer = {type = 'give-item', item = 'personal-roboport-equipment', count = 1}},
{price = {{"coin", 35}}, offer = {type = 'give-item', item = 'construction-robot', count = 1}},
{price = {{"coin", 25}}, offer = {type = 'give-item', item = 'cliff-explosives', count = 1}},
{price = {{"coin", 80}}, offer = {type = 'nothing', effect_description = special_descriptions["flame-boots"]}}
}
for _, item in pairs(market_items) do
global.market.add_market_item(item)
end
if not global.railgun_enhancer_unlocked then
global.market.add_market_item({price = {{"coin", 1500}}, offer = {type = 'nothing', effect_description = special_descriptions["railgun-enhancer"]}})
end
if not global.trapped_capsules_unlocked then
global.market.add_market_item({price = {{"coin", 3500}}, offer = {type = 'nothing', effect_description = special_descriptions["trapped-capsules"]}})
end
if not global.explosive_bullets_unlocked then
global.market.add_market_item({price = {{"coin", 4500}}, offer = {type = 'nothing', effect_description = special_descriptions["explosive-bullets"]}})
end
if not global.bouncy_shells_unlocked then
global.market.add_market_item({price = {{"coin", 10000}}, offer = {type = 'nothing', effect_description = special_descriptions["bouncy-shells"]}})
end
if not global.vehicle_nanobots_unlocked then
global.market.add_market_item({price = {{"coin", 15000}}, offer = {type = 'nothing', effect_description = special_descriptions["vehicle-nanobots"]}})
end
--[[
if not global.crumbly_walls_unlocked then
global.market.add_market_item({price = {{"coin", 35000}}, offer = {type = 'nothing', effect_description = special_descriptions["crumbly-walls"]}})
end
if not global.ultra_mines_unlocked then
global.market.add_market_item({price = {{"coin", 45000}}, offer = {type = 'nothing', effect_description = special_descriptions["ultra-mines"]}})
if not this.ultra_mines_unlocked then
this.market.add_market_item({price = {{"coin", 45000}}, offer = {type = 'nothing', effect_description = special_descriptions["ultra-mines"]}})
end
]]
if not global.laser_pointer_unlocked then
global.market.add_market_item({price = {{"coin", 65000}}, offer = {type = 'nothing', effect_description = special_descriptions["laser-pointer"]}})
end
if not this.laser_pointer_unlocked then
this.market.add_market_item(
{
price = {{'coin', 65000}},
offer = {type = 'nothing', effect_description = special_descriptions['laser-pointer']}
}
)
end
end
local function slot_upgrade(player, offer_index)
local price = global.entity_limits[slot_upgrade_offers[offer_index][1]].limit * global.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
local gain = 1
if offer_index == 5 then
price = math.ceil((global.entity_limits[slot_upgrade_offers[offer_index][1]].limit / 3) * global.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price)
gain = 3
end
if slot_upgrade_offers[offer_index][1] == "flamethrower-turret" then
price = (global.entity_limits[slot_upgrade_offers[offer_index][1]].limit + 1) * global.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
end
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 false
end
global.entity_limits[slot_upgrade_offers[offer_index][1]].limit = global.entity_limits[slot_upgrade_offers[offer_index][1]].limit + gain
game.print(player.name .. " has bought a " .. slot_upgrade_offers[offer_index][2] .. " slot for " .. price .. " coins!", {r = 0.22, g = 0.77, b = 0.44})
Server.to_discord_bold(table.concat{player.name .. " has bought a " .. slot_upgrade_offers[offer_index][2] .. " slot for " .. price .. " coins!"})
refresh_market_offers()
local this = FDT.get()
local price =
this.entity_limits[slot_upgrade_offers[offer_index][1]].limit *
this.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
local gain = 1
if offer_index == 5 then
price =
math.ceil(
(this.entity_limits[slot_upgrade_offers[offer_index][1]].limit / 3) *
this.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
)
gain = 3
end
if slot_upgrade_offers[offer_index][1] == 'flamethrower-turret' then
price =
(this.entity_limits[slot_upgrade_offers[offer_index][1]].limit + 1) *
this.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
end
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 false
end
this.entity_limits[slot_upgrade_offers[offer_index][1]].limit =
this.entity_limits[slot_upgrade_offers[offer_index][1]].limit + gain
game.print(
player.name .. ' has bought a ' .. slot_upgrade_offers[offer_index][2] .. ' slot for ' .. price .. ' coins!',
{r = 0.22, g = 0.77, b = 0.44}
)
if math.random(1, 2) == 1 then
Server.to_discord_bold(
table.concat {
'*** ' ..
player.name ..
' has bought a ' ..
slot_upgrade_offers[offer_index][2] .. ' slot for ' .. price .. ' coins! ***'
}
)
end
refresh_market_offers()
end
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
if slot_upgrade_offers[offer_index] then
if slot_upgrade(player, offer_index) then return end
end
if offer_index < 50 then return end
if bought_offer.effect_description == special_descriptions["flame-boots"] then
game.print(player.name .. " has bought themselves some flame boots.", {r = 0.22, g = 0.77, b = 0.44})
if not global.flame_boots[player.index].fuel then
global.flame_boots[player.index].fuel = math.random(1500, 3000)
else
global.flame_boots[player.index].fuel = global.flame_boots[player.index].fuel + math.random(1500, 3000)
end
player.print("Fuel remaining: " .. global.flame_boots[player.index].fuel, {r = 0.22, g = 0.77, b = 0.44})
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["explosive-bullets"] then
game.print(player.name .. " has unlocked explosive bullets.", {r = 0.22, g = 0.77, b = 0.44})
global.explosive_bullets_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["bouncy-shells"] then
game.print(player.name .. " has unlocked bouncy shells.", {r = 0.22, g = 0.77, b = 0.44})
global.bouncy_shells_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["trapped-capsules"] then
game.print(player.name .. " has unlocked trapped capsules!", {r = 0.22, g = 0.77, b = 0.44})
global.trapped_capsules_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["ultra-mines"] then
game.print(player.name .. " has unlocked ultra mines!", {r = 0.22, g = 0.77, b = 0.44})
global.ultra_mines_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["laser-pointer"] then
game.print(player.name .. " has unleashed the quest to slay the red dot!", {r = 0.22, g = 0.77, b = 0.44})
global.laser_pointer_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["railgun-enhancer"] then
game.print(player.name .. " has unlocked the enhanced railgun!", {r = 0.22, g = 0.77, b = 0.44})
global.railgun_enhancer_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["crumbly-walls"] then
game.print(player.name .. " has unlocked crumbly walls!", {r = 0.22, g = 0.77, b = 0.44})
global.crumbly_walls_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions["vehicle-nanobots"] then
game.print(player.name .. " has unlocked vehicle nanobots!", {r = 0.22, g = 0.77, b = 0.44})
global.vehicle_nanobots_unlocked = true
refresh_market_offers()
return
end
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 this = FDT.get()
if slot_upgrade_offers[offer_index] then
if slot_upgrade(player, offer_index) then
return
end
end
if offer_index < 50 then
return
end
if bought_offer.effect_description == special_descriptions['flame-boots'] then
game.print(player.name .. ' has bought themselves some flame boots.', {r = 0.22, g = 0.77, b = 0.44})
if not this.flame_boots[player.index].fuel then
this.flame_boots[player.index].fuel = math.random(1500, 3000)
else
this.flame_boots[player.index].fuel = this.flame_boots[player.index].fuel + math.random(1500, 3000)
end
player.print('Fuel remaining: ' .. this.flame_boots[player.index].fuel, {r = 0.22, g = 0.77, b = 0.44})
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['explosive-bullets'] then
game.print(player.name .. ' has unlocked explosive bullets.', {r = 0.22, g = 0.77, b = 0.44})
this.explosive_bullets_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['bouncy-shells'] then
game.print(player.name .. ' has unlocked bouncy shells.', {r = 0.22, g = 0.77, b = 0.44})
this.bouncy_shells_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['trapped-capsules'] then
game.print(player.name .. ' has unlocked trapped capsules!', {r = 0.22, g = 0.77, b = 0.44})
this.trapped_capsules_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['ultra-mines'] then
game.print(player.name .. ' has unlocked ultra mines!', {r = 0.22, g = 0.77, b = 0.44})
this.ultra_mines_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['laser-pointer'] then
game.print(player.name .. ' has unleashed the quest to slay the red dot!', {r = 0.22, g = 0.77, b = 0.44})
this.laser_pointer_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['railgun-enhancer'] then
game.print(player.name .. ' has unlocked the enhanced railgun!', {r = 0.22, g = 0.77, b = 0.44})
this.railgun_enhancer_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['crumbly-walls'] then
game.print(player.name .. ' has unlocked crumbly walls!', {r = 0.22, g = 0.77, b = 0.44})
this.crumbly_walls_unlocked = true
refresh_market_offers()
return
end
if bought_offer.effect_description == special_descriptions['vehicle-nanobots'] then
game.print(player.name .. ' has unlocked vehicle nanobots!', {r = 0.22, g = 0.77, b = 0.44})
this.vehicle_nanobots_unlocked = true
refresh_market_offers()
return
end
end
local function on_gui_opened(event)
if not event.entity then return end
if not event.entity.valid then return end
if event.entity.name == "market" then refresh_market_offers() return end
if not event.entity then
return
end
if not event.entity.valid then
return
end
if event.entity.name == 'market' then
refresh_market_offers()
return
end
end
event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
event.add(defines.events.on_gui_opened, on_gui_opened)
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
Event.add(defines.events.on_gui_opened, on_gui_opened)

View File

@ -1,42 +1,65 @@
local event = require 'utils.event'
require 'maps.fish_defender.boss_biters'
local Event = require 'utils.event'
local enhance_railgun = require 'maps.fish_defender.railgun_enhancer'
local explosive_bullets = require 'maps.fish_defender.explosive_gun_bullets'
local bouncy_shells = require 'maps.fish_defender.bouncy_shells'
local boss_biter = require "maps.fish_defender.boss_biters"
local FDT = require 'maps.fish_defender.table'
local function protect_market(event)
if event.entity.name ~= "market" then return end
if event.cause then
if event.cause.force.name == "enemy" then return end
end
event.entity.health = event.entity.health + event.final_damage_amount
return true
if event.entity.name ~= 'market' then
return
end
if event.cause then
if event.cause.force.name == 'enemy' then
return
end
end
event.entity.health = event.entity.health + event.final_damage_amount
return true
end
local function on_entity_damaged(event)
if not event.entity then return end
if not event.entity.valid then return end
if protect_market(event) then return end
if not event.cause then return end
--if event.cause.unit_number then
-- if global.boss_biters[event.cause.unit_number] then
-- boss_biter.damaged_entity(event)
-- end
--end
if event.cause.name ~= "character" then return end
if enhance_railgun(event) then return end
if global.explosive_bullets_unlocked then
if explosive_bullets(event) then return end
end
if global.bouncy_shells_unlocked then
if bouncy_shells(event) then return end
end
if not event.entity then
return
end
if not event.entity.valid then
return
end
if protect_market(event) then
return
end
if not event.cause then
return
end
local explosive_bullets_unlocked = FDT.get('explosive_bullets_unlocked')
local bouncy_shells_unlocked = FDT.get('bouncy_shells_unlocked')
--if event.cause.unit_number then
-- if this.boss_biters[event.cause.unit_number] then
-- boss_biter.damaged_entity(event)
-- end
--end
if event.cause.name ~= 'character' then
return
end
if enhance_railgun(event) then
return
end
if explosive_bullets_unlocked then
if explosive_bullets(event) then
return
end
end
if bouncy_shells_unlocked then
if bouncy_shells(event) then
return
end
end
end
event.add(defines.events.on_entity_damaged, on_entity_damaged)
Event.add(defines.events.on_entity_damaged, on_entity_damaged)

View File

@ -1,98 +1,157 @@
-- improves the damage of the railgun and adds visual effects -- by mewmew
-- laser turret research will increase it´s damage even further --
local FDT = require 'maps.fish_defender.table'
local damage_min = 400
local damage_max = 800
local math_random = math.random
local additional_visual_effects = true
local biological_target_types = {
["unit"] = true,
["player"] = true,
["turret"] = true,
["unit-spawner"] = true
['unit'] = true,
['player'] = true,
['turret'] = true,
['unit-spawner'] = true
}
local function create_visuals(source_entity, target_entity)
if not source_entity.valid then return end
if not target_entity.valid then return end
if not additional_visual_effects then return end
local surface = target_entity.surface
surface.create_entity({name = "water-splash", position = target_entity.position})
if biological_target_types[target_entity.type] then
surface.create_entity({name = "blood-explosion-big", position = target_entity.position})
for x = -8, 8, 1 do
for y = -8, 8, 1 do
if math_random(1, 16) == 1 then
surface.create_entity({name = "blood-fountain", position = {target_entity.position.x + (x * 0.1), target_entity.position.y + (y * 0.1)}})
surface.create_entity({name = "blood-fountain-big", position = {target_entity.position.x + (x * 0.1), target_entity.position.y + (y * 0.1)}})
end
end
end
else
if math_random(1, 3) ~= 1 then
surface.create_entity({name = "fire-flame", position = target_entity.position})
end
for x = -3, 3, 1 do
for y = -3, 3, 1 do
if math_random(1, 3) == 1 then
surface.create_trivial_smoke({name="smoke-fast", position={target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}})
end
if math_random(1, 5) == 1 then
surface.create_trivial_smoke({name="train-smoke", position={target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}})
end
end
end
end
if not source_entity.valid then
return
end
if not target_entity.valid then
return
end
if not additional_visual_effects then
return
end
local surface = target_entity.surface
surface.create_entity({name = 'water-splash', position = target_entity.position})
if biological_target_types[target_entity.type] then
surface.create_entity({name = 'blood-explosion-big', position = target_entity.position})
for x = -8, 8, 1 do
for y = -8, 8, 1 do
if math_random(1, 16) == 1 then
surface.create_entity(
{
name = 'blood-fountain',
position = {target_entity.position.x + (x * 0.1), target_entity.position.y + (y * 0.1)}
}
)
surface.create_entity(
{
name = 'blood-fountain-big',
position = {target_entity.position.x + (x * 0.1), target_entity.position.y + (y * 0.1)}
}
)
end
end
end
else
if math_random(1, 3) ~= 1 then
surface.create_entity({name = 'fire-flame', position = target_entity.position})
end
for x = -3, 3, 1 do
for y = -3, 3, 1 do
if math_random(1, 3) == 1 then
surface.create_trivial_smoke(
{
name = 'smoke-fast',
position = {target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}
}
)
end
if math_random(1, 5) == 1 then
surface.create_trivial_smoke(
{
name = 'train-smoke',
position = {target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}
}
)
end
end
end
end
end
local function do_splash_damage_around_entity(source_entity, player)
if not source_entity.valid then return end
local research_damage_bonus = player.force.get_ammo_damage_modifier("laser-turret") + 1
local research_splash_radius_bonus = player.force.get_ammo_damage_modifier("laser-turret") * 0.5
local splash_area = {
{source_entity.position.x - (2.5 + research_splash_radius_bonus), source_entity.position.y - (2.5 + research_splash_radius_bonus)},
{source_entity.position.x + (2.5 + research_splash_radius_bonus), source_entity.position.y + (2.5 + research_splash_radius_bonus)}
}
local entities = source_entity.surface.find_entities_filtered({area = splash_area})
for _, entity in pairs(entities) do
if entity.valid then
if entity.health and entity ~= source_entity and entity ~= player then
if additional_visual_effects then
local surface = entity.surface
surface.create_entity({name = "railgun-beam", position = source_entity.position, source = source_entity.position, target = entity.position})
surface.create_entity({name = "water-splash", position = entity.position})
if biological_target_types[entity.type] then
surface.create_entity({name = "blood-fountain", position = entity.position})
end
end
local damage = math_random(math.ceil((damage_min * research_damage_bonus) / 16), math.ceil((damage_max * research_damage_bonus) / 16))
entity.damage(damage, player.force, "physical")
end
end
end
if not source_entity.valid then
return
end
local research_damage_bonus = player.force.get_ammo_damage_modifier('laser-turret') + 1
local research_splash_radius_bonus = player.force.get_ammo_damage_modifier('laser-turret') * 0.5
local splash_area = {
{
source_entity.position.x - (2.5 + research_splash_radius_bonus),
source_entity.position.y - (2.5 + research_splash_radius_bonus)
},
{
source_entity.position.x + (2.5 + research_splash_radius_bonus),
source_entity.position.y + (2.5 + research_splash_radius_bonus)
}
}
local entities = source_entity.surface.find_entities_filtered({area = splash_area})
for _, entity in pairs(entities) do
if entity.valid then
if entity.health and entity ~= source_entity and entity ~= player then
if additional_visual_effects then
local surface = entity.surface
surface.create_entity(
{
name = 'railgun-beam',
position = source_entity.position,
source = source_entity.position,
target = entity.position
}
)
surface.create_entity({name = 'water-splash', position = entity.position})
if biological_target_types[entity.type] then
surface.create_entity({name = 'blood-fountain', position = entity.position})
end
end
local damage =
math_random(
math.ceil((damage_min * research_damage_bonus) / 16),
math.ceil((damage_max * research_damage_bonus) / 16)
)
entity.damage(damage, player.force, 'physical')
end
end
end
end
local function enhance(event)
if not global.railgun_enhancer_unlocked then return end
if event.damage_type.name ~= "physical" then return end
if event.original_damage_amount ~= 100 then return end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then return end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon.name ~= "railgun" then return end
create_visuals(event.cause, event.entity)
do_splash_damage_around_entity(event.entity, player)
event.entity.health = event.entity.health + event.final_damage_amount
local research_damage_bonus = player.force.get_ammo_damage_modifier("laser-turret") + 1
local damage = math_random(math.ceil(damage_min * research_damage_bonus), math.ceil(damage_max * research_damage_bonus))
event.entity.damage(damage, player.force, "physical")
return true
local railgun_enhancer_unlocked = FDT.get('railgun_enhancer_unlocked')
if not railgun_enhancer_unlocked then
return
end
if event.damage_type.name ~= 'physical' then
return
end
if event.original_damage_amount ~= 100 then
return
end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then
return
end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon.name ~= 'railgun' then
return
end
create_visuals(event.cause, event.entity)
do_splash_damage_around_entity(event.entity, player)
event.entity.health = event.entity.health + event.final_damage_amount
local research_damage_bonus = player.force.get_ammo_damage_modifier('laser-turret') + 1
local damage =
math_random(math.ceil(damage_min * research_damage_bonus), math.ceil(damage_max * research_damage_bonus))
event.entity.damage(damage, player.force, 'physical')
return true
end
return enhance
return enhance

View File

@ -1,28 +1,31 @@
local event = require 'utils.event'
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local gain_multiplier = 4
local function on_research_finished(event)
local research = event.research
local force_name = research.force.name
if not global.shotgun_shell_damage_modifier_old[force_name] then global.shotgun_shell_damage_modifier_old[force_name] = game.forces[force_name].get_ammo_damage_modifier("shotgun-shell") - 0.1 end
if string.sub(research.name, 0, 26) == "physical-projectile-damage" then
local current_damage = game.forces[force_name].get_ammo_damage_modifier("shotgun-shell")
local vanilla_gain = current_damage - global.shotgun_shell_damage_modifier_old[force_name]
local additional_gain = vanilla_gain * (gain_multiplier - 1)
game.forces[force_name].set_ammo_damage_modifier("shotgun-shell", current_damage + additional_gain)
end
global.shotgun_shell_damage_modifier_old[force_name] = game.forces[force_name].get_ammo_damage_modifier("shotgun-shell")
local research = event.research
local force_name = research.force.name
local this = FDT.get()
if not this.shotgun_shell_damage_modifier_old[force_name] then
this.shotgun_shell_damage_modifier_old[force_name] =
game.forces[force_name].get_ammo_damage_modifier('shotgun-shell') - 0.1
end
if string.sub(research.name, 0, 26) == 'physical-projectile-damage' then
local current_damage = game.forces[force_name].get_ammo_damage_modifier('shotgun-shell')
local vanilla_gain = current_damage - this.shotgun_shell_damage_modifier_old[force_name]
local additional_gain = vanilla_gain * (gain_multiplier - 1)
game.forces[force_name].set_ammo_damage_modifier('shotgun-shell', current_damage + additional_gain)
end
this.shotgun_shell_damage_modifier_old[force_name] =
game.forces[force_name].get_ammo_damage_modifier('shotgun-shell')
end
local function on_init()
game.forces.player.set_ammo_damage_modifier("shotgun-shell", 1)
global.shotgun_shell_damage_modifier_old = {}
game.forces.player.set_ammo_damage_modifier('shotgun-shell', 1)
end
event.on_init(on_init)
event.add(defines.events.on_research_finished, on_research_finished)
Event.on_init(on_init)
Event.add(defines.events.on_research_finished, on_research_finished)

View File

@ -0,0 +1,83 @@
-- one table to rule them all!
local Global = require 'utils.global'
local Event = require 'utils.event'
local this = {
players = {},
offline_players = {},
hidden_dimension = {
logistic_research_level = 0,
reset_counter = 1
},
power_sources = {},
refill_turrets = {index = 1},
magic_crafters = {index = 1},
magic_fluid_crafters = {index = 1},
breached_wall = 1,
entity_limits = {},
traps = {}
}
local Public = {}
Global.register(
this,
function(tbl)
this = tbl
end
)
function Public.reset_table()
this.chunk_queue = {}
this.game_has_ended = false
this.game_reset = false
this.spawn_area_generated = false
this.results_sent = false
this.explosive_bullets_unlocked = false
this.bouncy_shells_unlocked = false
this.trapped_capsules_unlocked = false
this.ultra_mines_unlocked = false
this.laser_pointer_unlocked = false
this.railgun_enhancer_unlocked = false
this.crumbly_walls_unlocked = false
this.vehicle_nanobots_unlocked = false
this.game_restart_timer = nil
this.wave_count = 1
this.market = nil
this.market_age = nil
this.last_reset = game.tick
this.wave_interval = 3600
this.wave_grace_period = game.tick + 3600 * 20
this.boss_biters = {}
this.acid_lines_delay = {}
this.show_floating_killscore = {}
this.entity_limits = {
['gun-turret'] = {placed = 1, limit = 1, str = 'gun turret', slot_price = 75},
['laser-turret'] = {placed = 0, limit = 1, str = 'laser turret', slot_price = 300},
['artillery-turret'] = {placed = 0, limit = 1, str = 'artillery turret', slot_price = 500},
['flamethrower-turret'] = {placed = 0, limit = 0, str = 'flamethrower turret', slot_price = 50000},
['land-mine'] = {placed = 0, limit = 1, str = 'mine', slot_price = 1}
}
this.comfylatron_habitat = {
left_top = {x = -1500, y = -1500},
right_bottom = {x = -80, y = 1500}
}
this.map_height = 96
this.shotgun_shell_damage_modifier_old = {}
this.flame_boots = {}
end
function Public.get(key)
if key then
return this[key]
else
return this
end
end
local on_init = function()
Public.reset_table()
end
Event.on_init(on_init)
return Public

View File

@ -1,48 +1,63 @@
local map_functions = require "tools.map_functions"
local simplex_noise = require "utils.simplex_noise".d2
local Event = require 'utils.event'
local map_functions = require 'tools.map_functions'
local simplex_noise = require 'utils.simplex_noise'.d2
local FDT = require 'maps.fish_defender.table'
local math_random = math.random
local math_abs = math.abs
local math_floor = math.floor
local math_sqrt = math.sqrt
local hourglass_center_piece_length = 64
local worm_raffle_table = {
[1] = {"small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret"},
[2] = {"small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret"},
[3] = {"small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret"},
[4] = {"small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret"},
[5] = {"small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret"},
[6] = {"small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret"},
[7] = {"medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret"},
[8] = {"medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret"},
[9] = {"medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret"},
[10] = {"medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret"}
}
local rock_raffle = {"sand-rock-big","sand-rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"}
local Public = {}
local rock_raffle = {
'sand-rock-big',
'sand-rock-big',
'rock-big',
'rock-big',
'rock-big',
'rock-big',
'rock-big',
'rock-big',
'rock-huge'
}
local function get_replacement_tile(surface, position)
for i = 1, 128, 1 do
local vectors = {{0, i}, {0, i * -1}, {i, 0}, {i * -1, 0}}
table.shuffle_table(vectors)
for k, v in pairs(vectors) do
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
if not tile.collides_with("resource-layer") then return tile.name end
end
end
return "grass-1"
for i = 1, 128, 1 do
local vectors = {{0, i}, {0, i * -1}, {i, 0}, {i * -1, 0}}
table.shuffle_table(vectors)
for k, v in pairs(vectors) do
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
if not tile.collides_with('resource-layer') then
return tile.name
end
end
end
return 'grass-1'
end
local function is_enemy_territory(p)
if p.x - 64 < math_abs(p.y) then return false end
--if p.x - 64 < p.y then return false end
if p.x < 160 then return false end
if p.x > 1024 then return false end
if p.y > 512 then return false end
if p.y < -512 then return false end
local noise = math_abs(simplex_noise(0, p.y * 0.015, game.surfaces[1].map_gen_settings.seed) * 96)
local noise_2 = math_abs(simplex_noise(0, p.y * 0.1, game.surfaces[1].map_gen_settings.seed) * 16)
if p.x > 288 + noise + noise_2 + math_abs(p.y * 0.75) then return false end
return true
if p.x - 64 < math_abs(p.y) then
return false
end
--if p.x - 64 < p.y then return false end
if p.x < 160 then
return false
end
if p.x > 1024 then
return false
end
if p.y > 512 then
return false
end
if p.y < -512 then
return false
end
local noise = math_abs(simplex_noise(0, p.y * 0.015, game.surfaces[1].map_gen_settings.seed) * 96)
local noise_2 = math_abs(simplex_noise(0, p.y * 0.1, game.surfaces[1].map_gen_settings.seed) * 16)
if p.x > 288 + noise + noise_2 + math_abs(p.y * 0.75) then
return false
end
return true
end
local body_radius = 3072
@ -57,323 +72,466 @@ local square_fin_radius = fin_radius ^ 2
local fin_circle_center_1 = {x = -480, y = 0}
local fin_circle_center_2 = {x = -480 - 360, y = 0}
local function is_body(p)
if p.y <= map_height and p.y >= map_height * -1 and p.x <= 160 and p.x > body_center_position.x then return true end
--Main Fish Body
local distance_to_center_1 = ((p.x - body_circle_center_1.x)^2 + (p.y - body_circle_center_1.y)^2)
local distance_to_center_2 = ((p.x - body_circle_center_2.x)^2 + (p.y - body_circle_center_2.y)^2)
--if distance_to_center_1 < body_square_radius and distance_to_center_2 < body_square_radius then return true end
if distance_to_center_1 < body_square_radius then
if distance_to_center_2 < body_square_radius then return true end
end
--Fish Fins
local distance_to_center_1 = ((p.x - fin_circle_center_1.x)^2 + (p.y - fin_circle_center_1.y)^2)
if distance_to_center_1 + math_abs(simplex_noise(0, p.y * 0.075, game.surfaces[1].map_gen_settings.seed) * 32000) > square_fin_radius then
local distance_to_center_2 = ((p.x - fin_circle_center_2.x)^2 + (p.y - fin_circle_center_2.y)^2)
if distance_to_center_2 < square_fin_radius then
return true
end
end
return false
local function is_body(p)
local this = FDT.get()
if p.y <= this.map_height and p.y >= this.map_height * -1 and p.x <= 160 and p.x > body_center_position.x then
return true
end
--Main Fish Body
local distance_to_center_1 = ((p.x - body_circle_center_1.x) ^ 2 + (p.y - body_circle_center_1.y) ^ 2)
local distance_to_center_2 = ((p.x - body_circle_center_2.x) ^ 2 + (p.y - body_circle_center_2.y) ^ 2)
--if distance_to_center_1 < body_square_radius and distance_to_center_2 < body_square_radius then return true end
if distance_to_center_1 < body_square_radius then
if distance_to_center_2 < body_square_radius then
return true
end
end
--Fish Fins
distance_to_center_1 = ((p.x - fin_circle_center_1.x) ^ 2 + (p.y - fin_circle_center_1.y) ^ 2)
if
distance_to_center_1 + math_abs(simplex_noise(0, p.y * 0.075, game.surfaces[1].map_gen_settings.seed) * 32000) >
square_fin_radius
then
distance_to_center_2 = ((p.x - fin_circle_center_2.x) ^ 2 + (p.y - fin_circle_center_2.y) ^ 2)
if distance_to_center_2 < square_fin_radius then
return true
end
end
return false
end
local function is_out_of_map_tile(p)
if p.y > 850 then return true end
if p.y < -850 then return true end
if p.x < -3264 then return true end
if p.x > 800 then return true end
if is_enemy_territory(p) then return false end
if is_body(p) then return false end
return true
if p.y > 850 then
return true
end
if p.y < -850 then
return true
end
if p.x < -3264 then
return true
end
if p.x > 800 then
return true
end
if is_enemy_territory(p) then
return false
end
if is_body(p) then
return false
end
return true
end
local function place_fish_market(surface, position)
local market = surface.create_entity({name = 'market', position = position, force = 'player'})
market.minable = false
return market
end
local function generate_spawn_area(surface)
surface.request_to_generate_chunks({x = 0, y = 0}, 7)
surface.request_to_generate_chunks({x = 160, y = 0}, 5)
--surface.force_generate_chunk_requests()
if global.spawn_area_generated then return end
if not surface.is_chunk_generated({-7, 0}) then return end
if not surface.is_chunk_generated({5, 0}) then return end
global.spawn_area_generated = true
surface.request_to_generate_chunks({x = 0, y = 0}, 7)
surface.request_to_generate_chunks({x = 160, y = 0}, 4)
--surface.force_generate_chunk_requests()
local spawn_area_generated = FDT.get('spawn_area_generated')
if spawn_area_generated then
return
end
if not surface.is_chunk_generated({-7, 0}) then
return
end
if not surface.is_chunk_generated({5, 0}) then
return
end
FDT.get().spawn_area_generated = true
local spawn_position_x = -128
local spawn_position_x = -128
surface.create_entity({name = "electric-beam", position = {160, -96}, source = {160, -96}, target = {160,96}})
surface.create_entity({name = 'electric-beam', position = {160, -96}, source = {160, -96}, target = {160, 96}})
for _, tile in pairs(surface.find_tiles_filtered({name = {"water", "deepwater"}, area = {{-160, -160},{160, 160}}})) do
local noise = math_abs(simplex_noise(tile.position.x * 0.02, tile.position.y * 0.02, game.surfaces[1].map_gen_settings.seed) * 16)
if tile.position.x > -160 + noise then surface.set_tiles({{name = get_replacement_tile(surface, tile.position), position = {tile.position.x, tile.position.y}}}, true) end
end
for _, tile in pairs(
surface.find_tiles_filtered({name = {'water', 'deepwater'}, area = {{-160, -160}, {160, 160}}})
) do
local noise =
math_abs(
simplex_noise(tile.position.x * 0.02, tile.position.y * 0.02, game.surfaces[1].map_gen_settings.seed) * 16
)
if tile.position.x > -160 + noise then
surface.set_tiles(
{{name = get_replacement_tile(surface, tile.position), position = {tile.position.x, tile.position.y}}},
true
)
end
end
for _, entity in pairs(surface.find_entities_filtered({type = {"resource", "cliff"}, area = {{spawn_position_x - 32, -256},{160, 256}}})) do
if is_body(entity.position) then
if entity.position.x > spawn_position_x - 32 + math_abs(simplex_noise(entity.position.x * 0.02, entity.position.y * 0.02, game.surfaces[1].map_gen_settings.seed) * 16) then
entity.destroy()
end
end
end
for _, entity in pairs(
surface.find_entities_filtered(
{type = {'resource', 'cliff'}, area = {{spawn_position_x - 32, -256}, {160, 256}}}
)
) do
if is_body(entity.position) then
if
entity.position.x >
spawn_position_x - 32 +
math_abs(
simplex_noise(
entity.position.x * 0.02,
entity.position.y * 0.02,
game.surfaces[1].map_gen_settings.seed
) * 16
)
then
entity.destroy()
end
end
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
local y = 80
local ore_positions = {{x = spawn_position_x - 52, y = y},{x = spawn_position_x - 52, y = y * 0.5},{x = spawn_position_x - 52, y = 0},{x = spawn_position_x - 52, y = y * -0.5},{x = spawn_position_x - 52, y = y * -1}}
table.shuffle_table(ore_positions)
map_functions.draw_smoothed_out_ore_circle(ore_positions[1], "copper-ore", surface, 15, 2500)
map_functions.draw_smoothed_out_ore_circle(ore_positions[2], "iron-ore", surface, 15, 2500)
map_functions.draw_smoothed_out_ore_circle(ore_positions[3], "coal", surface, 15, 1500)
map_functions.draw_smoothed_out_ore_circle(ore_positions[4], "stone", surface, 15, 1500)
map_functions.draw_noise_tile_circle({x = spawn_position_x - 20, y = 0}, "water", surface, 16)
map_functions.draw_oil_circle(ore_positions[5], "crude-oil", surface, 8, 200000)
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
local pos = surface.find_non_colliding_position("market",{spawn_position_x, 0}, 50, 1)
global.market = place_fish_market(surface, pos)
local r = 16
for _, entity in pairs(surface.find_entities_filtered({area = {{global.market.position.x - r, global.market.position.y - r}, {global.market.position.x + r, global.market.position.y + r}}, type = "tree"})) do
local distance_to_center = math_sqrt((entity.position.x - global.market.position.x)^2 + (entity.position.y - global.market.position.y)^2)
if distance_to_center < r then
if math_random(1, r) > distance_to_center then entity.destroy() end
end
end
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})
local y = 80
local ore_positions = {
{x = spawn_position_x - 52, y = y},
{x = spawn_position_x - 52, y = y * 0.5},
{x = spawn_position_x - 52, y = 0},
{x = spawn_position_x - 52, y = y * -0.5},
{x = spawn_position_x - 52, y = y * -1}
}
table.shuffle_table(ore_positions)
map_functions.draw_smoothed_out_ore_circle(ore_positions[1], 'copper-ore', surface, 15, 2500)
map_functions.draw_smoothed_out_ore_circle(ore_positions[2], 'iron-ore', surface, 15, 2500)
map_functions.draw_smoothed_out_ore_circle(ore_positions[3], 'coal', surface, 15, 1500)
map_functions.draw_smoothed_out_ore_circle(ore_positions[4], 'stone', surface, 15, 1500)
map_functions.draw_noise_tile_circle({x = spawn_position_x - 20, y = 0}, 'water', surface, 16)
map_functions.draw_oil_circle(ore_positions[5], 'crude-oil', surface, 8, 200000)
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
local distance_to_center = x^2 + y^2
if distance_to_center > 64 and distance_to_center < 225 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
local pos = surface.find_non_colliding_position('market', {spawn_position_x, 0}, 50, 1)
FDT.get().market = place_fish_market(surface, pos)
local market = FDT.get('market')
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, 32) == 1 then
surface.create_entity({name = "fish", position = tile.position})
end
end
local r = 16
for _, entity in pairs(
surface.find_entities_filtered(
{
area = {
{market.position.x - r, market.position.y - r},
{market.position.x + r, market.position.y + r}
},
type = 'tree'
}
)
) do
local distance_to_center =
math_sqrt((entity.position.x - market.position.x) ^ 2 + (entity.position.y - market.position.y) ^ 2)
if distance_to_center < r then
if math_random(1, r) > distance_to_center then
entity.destroy()
end
end
end
local pos = surface.find_non_colliding_position("character",{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("character",{spawn_position_x + 1, 4}, 50, 1)
player.teleport(pos, surface)
end
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 = market.position.x + x, y = 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
local distance_to_center = x ^ 2 + y ^ 2
if distance_to_center > 64 and distance_to_center < 225 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
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, 32) == 1 then
surface.create_entity({name = 'fish', position = tile.position})
end
end
local pos = surface.find_non_colliding_position('character', {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('character', {spawn_position_x + 1, 4}, 50, 1)
player.teleport(pos, surface)
end
end
local function enemy_territory(surface, left_top)
--surface.request_to_generate_chunks({x = 256, y = 0}, 16)
--surface.force_generate_chunk_requests()
if left_top.x < 160 then return end
if left_top.x > 750 then return end
if left_top.y > 512 then return end
if left_top.y < -512 then return end
local area = {{left_top.x, left_top.y},{left_top.x + 32, left_top.y + 32}}
--local area = {{160, -512},{750, 512}}
--for _, tile in pairs(surface.find_tiles_filtered({area = area})) do
-- if is_enemy_territory(tile.position) then
-- surface.set_tiles({{name = "water-mud", position = {tile.position.x, tile.position.y}}}, true)
-- end
--end
if left_top.x > 256 then
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
if is_enemy_territory(pos) then
if math_random(1, 512) == 1 then
if surface.can_place_entity({name = "biter-spawner", force = "decoratives", position = pos}) then
local entity
if math_random(1,4) == 1 then
entity = surface.create_entity({name = "spitter-spawner", force = "decoratives", position = pos})
else
entity = surface.create_entity({name = "biter-spawner", force = "decoratives", position = pos})
end
entity.active = false
entity.destructible = false
end
end
--if pos.x % 32 == 0 and pos.y % 32 == 0 then
-- 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
-- surface.regenerate_decorative(decorative_names, {{x=math_floor(pos.x/32),y=math_floor(pos.y/32)}})
--end
end
end
end
end
for _, entity in pairs(surface.find_entities_filtered({area = area, type = {"tree", "cliff"}})) do
if is_enemy_territory(entity.position) then entity.destroy() end
end
for _, entity in pairs(surface.find_entities_filtered({area = area, type = "resource"})) do
if is_enemy_territory(entity.position) then
surface.create_entity({name = "uranium-ore", position = entity.position, amount = math_random(200, 8000)})
entity.destroy()
end
end
for _, tile in pairs(surface.find_tiles_filtered({name = {"water", "deepwater"}, area = area})) do
if is_enemy_territory(tile.position) then
surface.set_tiles({{name = get_replacement_tile(surface, tile.position), position = {tile.position.x, tile.position.y}}}, true)
end
end
--surface.request_to_generate_chunks({x = 256, y = 0}, 16)
--surface.force_generate_chunk_requests()
if left_top.x < 160 then
return
end
if left_top.x > 750 then
return
end
if left_top.y > 512 then
return
end
if left_top.y < -512 then
return
end
local area = {{left_top.x, left_top.y}, {left_top.x + 32, left_top.y + 32}}
--local area = {{160, -512},{750, 512}}
--for _, tile in pairs(surface.find_tiles_filtered({area = area})) do
-- if is_enemy_territory(tile.position) then
-- surface.set_tiles({{name = "water-mud", position = {tile.position.x, tile.position.y}}}, true)
-- end
--end
if left_top.x > 256 then
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
if is_enemy_territory(pos) then
if math_random(1, 512) == 1 then
if surface.can_place_entity({name = 'biter-spawner', force = 'decoratives', position = pos}) then
local entity
if math_random(1, 4) == 1 then
entity =
surface.create_entity(
{name = 'spitter-spawner', force = 'decoratives', position = pos}
)
else
entity =
surface.create_entity(
{name = 'biter-spawner', force = 'decoratives', position = pos}
)
end
entity.active = false
entity.destructible = false
end
end
--if pos.x % 32 == 0 and pos.y % 32 == 0 then
-- 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
-- surface.regenerate_decorative(decorative_names, {{x=math_floor(pos.x/32),y=math_floor(pos.y/32)}})
--end
end
end
end
end
for _, entity in pairs(surface.find_entities_filtered({area = area, type = {'tree', 'cliff'}})) do
if is_enemy_territory(entity.position) then
entity.destroy()
end
end
for _, entity in pairs(surface.find_entities_filtered({area = area, type = 'resource'})) do
if is_enemy_territory(entity.position) then
surface.create_entity({name = 'uranium-ore', position = entity.position, amount = math_random(200, 8000)})
entity.destroy()
end
end
for _, tile in pairs(surface.find_tiles_filtered({name = {'water', 'deepwater'}, area = area})) do
if is_enemy_territory(tile.position) then
surface.set_tiles(
{{name = get_replacement_tile(surface, tile.position), position = {tile.position.x, tile.position.y}}},
true
)
end
end
end
local function fish_mouth(surface, left_top)
if left_top.x > -2300 then return end
if left_top.y > 64 then return end
if left_top.y < -64 then return end
if left_top.x < -3292 then return end
if left_top.x > -2300 then
return
end
if left_top.y > 64 then
return
end
if left_top.y < -64 then
return
end
if left_top.x < -3292 then
return
end
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
local noise = simplex_noise(pos.x * 0.006, 0, game.surfaces[1].map_gen_settings.seed) * 20
if pos.y <= 12 + noise and pos.y >= -12 + noise then surface.set_tiles({{name = "water", position = pos}}) end
end
end
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
local noise = simplex_noise(pos.x * 0.006, 0, game.surfaces[1].map_gen_settings.seed) * 20
if pos.y <= 12 + noise and pos.y >= -12 + noise then
surface.set_tiles({{name = 'water', position = pos}})
end
end
end
end
function fish_eye(surface, position)
surface.request_to_generate_chunks(position, 2)
surface.force_generate_chunk_requests()
for x = -48, 48, 1 do
for y = -48, 48, 1 do
local p = {x = position.x + x, y = position.y + y}
--local distance = math_sqrt(((position.x - p.x) ^ 2) + ((position.y - p.y) ^ 2))
--if distance < 44 then
-- surface.set_tiles({{name = "water-green", position = p}}, true)
--end
--if distance < 22 then
-- surface.set_tiles({{name = "out-of-map", position = p}}, true)
--end
function Public.fish_eye(surface, position)
surface.request_to_generate_chunks(position, 2)
surface.force_generate_chunk_requests()
for x = -48, 48, 1 do
for y = -48, 48, 1 do
local p = {x = position.x + x, y = position.y + y}
--local distance = math_sqrt(((position.x - p.x) ^ 2) + ((position.y - p.y) ^ 2))
--if distance < 44 then
-- surface.set_tiles({{name = "water-green", position = p}}, true)
--end
--if distance < 22 then
-- surface.set_tiles({{name = "out-of-map", position = p}}, true)
--end
local distance = ((position.x - p.x) ^ 2) + ((position.y - p.y) ^ 2)
if distance < 1936 then
if distance < 484 then
surface.set_tiles({{name = "out-of-map", position = p}}, true)
else
surface.set_tiles({{name = "water-green", position = p}}, true)
end
end
end
end
local distance = ((position.x - p.x) ^ 2) + ((position.y - p.y) ^ 2)
if distance < 1936 then
if distance < 484 then
surface.set_tiles({{name = 'out-of-map', position = p}}, true)
else
surface.set_tiles({{name = 'water-green', position = p}}, true)
end
end
end
end
end
local ores = {"coal", "iron-ore", "copper-ore", "stone"}
local ores = {'coal', 'iron-ore', 'copper-ore', 'stone'}
local function plankton_territory(surface, position, seed)
local noise = simplex_noise(position.x * 0.009, position.y * 0.009, seed)
local d = 196
local tile_to_set = "out-of-map"
if position.x + position.y > (d * -1) - (math_abs(noise) * d * 3) and position.x > position.y - (d + (math_abs(noise) * d * 3)) then return "out-of-map" end
local noise_2 = simplex_noise(position.x * 0.0075, position.y * 0.0075, seed + 10000)
--if noise_2 > 0.87 then surface.set_tiles({{name = "deepwater-green", position = position}}, true) return true end
if noise_2 > 0.87 then return "deepwater-green" end
if noise_2 > 0.75 then
local i = math_floor(noise * 6) % 4 + 1
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
surface.create_entity({name = ores[i], position = position, amount = 1 + 2500 * math_abs(noise_2 * 3)})
return ("grass-" .. i)
end
if noise_2 < -0.76 then
local i = math_floor(noise * 6) % 4 + 1
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
if noise_2 < -0.86 then surface.create_entity({name = "uranium-ore", position = position, amount = 1 + 1000 * math_abs(noise_2 * 2)}) return ("grass-" .. i) end
if math_random(1, 3) ~= 1 then surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = position}) end
return ("grass-" .. i)
end
if noise < 0.12 and noise > -0.12 then
local i = math_floor(noise * 32) % 4 + 1
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
if math_random(1, 5) == 1 then surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = position}) end
return ("grass-" .. i)
end
--surface.set_tiles({{name = "water", position = position}}, true)
if math_random(1, 128) == 1 then surface.create_entity({name = "fish", position = position}) end
return "water"
local function plankton_territory(surface, position, seed)
local noise = simplex_noise(position.x * 0.009, position.y * 0.009, seed)
local d = 196
if
position.x + position.y > (d * -1) - (math_abs(noise) * d * 3) and
position.x > position.y - (d + (math_abs(noise) * d * 3))
then
return 'out-of-map'
end
local noise_2 = simplex_noise(position.x * 0.0075, position.y * 0.0075, seed + 10000)
--if noise_2 > 0.87 then surface.set_tiles({{name = "deepwater-green", position = position}}, true) return true end
if noise_2 > 0.87 then
return 'deepwater-green'
end
if noise_2 > 0.75 then
local i = math_floor(noise * 6) % 4 + 1
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
surface.create_entity({name = ores[i], position = position, amount = 1 + 2500 * math_abs(noise_2 * 3)})
return ('grass-' .. i)
end
if noise_2 < -0.76 then
local i = math_floor(noise * 6) % 4 + 1
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
if noise_2 < -0.86 then
surface.create_entity(
{name = 'uranium-ore', position = position, amount = 1 + 1000 * math_abs(noise_2 * 2)}
)
return ('grass-' .. i)
end
if math_random(1, 3) ~= 1 then
surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = position})
end
return ('grass-' .. i)
end
if noise < 0.12 and noise > -0.12 then
local i = math_floor(noise * 32) % 4 + 1
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
if math_random(1, 5) == 1 then
surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = position})
end
return ('grass-' .. i)
end
--surface.set_tiles({{name = "water", position = position}}, true)
if math_random(1, 128) == 1 then
surface.create_entity({name = 'fish', position = position})
end
return 'water'
end
local function process_chunk(left_top)
local surface = game.surfaces["fish_defender"]
local seed = game.surfaces[1].map_gen_settings.seed
generate_spawn_area(surface)
enemy_territory(surface, left_top)
fish_mouth(surface, left_top)
local tiles = {}
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
if is_out_of_map_tile(pos) then
--if not plankton_territory(surface, pos, seed) then surface.set_tiles({{name = "out-of-map", position = pos}}, true) end
local tile_to_set = plankton_territory(surface, pos, seed)
--local tile_to_set = "out-of-map"
table.insert(tiles, {name = tile_to_set, position = pos})
end
end
end
surface.set_tiles(tiles,true)
--if game.tick == 0 then return end
--if game.forces.player.is_chunk_charted(surface, {left_top.x / 32, left_top.y / 32}) then
game.forces.player.chart(surface, {{left_top.x, left_top.y},{left_top.x + 31, left_top.y + 31}})
--end
local active_surface = FDT.get('active_surface')
local market = FDT.get('market')
local surface = active_surface
local seed = game.surfaces[1].map_gen_settings.seed
generate_spawn_area(surface)
enemy_territory(surface, left_top)
fish_mouth(surface, left_top)
local tiles = {}
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
if is_out_of_map_tile(pos) then
--if not plankton_territory(surface, pos, seed) then surface.set_tiles({{name = "out-of-map", position = pos}}, true) end
local tile_to_set = plankton_territory(surface, pos, seed)
--local tile_to_set = "out-of-map"
table.insert(tiles, {name = tile_to_set, position = pos})
end
end
end
surface.set_tiles(tiles, true)
--if game.tick == 0 then return end
--if game.forces.player.is_chunk_charted(surface, {left_top.x / 32, left_top.y / 32}) then
game.forces.player.chart(surface, {{left_top.x, left_top.y}, {left_top.x + 31, left_top.y + 31}})
--end
if market and market.valid then
FDT.get().game_reset = false
end
end
local function process_chunk_queue()
for k, left_top in pairs(global.chunk_queue) do
process_chunk(left_top)
table.remove(global.chunk_queue, k)
return
end
local chunk_queue = FDT.get('chunk_queue')
for k, left_top in pairs(chunk_queue) do
process_chunk(left_top)
FDT.get().chunk_queue[k] = nil
return
end
end
local function on_chunk_generated(event)
if game.surfaces["fish_defender"].index ~= event.surface.index then return end
local left_top = event.area.left_top
if game.tick == 0 then
process_chunk(left_top)
else
table.insert(global.chunk_queue, {x = left_top.x, y = left_top.y})
end
local map_name = 'fish_defender'
if string.sub(event.surface.name, 0, #map_name) ~= map_name then
return
end
local left_top = event.area.left_top
local game_reset = FDT.get('game_reset')
local game_has_ended = FDT.get('game_has_ended')
local this = FDT.get()
if game.tick == 0 or game_reset then
process_chunk(left_top)
else
if game_has_ended then
return
end
this.chunk_queue[#this.chunk_queue + 1] = {x = left_top.x, y = left_top.y}
end
end
local event = require 'utils.event'
event.on_nth_tick(25, process_chunk_queue)
event.add(defines.events.on_chunk_generated, on_chunk_generated)
Event.on_nth_tick(25, process_chunk_queue)
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
return Public

View File

@ -1,44 +1,61 @@
local event = require 'utils.event'
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local radius = 20
local whitelist = {
["defender"] = "explosive-cannon-projectile",
["distractor"] = "explosive-uranium-cannon-projectile",
["destroyer"] = "explosive-uranium-cannon-projectile"
['defender'] = 'explosive-cannon-projectile',
['distractor'] = 'explosive-uranium-cannon-projectile',
['destroyer'] = 'explosive-uranium-cannon-projectile'
}
local function on_entity_died(event)
if not global.trapped_capsules_unlocked then return end
if not event.entity.valid then return end
if not whitelist[event.entity.name] then return end
local valid_targets = {}
local position = event.entity.position
for _, e in pairs(event.entity.surface.find_entities_filtered({area = {{position.x - radius, position.y - radius},{position.x + radius, position.y + radius}}, force = "enemy"})) do
if e.health then
local distance_from_center = math.sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
if distance_from_center <= radius then
valid_targets[#valid_targets + 1] = e
end
end
end
if not valid_targets[1] then return end
event.entity.surface.create_entity({
name = whitelist[event.entity.name],
position = position,
force = "player",
source = position,
target = valid_targets[math.random(1, #valid_targets)].position,
max_range = 20,
speed = 0.1
})
local trapped_capsules_unlocked = FDT.get('trapped_capsules_unlocked')
if not trapped_capsules_unlocked then
return
end
if not event.entity.valid then
return
end
if not whitelist[event.entity.name] then
return
end
local valid_targets = {}
local position = event.entity.position
for _, e in pairs(
event.entity.surface.find_entities_filtered(
{
area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}},
force = 'enemy'
}
)
) do
if e.health then
local distance_from_center = math.sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
if distance_from_center <= radius then
valid_targets[#valid_targets + 1] = e
end
end
end
if not valid_targets[1] then
return
end
event.entity.surface.create_entity(
{
name = whitelist[event.entity.name],
position = position,
force = 'player',
source = position,
target = valid_targets[math.random(1, #valid_targets)].position,
max_range = 20,
speed = 0.1
}
)
end
event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_entity_died, on_entity_died)

View File

@ -1,34 +1,52 @@
local event = require 'utils.event'
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local radius = 8
local function damage_entities_around_target(entity, damage)
for _, e in pairs(entity.surface.find_entities_filtered({area = {{entity.position.x - radius, entity.position.y - radius},{entity.position.x + radius, entity.position.y + radius}}})) do
if e.health then
if e.force.name ~= "player" then
local distance_from_center = math.sqrt((e.position.x - entity.position.x) ^ 2 + (e.position.y - entity.position.y) ^ 2)
if distance_from_center <= radius then
e.damage(damage, "player", "explosion")
end
end
end
end
for _, e in pairs(
entity.surface.find_entities_filtered(
{
area = {
{entity.position.x - radius, entity.position.y - radius},
{entity.position.x + radius, entity.position.y + radius}
}
}
)
) do
if e.health then
if e.force.name ~= 'player' then
local distance_from_center =
math.sqrt((e.position.x - entity.position.x) ^ 2 + (e.position.y - entity.position.y) ^ 2)
if distance_from_center <= radius then
e.damage(damage, 'player', 'explosion')
end
end
end
end
end
local function on_entity_died(event)
if not global.ultra_mines_unlocked then return end
if not event.entity.valid then return end
if event.entity.name ~= "land-mine" then return end
event.entity.surface.create_entity({
name = "big-artillery-explosion",
position = event.entity.position
})
local damage = (1 + event.entity.force.get_ammo_damage_modifier("grenade")) * 250
damage_entities_around_target(event.entity, damage)
local ultra_mines_unlocked = FDT.get('ultra_mines_unlocked')
if not ultra_mines_unlocked then
return
end
if not event.entity.valid then
return
end
if event.entity.name ~= 'land-mine' then
return
end
event.entity.surface.create_entity(
{
name = 'big-artillery-explosion',
position = event.entity.position
}
)
local damage = (1 + event.entity.force.get_ammo_damage_modifier('grenade')) * 250
damage_entities_around_target(event.entity, damage)
end
event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_entity_died, on_entity_died)

View File

@ -1,16 +1,29 @@
local event = require 'utils.event'
local Event = require 'utils.event'
local FDT = require 'maps.fish_defender.table'
local function on_player_changed_position(event)
if not global.vehicle_nanobots_unlocked then return end
local player = game.players[event.player_index]
if not player.character then return end
if not player.character.driving then return end
if not player.vehicle then return end
if not player.vehicle.valid then return end
if player.vehicle.health == player.vehicle.prototype.max_health then return end
player.vehicle.health = player.vehicle.health + player.vehicle.prototype.max_health * 0.005
local vehicle_nanobots_unlocked = FDT.get('vehicle_nanobots_unlocked')
if not vehicle_nanobots_unlocked then
return
end
local player = game.players[event.player_index]
if not player.character then
return
end
if not player.character.driving then
return
end
if not player.vehicle then
return
end
if not player.vehicle.valid then
return
end
if player.vehicle.health == player.vehicle.prototype.max_health then
return
end
player.vehicle.health = player.vehicle.health + player.vehicle.prototype.max_health * 0.005
end
event.add(defines.events.on_player_changed_position, on_player_changed_position)
Event.add(defines.events.on_player_changed_position, on_player_changed_position)