1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-05 13:15:03 +02:00

Difficulty and biter boat adjustments

Changes:
- In hard and nightmare difficulties, spawners have a chance to become elite.
- Biter boats now can arrive at any time, instead of only arriving within few minutes of crew ship's landing.
- Fixed memory leak with healthbars.

Previous change update:
- Allowing ore to spawn on top of another in walkways.
- Disabled boat steering in Mysterious Caves island.
This commit is contained in:
Piratux 2023-02-01 16:24:42 +02:00
parent a1a3e7d1b9
commit b579ff27f9
12 changed files with 232 additions and 158 deletions

View File

@ -307,7 +307,7 @@ function Public.create_mail_delivery_biters() --these travel cross-map between b
local surface = game.surfaces[Common.current_destination().surface_name]
local enemy_force_name = memory.enemy_force_name
local spawners = Public.get_valid_spawners(surface)
local spawners = Common.get_valid_spawners(surface)
local try_how_many_groups = Math.clamp(0, 4, (#spawners - 8) / 100)
@ -360,7 +360,7 @@ function Public.spawn_group_of_scripted_biters(fraction_of_floating_pollution, m
local surface = game.surfaces[Common.current_destination().surface_name]
local enemy_force_name = memory.enemy_force_name
local spawner = Public.get_random_valid_spawner(surface)
local spawner = Common.get_random_valid_spawner(surface)
if not spawner then log('no spawner found') return end
local nearby_units_to_bring
@ -587,50 +587,6 @@ end
-- return false
-- end
function Public.get_valid_spawners(surface)
local memory = Memory.get_crew_memory()
local spawners = surface.find_entities_filtered({type = 'unit-spawner', force = memory.enemy_force_name})
local boat_spawners = {}
if memory.enemyboats and #memory.enemyboats > 0 then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if eb.spawner and eb.spawner.valid then
boat_spawners[#boat_spawners + 1] = eb.spawner
end
end
end
local valid_spawners = {}
for i = 1, #spawners do
local s = spawners[i]
local valid = true
for j = 1, #boat_spawners do
local bs = boat_spawners[j]
if s == bs then
valid = false
break
end
end
if valid then
valid_spawners[#valid_spawners + 1] = s
end
end
return valid_spawners
end
function Public.get_random_valid_spawner(surface)
local spawners = Public.get_valid_spawners(surface)
if #spawners == 0 then return end
return spawners[Math.random(#spawners)]
end
function Public.is_biter_inactive(biter)
if (not biter.entity) or (not biter.entity.valid) then
return true

View File

@ -160,7 +160,7 @@ local function damage_to_silo(event)
destination.dynamic_data.rocketsilos[1].valid and
entity == Common.current_destination().dynamic_data.rocketsilos[1]
then
if string.sub(event.cause.force.name, 1, 4) ~= 'crew' then
if string.sub(event.cause.force.name, 1, 4) ~= 'crew' then -- @Piratux: wonder why this is needed
-- play alert sound for all crew members
if memory.seconds_until_alert_sound_can_be_played_again <= 0 then
@ -172,10 +172,12 @@ local function damage_to_silo(event)
end
end
if Common.entity_damage_healthbar(entity, event.original_damage_amount / Balance.silo_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))) <= 0 then
local damage = event.original_damage_amount / Balance.silo_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))
local remaining_health = Common.entity_damage_healthbar(entity, damage, destination.dynamic_data)
if remaining_health and remaining_health <= 0 then
Public.silo_die()
else
destination.dynamic_data.rocketsilohp = memory.healthbars[entity.unit_number].health
destination.dynamic_data.rocketsilohp = remaining_health
end
else
entity.health = entity.prototype.max_health
@ -187,29 +189,52 @@ end
local function damage_to_enemyboat_spawners(event)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
if memory.enemyboats and
#memory.enemyboats > 0 and
if destination.dynamic_data.enemyboats and
#destination.dynamic_data.enemyboats > 0 and
event.cause and
event.cause.valid and
event.entity and
event.entity.valid and
event.entity.force.name == memory.enemy_force_name
then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
for i = 1, #destination.dynamic_data.enemyboats do
local eb = destination.dynamic_data.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity == eb.spawner then
-- if eb.spawner and eb.spawner.valid and event.entity == eb.spawner and eb.state == Structures.Boats.enum_state.APPROACHING then
local damage = event.final_damage_amount
local adjusted_damage = damage
local remaining_health = Common.entity_damage_healthbar(event.entity, damage, destination.dynamic_data)
adjusted_damage = adjusted_damage / 2.6
if remaining_health and remaining_health <= 0 then
event.entity.die()
end
end
end
end
end
-- if event.cause.name == 'artillery-turret' then
-- adjusted_damage = adjusted_damage / 1
-- end
-- Does not include krakens or biter boat spawners
local function damage_to_elite_spawners(event)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
if destination.dynamic_data.elite_spawners and
#destination.dynamic_data.elite_spawners > 0 and
event.cause and
event.cause.valid and
event.entity and
event.entity.valid and
event.entity.force.name == memory.enemy_force_name
then
for i = 1, #destination.dynamic_data.elite_spawners do
local spawner = destination.dynamic_data.elite_spawners[i]
if spawner and spawner.valid and event.entity == spawner then
local damage = event.final_damage_amount
local remaining_health = Common.entity_damage_healthbar(event.entity, damage, destination.dynamic_data)
if remaining_health and remaining_health <= 0 then
event.entity.die()
end
end
@ -224,15 +249,7 @@ local function damage_to_artillery(event)
if not event.cause.valid then return end
if not event.cause.name then return end
if (event.cause.name == 'small-biter')
or (event.cause.name == 'small-spitter')
or (event.cause.name == 'medium-biter')
or (event.cause.name == 'medium-spitter')
or (event.cause.name == 'big-biter')
or (event.cause.name == 'big-spitter')
or (event.cause.name == 'behemoth-biter')
or (event.cause.name == 'behemoth-spitter')
then
if Utils.contains(CoreData.enemy_units, event.cause.name) then
if event.cause.force.name ~= memory.enemy_force_name then return end
-- play alert sound for all crew members
@ -248,7 +265,11 @@ local function damage_to_artillery(event)
-- remove resistances:
-- event.entity.health = event.entity.health + event.final_damage_amount - event.original_damage_amount
if Common.entity_damage_healthbar(event.entity, event.original_damage_amount / Balance.cannon_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)), Memory.get_crew_memory().boat) <= 0 then
local damage = event.original_damage_amount / Balance.cannon_resistance_factor
damage = damage * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))
local remaining_health = Common.entity_damage_healthbar(event.entity, damage, memory.boat)
if remaining_health and remaining_health <= 0 then
event.entity.die()
end
else
@ -279,7 +300,6 @@ local function damage_to_krakens(event)
local adjusted_damage = damage
if event.damage_type.name and event.damage_type.name == 'poison' then
-- if event.cause.name == 'artillery-turret' then
adjusted_damage = adjusted_damage / 1.25
elseif event.damage_type.name and (event.damage_type.name == 'explosion') then
adjusted_damage = adjusted_damage / 1.5
@ -295,8 +315,13 @@ local function damage_to_krakens(event)
adjusted_damage = adjusted_damage / 7 --laser turrets are in range. give some resistance
end
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
Kraken.kraken_die(memory.healthbars[unit_number].id)
-- There should be a better way to do it than this...
if memory.healthbars and memory.healthbars[unit_number] then
local kraken_id = memory.healthbars[unit_number].id
local remaining_health = Common.entity_damage_healthbar(event.entity, adjusted_damage)
if remaining_health and remaining_health <= 0 then
Kraken.kraken_die(kraken_id)
end
end
end
@ -346,17 +371,9 @@ local function damage_to_players_changes(event)
end
elseif class == Classes.enum.VETERAN then
local chance = Balance.veteran_on_hit_slow_chance
if Math.random() < chance then
if Math.random() <= chance then
-- only certain targets accept stickers
if event.cause.name == 'small-biter' or
event.cause.name == 'small-spitter' or
event.cause.name == 'medium-biter' or
event.cause.name == 'medium-spitter' or
event.cause.name == 'big-biter' or
event.cause.name == 'big-spitter' or
event.cause.name == 'behemoth-biter' or
event.cause.name == 'behemoth-spitter'
then
if Utils.contains(CoreData.enemy_units, event.cause.name) then
player.surface.create_entity{
name = 'slowdown-sticker',
position = player.character.position,
@ -616,6 +633,7 @@ local function event_on_entity_damaged(event)
damage_to_silo(event)
damage_to_krakens(event)
damage_to_enemyboat_spawners(event)
damage_to_elite_spawners(event)
if event.entity and event.entity.valid and event.entity.name and event.entity.name == 'artillery-turret' then
damage_to_artillery(event)
@ -1000,10 +1018,13 @@ local function event_on_player_mined_entity(event)
local points_to_avoid = destination.dynamic_data.ore_spawn_points_to_avoid
local can_place_ores = true
for _, pos in ipairs(points_to_avoid) do
if Math.distance(pos, entity.position) < Balance.min_ore_spawn_distance then
can_place_ores = false
break
-- Sometimes there can be very little amount of rocks here, so it probably isn't bad idea to spawn ore on top of another
if destination.subtype ~= IslandEnum.enum.WALKWAYS then
for _, pos in ipairs(points_to_avoid) do
if Math.distance(pos, entity.position) < Balance.min_ore_spawn_distance then
can_place_ores = false
break
end
end
end
@ -1168,9 +1189,9 @@ local function base_kill_rewards(event)
if (entity_name == 'biter-spawner' or entity_name == 'spitter-spawner') and entity.position and entity.surface and entity.surface.valid then
--check if its a boat biter entity
local boat_spawner = false
if memory.enemyboats then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if destination.dynamic_data.enemyboats then
for i = 1, #destination.dynamic_data.enemyboats do
local eb = destination.dynamic_data.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity == eb.spawner then
boat_spawner = true
break
@ -1194,9 +1215,9 @@ local function spawner_died(event)
if (destination and destination.type and destination.type == Surfaces.enum.ISLAND) then
local not_boat = true
if memory.enemyboats and #memory.enemyboats > 0 then
for i = 1, #memory.enemyboats do
local eb = memory.enemyboats[i]
if destination.dynamic_data.enemyboats and #destination.dynamic_data.enemyboats > 0 then
for i = 1, #destination.dynamic_data.enemyboats do
local eb = destination.dynamic_data.enemyboats[i]
if eb.spawner and eb.spawner.valid and event.entity and event.entity.valid and event.entity == eb.spawner then
not_boat = false
break

View File

@ -813,9 +813,9 @@ function Public.boat_movement_tick(tickinterval)
end
end
if memory.enemyboats then
for i = 1, #memory.enemyboats do
local eboat = memory.enemyboats[i]
if destination.dynamic_data.enemyboats then
for i = 1, #destination.dynamic_data.enemyboats do
local eboat = destination.dynamic_data.enemyboats[i]
if eboat and eboat.surface_name and game.surfaces[eboat.surface_name] and game.surfaces[eboat.surface_name].valid then
if eboat.state == Boats.enum_state.APPROACHING and eboat.speed and eboat.speed > 0 and memory.game_lost == false then
local ticker_increase = eboat.speed / 60 * tickinterval
@ -860,7 +860,7 @@ function Public.boat_movement_tick(tickinterval)
do end
end
else
memory.enemyboats[i] = nil
destination.dynamic_data.enemyboats[i] = nil
end
end
end
@ -1161,17 +1161,17 @@ function Public.slower_boat_tick(tickinterval)
game.pollution_statistics.on_flow('locomotive', pollution)
end
if memory.enemyboats then
for i = 1, #memory.enemyboats do
local b = memory.enemyboats[i]
-- if memory.enemyboats then
-- for i = 1, #memory.enemyboats do
-- local b = memory.enemyboats[i]
-- if b.landing_time and destination.dynamic_data.timer and destination.dynamic_data.timer >= b.landing_time and b.spawner and b.spawner.valid then
-- -- if b.landing_time and destination.dynamic_data.timer and destination.dynamic_data.timer >= b.landing_time + 3 and b.spawner and b.spawner.valid then
-- b.spawner.destructible = true
-- b.landing_time = nil
-- end
end
end
-- -- if b.landing_time and destination.dynamic_data.timer and destination.dynamic_data.timer >= b.landing_time and b.spawner and b.spawner.valid then
-- -- -- if b.landing_time and destination.dynamic_data.timer and destination.dynamic_data.timer >= b.landing_time + 3 and b.spawner and b.spawner.valid then
-- -- b.spawner.destructible = true
-- -- b.landing_time = nil
-- -- end
-- end
-- end
end
function Public.LOS_tick(tickinterval)

View File

@ -90,6 +90,8 @@ Public.prevent_waves_from_spawning_in_cave_timer_length = 10 -- in seconds
Public.min_ore_spawn_distance = 20
Public.biter_boat_average_arrival_rate = 8*60 -- in seconds
function Public.starting_boatEEIpower_production_MW()
-- return 3 * Math.sloped(Common.capacity_scale(), 1/2) / 2 --/2 as we have 2
return 3/2
@ -569,7 +571,11 @@ function Public.krakens_per_free_slot(overworldx)
end
function Public.biter_boat_health()
return Math.ceil(700 * Math.max(1, 1 + 0.075 * (Common.overworldx()/40)^(13/10)) * (Public.crew_scale()^(1/5)) * Math.sloped(Common.difficulty_scale(), 3/4))
return Math.ceil(1500 * Math.max(1, 1 + 0.075 * (Common.overworldx()/40)^(13/10)) * (Public.crew_scale()^(1/5)) * Math.sloped(Common.difficulty_scale(), 3/4))
end
function Public.elite_spawner_health()
return Math.ceil(5000 * Math.max(1, 1 + 0.075 * (Common.overworldx()/40)^(13/10)) * (Public.crew_scale()^(1/5)) * Math.sloped(Common.difficulty_scale(), 3/4))
end
function Public.main_shop_cost_multiplier()

View File

@ -658,7 +658,7 @@ if _DEBUG then
if not Common.get_id_from_force_name(player.character.force.name) then
local proposal = {
capacity_option = 3,
difficulty_option = 2,
difficulty_option = 4,
-- mode_option = 'left',
endorserindices = { 1 },
name = "AdminRun"
@ -898,10 +898,9 @@ if _DEBUG then
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
Islands.spawn_enemy_boat(Boats.enum.RAFT)
local boat = memory.enemyboats[1]
local boat = destination.dynamic_data.enemyboats[1]
Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width)
game.print('enemy boat spawned')
end
@ -914,10 +913,9 @@ if _DEBUG then
cmd_set_memory(cmd)
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
Islands.spawn_enemy_boat(Boats.enum.RAFTLARGE)
local boat = memory.enemyboats[1]
local boat = destination.dynamic_data.enemyboats[1]
Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width)
game.print('large enemy boat spawned')
end
@ -1159,7 +1157,7 @@ if _DEBUG then
end
for i = -2, 2 do
local p1 = scope.Data.cannons[2]
local p2 = {x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y + 4}
local p2 = {x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y + 3}
local e = surface.create_entity({name = 'gun-turret', position = p2, force = boat.force_name, create_build_effect_smoke = false})
if e and e.valid then
e.insert({name = "uranium-rounds-magazine", count = 200})

