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:
parent
a1a3e7d1b9
commit
b579ff27f9
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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})
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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}}
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user