View File

@ -744,6 +744,7 @@ end
function Public.transfer_healthbar(old_unit_number, new_entity, location_override)
location_override = location_override or Memory.get_crew_memory()
if not location_override.healthbars then return end
local old_healthbar = location_override.healthbars[old_unit_number]
-- local new_unit_number = new_entity.unit_number
@ -771,11 +772,12 @@ end
function Public.entity_damage_healthbar(entity, damage, location_override)
location_override = location_override or Memory.get_crew_memory()
local unit_number = entity.unit_number
if not (location_override.healthbars) then return end
local unit_number = entity.unit_number
local healthbar = location_override.healthbars[unit_number]
if not healthbar then return 0 end
if not healthbar then return end
local new_health = healthbar.health - damage
healthbar.health = new_health
@ -785,6 +787,10 @@ function Public.entity_damage_healthbar(entity, damage, location_override)
entity.health = entity.prototype.max_health
end
if healthbar.health <= 0 then
location_override.healthbars[unit_number] = nil
end
return healthbar.health
end
@ -1705,4 +1711,49 @@ function Public.replace_unwalkable_tiles(surface, position, width, height)
end
end
function Public.get_valid_spawners(surface)
local memory = Memory.get_crew_memory()
local destination = Public.current_destination()
local spawners = surface.find_entities_filtered({type = 'unit-spawner', force = memory.enemy_force_name})
local boat_spawners = {}
if destination.dynamic_data.enemyboats and #destination.dynamic_data.enemyboats > 0 then
for i = 1, #destination.dynamic_data.enemyboats do
local eb = destination.dynamic_data.enemyboats[i]
if eb.spawner and eb.spawner.valid then
boat_spawners[#boat_spawners + 1] = eb.spawner
end
end
end
local valid_spawners = {}
for i = 1, #spawners do
local s = spawners[i]
local valid = true
for j = 1, #boat_spawners do
local bs = boat_spawners[j]
if s == bs then
valid = false
break
end
end
if valid and s.valid then
valid_spawners[#valid_spawners + 1] = s
end
end
return valid_spawners
end
function Public.get_random_valid_spawner(surface)
local spawners = Public.get_valid_spawners(surface)
if #spawners == 0 then return end
return spawners[Math.random(#spawners)]
end
return Public

View File

@ -90,7 +90,6 @@ function Public.initialise_crew_memory(id) --mostly serves as a dev reference of
memory.speed_boost_characters = nil
memory.enemyboats = nil
memory.overworld_krakens = nil
memory.active_sea_enemies = nil
memory.kraken_stream_registrations = nil

View File

@ -283,8 +283,6 @@ function Public.progress_to_destination(destination_index)
boat.state = destination_data.init_boat_state
boat.dockedposition = nil
memory.enemyboats = {}
local old_water = 'deepwater'
if old_type == Surfaces.enum.LOBBY or old_type == Surfaces.enum.DOCK then old_water = 'water' end
@ -312,6 +310,10 @@ function Public.progress_to_destination(destination_index)
destination.dynamic_data.timer = 0
destination.dynamic_data.timeratlandingtime = nil
destination.dynamic_data.enemyboats = {}
destination.dynamic_data.elite_spawners = {}
destination.dynamic_data.healthbars = {}
memory.extra_time_at_sea = 0

View File

@ -256,7 +256,7 @@ Public.entry_price_data_raw = {
['steel-chest'] = {
overallWeight = 0.5,
minLambda = 0.2,
maxLambda = 0.7,
maxLambda = 1,
shape = false,
base_amount = 125,
raw_materials = {{name = 'steel-plate', count = 1000}}
@ -264,7 +264,7 @@ Public.entry_price_data_raw = {
['rail'] = {
overallWeight = 1,
minLambda = 0.2,
maxLambda = 0.8,
maxLambda = 1,
shape = false,
base_amount = 400,
raw_materials = {{name = 'iron-plate', count = 1100}}

View File

@ -31,14 +31,16 @@ function Public.choose_quest_structure_type()
local destination = Common.current_destination()
local subtype = destination.subtype
local rng = Math.random(3)
if subtype == IslandEnum.enum.WALKWAYS then
return enum.MARKET1
end
-- Furnace quests are more interesting after that rather than collecting stone furnaces
if Common.overworldx() >= 600 then
return enum.FURNACE1
end
if rng == 1 or subtype and subtype == IslandEnum.enum.WALKWAYS then
if Math.random(3) == 1 then
return enum.MARKET1
else
return enum.FURNACE1

View File

@ -303,7 +303,7 @@ function Public.spawn_silo_setup(points_to_avoid)
silo.operable = false
if i == 1 then
silo.auto_launch = true
Common.new_healthbar(true, silo, Balance.silo_max_hp, nil, Balance.silo_max_hp, 0.6, -2)
Common.new_healthbar(true, silo, Balance.silo_max_hp, nil, Balance.silo_max_hp, 0.6, -2, destination.dynamic_data)
else
silo.destructible = false
end
@ -345,20 +345,21 @@ end
-- NOTE: Currently the boats can trigger landing early if 2 boats spawn in same lane in short interval. Too lazy to fix.
-- NOTE: As well as biter boats can miss the island on smaller ones when boat is steered
function Public.spawn_enemy_boat(type)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
local offsets = {50, -50, 63, -63}
local offsets = {50, -50, 63, -63, 76, -76, 89, -89}
local enemyboats = memory.enemyboats
local enemyboats = destination.dynamic_data.enemyboats
if enemyboats then
local boat = {
state = Boats.enum_state.APPROACHING,
type = type,
speed = 4,
position = {x = - surface.map_gen_settings.width/2 + 23.5, y = (memory.boat.dockedposition or memory.boat.position).y + offsets[Math.random(4)]},
position = {x = - surface.map_gen_settings.width/2 + 23.5, y = (memory.boat.dockedposition or memory.boat.position).y + offsets[Math.random(#offsets)]},
force_name = memory.enemy_force_name,
surface_name = surface.name,
unit_group = nil,
@ -375,7 +376,7 @@ function Public.spawn_enemy_boat(type)
boat.spawner = e
local max_health = Balance.biter_boat_health()
Common.new_healthbar(true, e, max_health, nil, max_health, 0.5)
Common.new_healthbar(true, e, max_health, nil, max_health, 0.5, nil, destination.dynamic_data)
end
return enemyboats[#enemyboats]

View File

@ -180,9 +180,9 @@ function Public.destination_on_collide(destination)
Common.parrot_speak(memory.force, {'pirates.parrot_cave_tip_1'})
else
local scheduled_raft_raids
local scheduled_raft_raids = {}
-- temporarily placed this back here, as moving it to shorehit broke things:
local playercount = Common.activecrewcount()
-- local playercount = Common.activecrewcount()
local max_evo
local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(Common.difficulty_scale())
@ -209,34 +209,53 @@ function Public.destination_on_collide(destination)
-- Currently biter boats don't spawn properly for cave island, so disabling it for now
if destination.subtype ~= IslandEnum.enum.CAVE then
if memory.overworldx > 200 then
scheduled_raft_raids = {}
local times = {600, 360, 215, 210, 120, 30, 10, 5}
for i = 1, #times do
local t = times[i]
if Math.random(6) == 1 and #scheduled_raft_raids < 6 then
scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_evo = max_evo}
-- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_bonus_evolution = 0.52}
-- if memory.overworldx > 200 then
-- scheduled_raft_raids = {}
-- local times = {600, 360, 215, 210, 120, 30, 10, 5}
-- for i = 1, #times do
-- local t = times[i]
-- if Math.random(6) == 1 and #scheduled_raft_raids < 6 then
-- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_evo = max_evo}
-- -- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_bonus_evolution = 0.52}
-- end
-- end
-- elseif memory.overworldx == 200 then
-- local times
-- if playercount <= 2 then
-- times = {1, 5, 10, 15, 20}
-- elseif playercount <= 8 then
-- times = {1, 5, 10, 15, 20, 25}
-- elseif playercount <= 15 then
-- times = {1, 5, 10, 15, 20, 25, 30}
-- elseif playercount <= 21 then
-- times = {1, 5, 10, 15, 20, 25, 30, 35}
-- else
-- times = {1, 5, 10, 15, 20, 25, 30, 35, 40}
-- end
-- scheduled_raft_raids = {}
-- for _, t in pairs(times) do
-- -- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_bonus_evolution = 0.62}
-- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_evo = max_evo}
-- end
-- end
-- NOTE: No need to scale boat count as boat spawner health already scales
local max_time = Balance.max_time_on_island(destination.subtype)
local boat_count = Math.floor(max_time / Balance.biter_boat_average_arrival_rate) - 2 -- avoid spawning biter boats at very last seconds
for i = 1, boat_count do
local spawn_time = Math.random((i-1) * Balance.biter_boat_average_arrival_rate, (i+1) * Balance.biter_boat_average_arrival_rate)
spawn_time = spawn_time + 5
if memory.overworldx == 200 then
if i == 1 then
spawn_time = 5
elseif i == 2 then
spawn_time = 15
end
end
elseif memory.overworldx == 200 then
local times
if playercount <= 2 then
times = {1, 5, 10, 15, 20}
elseif playercount <= 8 then
times = {1, 5, 10, 15, 20, 25}
elseif playercount <= 15 then
times = {1, 5, 10, 15, 20, 25, 30}
elseif playercount <= 21 then
times = {1, 5, 10, 15, 20, 25, 30, 35}
else
times = {1, 5, 10, 15, 20, 25, 30, 35, 40}
end
scheduled_raft_raids = {}
for _, t in pairs(times) do
-- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_bonus_evolution = 0.62}
scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_evo = max_evo}
end
scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = spawn_time, max_evo = max_evo}
end
destination.static_params.scheduled_raft_raids = scheduled_raft_raids
@ -465,6 +484,25 @@ function Public.destination_on_crewboat_hits_shore(destination)
ShopMerchants.generate_merchant_trades(destination.dynamic_data.merchant_market)
end
if CoreData.get_difficulty_option_from_value(memory.difficulty) >= 3 and
destination.subtype ~= IslandEnum.enum.FIRST
then
local surface = game.surfaces[destination.surface_name]
local spawner = Common.get_random_valid_spawner(surface)
if spawner then
local max_health = Balance.elite_spawner_health()
Common.new_healthbar(true, spawner, max_health, nil, max_health, 0.8, nil, destination.dynamic_data)
local elite_spawners = destination.dynamic_data.elite_spawners
if elite_spawners then
elite_spawners[#elite_spawners + 1] = spawner
end
spawner.destructible = true
end
end
end
end