2022-06-01 20:50:36 +02:00
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
2021-10-13 10:21:53 +02:00
local Public = { }
local Math = require ' maps.pirates.math '
2022-05-29 13:43:31 +02:00
-- local Raffle = require 'maps.pirates.raffle'
2022-03-19 23:20:55 +02:00
-- local Memory = require 'maps.pirates.memory'
2021-10-13 10:21:53 +02:00
local Common = require ' maps.pirates.common '
2023-02-19 21:08:21 +02:00
-- local CoreData = require 'maps.pirates.coredata'
2022-05-29 13:43:31 +02:00
-- local Utils = require 'maps.pirates.utils_local'
2022-07-18 14:50:18 +02:00
-- local _inspect = require 'utils.inspect'.inspect
2021-10-13 10:21:53 +02:00
2023-01-29 15:02:06 +02:00
local IslandEnum = require ' maps.pirates.surfaces.islands.island_enum '
2022-03-09 01:36:03 +02:00
-- this file is an API to all the balance tuning knobs
2022-06-02 21:08:55 +02:00
2022-06-06 22:13:58 +02:00
-- Kraken related parameters
2023-01-12 23:34:44 +02:00
Public.biter_swim_speed = 1.5
2022-06-06 22:13:58 +02:00
Public.kraken_biter_spawn_radius = 6 -- only used during non automatic forced spawning during kraken's "special ability"
2022-07-30 15:02:24 +02:00
Public.kraken_spit_targeting_player_chance = 0
2022-06-06 22:13:58 +02:00
2022-06-02 21:08:55 +02:00
Public.base_extra_character_speed = 1.44
2022-07-30 11:29:17 +02:00
Public.respawn_speed_boost = 1.85
2021-10-13 10:21:53 +02:00
2022-06-08 15:26:49 +02:00
-- maximum rate at which alert sound can be played when important buildings are damaged (like silo or cannons)
-- NOTE: frequency can sometimes be faster by 1 second than denoted, but accuracy doesn't really matter here
Public.alert_sound_max_frequency_in_seconds = 3
2022-06-04 20:52:55 +02:00
Public.cannon_extra_hp_for_upgrade = 1000
2022-06-03 15:15:42 +02:00
Public.cannon_starting_hp = 2000
2022-06-04 20:52:55 +02:00
Public.cannon_resistance_factor = 2
2021-10-13 10:21:53 +02:00
Public.technology_price_multiplier = 1
2022-07-31 11:40:10 +02:00
Public.base_caught_fish_amount = 3
Public.class_reward_tick_rate_in_seconds = 7
Public.poison_damage_multiplier = 1.85
2023-02-19 22:42:07 +02:00
Public.every_nth_tree_gives_coins = 10
2022-07-31 11:40:10 +02:00
2023-07-01 21:13:49 +02:00
Public.samurai_damage_taken_multiplier = 0.45
2022-07-31 11:40:10 +02:00
Public.samurai_damage_dealt_when_not_melee_multiplier = 0.75
2023-07-01 21:13:49 +02:00
Public.samurai_damage_dealt_with_melee = 30
Public.hatamoto_damage_taken_multiplier = 0.3
2022-07-31 11:40:10 +02:00
Public.hatamoto_damage_dealt_when_not_melee_multiplier = 0.75
2023-07-01 21:13:49 +02:00
Public.hatamoto_damage_dealt_with_melee = 50
2022-12-07 21:16:22 +02:00
Public.iron_leg_damage_taken_multiplier = 0.24
2022-07-31 11:40:10 +02:00
Public.iron_leg_iron_ore_required = 3000
Public.deckhand_extra_speed = 1.25
2022-10-10 22:30:16 +02:00
Public.deckhand_ore_grant_multiplier = 5
2022-07-31 11:40:10 +02:00
Public.boatswain_extra_speed = 1.25
2022-10-10 22:30:16 +02:00
Public.boatswain_ore_grant_multiplier = 8
2022-07-31 11:40:10 +02:00
Public.shoresman_extra_speed = 1.1
2023-02-20 23:21:20 +02:00
Public.shoresman_ore_grant_multiplier = 3
2022-07-31 11:40:10 +02:00
Public.quartermaster_range = 19
Public.quartermaster_bonus_physical_damage = 1.3
Public.scout_extra_speed = 1.3
Public.scout_damage_taken_multiplier = 1.25
Public.scout_damage_dealt_multiplier = 0.6
2022-11-18 15:49:03 +02:00
Public.fisherman_fish_bonus = 2
2022-07-31 11:40:10 +02:00
Public.fisherman_reach_bonus = 10
2023-02-19 22:42:07 +02:00
Public.lumberjack_coins_from_tree_multiplier = 2
Public.lumberjack_ore_base_amount = 8
2022-07-31 11:40:10 +02:00
Public.master_angler_reach_bonus = 16
2022-11-18 15:49:03 +02:00
Public.master_angler_fish_bonus = 4
2022-07-31 11:40:10 +02:00
Public.master_angler_coin_bonus = 20
Public.dredger_reach_bonus = 16
2022-11-18 15:49:03 +02:00
Public.dredger_fish_bonus = 6
2022-07-31 11:40:10 +02:00
Public.gourmet_ore_scaling_enabled = false
Public.chef_fish_received_for_biter_kill = 1
Public.chef_fish_received_for_worm_kill = 3
Public.rock_eater_damage_taken_multiplier = 0.8
Public.rock_eater_required_stone_furnace_to_heal_count = 1
Public.soldier_defender_summon_chance = 0.2
Public.veteran_destroyer_summon_chance = 0.2
2023-02-01 22:17:22 +02:00
Public.veteran_on_hit_slow_chance = 1
2023-01-31 00:25:43 +02:00
Public.medic_heal_radius = 15
Public.medic_heal_percentage_amount = 0.1
Public.doctor_heal_radius = 20
Public.doctor_heal_percentage_amount = 0.15
Public.shaman_energy_required_per_summon = 1000000
Public.shaman_max_charge = 30000000
2023-02-07 14:58:48 +02:00
Public.shaman_summoned_biter_time_to_live = 60 * 2 -- in seconds
2023-02-12 00:01:53 +02:00
Public.shaman_passive_charge = 200000 -- each second
2023-01-31 00:25:43 +02:00
Public.class_cycle_count = 5 -- How many classes should be purchased to have a chance to buy the same class again
2022-06-03 21:55:57 +02:00
2023-02-12 00:01:53 +02:00
Public.maximum_fish_allowed_to_catch_at_sea = 40
2023-01-11 22:15:55 +02:00
2023-01-12 18:58:53 +02:00
Public.prevent_waves_from_spawning_in_cave_timer_length = 10 -- in seconds
2023-02-04 19:39:07 +02:00
Public.min_ore_spawn_distance = 10
2021-10-13 10:21:53 +02:00
2023-02-08 19:41:52 +02:00
Public.biter_boats_start_arrive_x = 40 * 5
Public.need_resources_to_undock_x = 40 * 20
2023-02-01 16:24:42 +02:00
2023-06-29 23:47:50 +02:00
Public.biters_spawned_on_elite_biter_death = 4
2023-07-01 21:13:49 +02:00
Public.walkways_frozen_pool_damage = 12
2021-10-13 10:21:53 +02:00
function Public . starting_boatEEIpower_production_MW ( )
-- return 3 * Math.sloped(Common.capacity_scale(), 1/2) / 2 --/2 as we have 2
return 3 / 2
end
function Public . starting_boatEEIelectric_buffer_size_MJ ( ) --maybe needs to be at least the power_production
-- return 3 * Math.sloped(Common.capacity_scale(), 1/2) / 2 --/2 as we have 2
return 3 / 2
end
Public.EEI_stages = { --multipliers
2023-01-28 20:08:16 +02:00
1 , 2 , 4 , 6 , 8 , 11 , 14
2021-10-13 10:21:53 +02:00
}
function Public . scripted_biters_pollution_cost_multiplier ( )
2023-02-21 13:27:48 +02:00
return ( 1.1 / Math.sloped ( Common.difficulty_scale ( ) , 0.7 ) ) * ( 1 + 1.2 / ( ( 1 + ( Common.overworldx ( ) / 40 ) ) ^ ( 1.5 + Common.difficulty_scale ( ) ) ) ) -- the complicated factor just makes the early-game easier; in particular the first island, but on easier difficulties the next few islands as well
2021-10-13 10:21:53 +02:00
end
2021-10-14 11:23:34 +02:00
function Public . cost_to_leave_multiplier ( )
2022-05-03 14:52:21 +02:00
-- return Math.sloped(Common.difficulty_scale(), 7/10) --should scale with difficulty similar to, but slightly slower than, passive fuel depletion rate --Edit: not sure about this?
-- return Math.sloped(Common.difficulty_scale(), 9/10)
2022-03-14 14:44:30 +02:00
-- extra factor now that the cost scales with time:
2023-01-29 20:20:29 +02:00
-- return Math.sloped(Common.difficulty_scale(), 8/10)
2023-01-31 00:25:43 +02:00
return 0.6 * Math.sloped ( Common.difficulty_scale ( ) , 0.4 )
2021-10-14 11:23:34 +02:00
end
2023-01-29 23:01:48 +02:00
-- Avoid using e >= 1/4 in calculations "crew_scale()^(e)" to strictly avoid situations where people want to have less people in the crew
2022-02-28 22:35:45 +02:00
function Public . crew_scale ( )
2022-03-04 19:57:58 +02:00
local ret = Common.activecrewcount ( ) / 10
if ret == 0 then ret = 1 / 10 end --if all players are afk
2022-05-09 01:36:48 +02:00
if ret > 2.1 then ret = 2.1 end --An upper cap on this is important, for two reasons:
-- large crews become disorganised
-- Higher values of this scale lower the amount of time you get on each island. But the amount of time certain island tasks take is fixed; e.g. the amount of ore is mostly invariant, and you need time to mine it.
2022-03-04 19:57:58 +02:00
return ret
2021-10-13 10:21:53 +02:00
end
function Public . silo_base_est_time ( )
2023-02-19 21:08:21 +02:00
local T = Public.expected_time_on_island ( ) * Public.crew_scale ( ) ^ ( 1 / 5 ) --to undo some of the time scaling
2021-10-13 10:21:53 +02:00
local est_secs
if T > 0 then
est_secs = T / 6
else
est_secs = 60 * 6
end
if Common.overworldx ( ) == 0 then est_secs = 60 * 2 end
return est_secs
end
function Public . time_quest_seconds ( )
2022-02-24 21:39:03 +02:00
return 2.8 * Public.silo_base_est_time ( )
2021-10-13 10:21:53 +02:00
end
function Public . silo_energy_needed_MJ ( )
local est_secs = Public.silo_base_est_time ( )
2021-10-31 22:34:18 +02:00
local est_base_power = 2 * Public.starting_boatEEIpower_production_MW ( ) * ( 1 + 0.05 * ( Common.overworldx ( ) / 40 ) ^ ( 5 / 3 ) )
2021-10-13 10:21:53 +02:00
2021-10-31 22:34:18 +02:00
return est_secs * est_base_power
2022-05-03 14:52:21 +02:00
-- return est_secs * est_base_power * Math.sloped(Common.difficulty_scale(), 1/3)
2021-10-13 10:21:53 +02:00
end
2022-02-24 21:39:03 +02:00
function Public . silo_count ( )
local E = Public.silo_energy_needed_MJ ( )
2022-05-29 17:27:04 +02:00
return Math.min ( Math.ceil ( E / ( 16.8 * 300 ) ) , 6 )
-- return Math.ceil(E/(16.8 * 300)) --no more than this many seconds to charge it. Players can in fact go even faster using beacons
2022-02-24 21:39:03 +02:00
end
2021-10-13 10:21:53 +02:00
2023-01-28 20:08:16 +02:00
-- Higher scale = slower game
2022-03-09 01:36:03 +02:00
function Public . game_slowness_scale ( )
2022-05-03 14:52:21 +02:00
-- return 1 / Public.crew_scale()^(55/100) / Math.sloped(Common.difficulty_scale(), 1/4) --changed crew_scale factor significantly to help smaller crews
2022-10-12 22:55:22 +02:00
-- return 1 / (Public.crew_scale()^(50/100) / Math.sloped(Common.difficulty_scale(), 1/4)) --changed crew_scale factor significantly to help smaller crews
2023-06-29 20:15:54 +02:00
-- local scale = 0.3 + Math.sloped(Common.difficulty_scale(), -0.15) / (Public.crew_scale()^(1/8))
local scale = 2.6 * Math.sloped ( Common.difficulty_scale ( ) , - 0.2 ) - Public.crew_scale ( ) ^ ( 1 / 4 )
2023-01-28 20:08:16 +02:00
return Math.max ( 1 , scale )
2022-03-09 01:36:03 +02:00
end
2023-01-28 20:08:16 +02:00
-- In seconds
2022-02-26 20:25:48 +02:00
function Public . max_time_on_island_formula ( ) --always >0 --tuned
2023-01-28 20:08:16 +02:00
-- return 60 * (
-- -- (32 + 2.2 * (Common.overworldx()/40)^(1/3))
-- (33 + 0.2 * (Common.overworldx()/40)^(1/3)) --based on observing x=2000, lets try killing the extra time
-- ) * Public.game_slowness_scale()
2023-06-29 20:15:54 +02:00
local minimum_mins_on_island = 30
2023-01-29 15:02:06 +02:00
return Math.ceil ( 60 * minimum_mins_on_island * Public.game_slowness_scale ( ) )
2021-10-13 10:21:53 +02:00
end
2023-01-28 20:08:16 +02:00
-- In seconds
2023-01-29 15:02:06 +02:00
function Public . max_time_on_island ( island_subtype )
2022-05-07 22:41:45 +02:00
local x = Common.overworldx ( )
2023-01-29 15:02:06 +02:00
if x == 0 then
2022-03-09 01:36:03 +02:00
-- if Common.overworldx() == 0 or ((Common.overworldx()/40) > 20 and (Common.overworldx()/40) < 25) then
2021-10-13 10:21:53 +02:00
return - 1
else
2023-01-29 15:02:06 +02:00
local time = Public.max_time_on_island_formula ( )
if x == 40 then -- it's important for this island to be somewhat chill, so that it's not such a shock to go here from the first lobby chill island
time = time * 1.2
2023-02-03 23:24:11 +02:00
-- elseif island_subtype == IslandEnum.enum.MAZE then --more time
-- time = time * 1.05
2023-01-29 15:02:06 +02:00
elseif island_subtype == IslandEnum.enum . CAVE then -- supposed to be chill island
time = time * 0.9
elseif island_subtype == IslandEnum.enum . RED_DESERT then --this island has big amount of resources so rather high risk (need time to mine resources) and high reward (lots of iron/copper/stone)
time = time * 0.9
2022-05-07 22:41:45 +02:00
end
2023-01-29 15:02:06 +02:00
return Math.ceil ( time )
2021-10-13 10:21:53 +02:00
end
end
2023-01-28 20:08:16 +02:00
Public.expected_time_fraction = 0.7
2022-03-07 14:57:07 +02:00
2022-02-26 20:25:48 +02:00
function Public . expected_time_on_island ( ) --always >0
2022-03-07 14:57:07 +02:00
return Public.expected_time_fraction * Public.max_time_on_island_formula ( )
2021-10-13 10:21:53 +02:00
end
2022-02-24 21:39:03 +02:00
function Public . fuel_depletion_rate_static ( )
if ( not Common.overworldx ( ) ) then return 0 end
2022-02-28 18:36:46 +02:00
if Common.overworldx ( ) > 0 then
2022-10-12 22:55:22 +02:00
-- With this formula coal consumption becomes 1x, 2x, 3x and 4x with 1, 3, 6, 9 crew members respectively
-- most of the crewsize dependence is through T, i.e. the coal cost per island stays the same... but the extra player dependency accounts for the fact that even in compressed time, more players seem to get more resources per island
-- rate = 570 * ((Common.overworldx()/40)^(9/10)) * Public.crew_scale()^(1/8) * Math.sloped(Common.difficulty_scale(), 65/100) / T
-- With this formula coal consumption becomes 1x, 1.24x, 1.44x and 1.57x with 1, 3, 6, 9 crew members respectively.
-- Coal consumption should scale slowly because:
-- - More people doesn't necessarily mean faster progression: people just focus on other things (and on some islands it's hard to "employ" every crew member to be productive, due to lack of activities).
-- - Although more players can setup miners faster, miners don't dig ore faster.
-- - It's not fun being punished when noobs(or just your casual friends) join game and don't contribute "enough" to make up for increased coal consumption (among other things).
2023-02-19 21:08:21 +02:00
return - 0.2 * ( ( Common.overworldx ( ) / 40 ) ^ ( 9 / 10 ) ) * Public.crew_scale ( ) ^ ( 1 / 5 ) * Math.sloped ( Common.difficulty_scale ( ) , 4 / 10 )
2022-02-28 18:36:46 +02:00
else
2022-10-12 22:55:22 +02:00
return 0
2022-02-28 18:36:46 +02:00
end
2022-02-24 21:39:03 +02:00
end
function Public . fuel_depletion_rate_sailing ( )
if ( not Common.overworldx ( ) ) then return 0 end
2022-07-30 11:29:17 +02:00
return - 7.75 * ( 1 + 0.135 * ( Common.overworldx ( ) / 40 ) ^ ( 100 / 100 ) ) * Math.sloped ( Common.difficulty_scale ( ) , 1 / 20 ) --shouldn't depend on difficulty much if at all, as available resources don't depend much on difficulty
2022-02-24 21:39:03 +02:00
end
2022-03-01 23:59:48 +02:00
function Public . silo_total_pollution ( )
return (
2023-02-19 21:08:21 +02:00
310 * Common.difficulty_scale ( ) * Public.crew_scale ( ) ^ ( 1 / 5 ) * ( 3.2 + 0.7 * ( Common.overworldx ( ) / 40 ) ^ ( 1.6 ) ) --shape of the curve with x is tuned.
2022-03-01 23:59:48 +02:00
)
end
2021-10-13 10:21:53 +02:00
function Public . boat_passive_pollution_per_minute ( time )
local T = Public.max_time_on_island_formula ( )
2022-03-09 01:36:03 +02:00
if ( Common.overworldx ( ) / 40 ) > 25 then T = T * 0.9 end
2022-07-31 11:40:10 +02:00
local boost
if time then --sharp rise approaching T, steady increase thereafter
if time > T then
boost = 20 + 10 * ( time - T ) / ( 30 / 100 * T )
2022-03-05 21:56:41 +02:00
elseif time >= 90 / 100 * T then
2023-02-21 13:27:48 +02:00
boost = 16
2022-03-01 17:57:23 +02:00
elseif time >= 85 / 100 * T then
2023-02-21 13:27:48 +02:00
boost = 12
2022-03-01 17:57:23 +02:00
elseif time >= 80 / 100 * T then
2023-02-21 13:27:48 +02:00
boost = 8
2022-03-01 17:57:23 +02:00
elseif time >= 70 / 100 * T then
2023-02-21 13:27:48 +02:00
boost = 5
2022-03-05 21:56:41 +02:00
elseif time >= 60 / 100 * T then
2023-02-21 13:27:48 +02:00
boost = 3
2022-03-05 21:56:41 +02:00
elseif time >= 50 / 100 * T then
2023-02-21 13:27:48 +02:00
boost = 2
elseif time >= 40 / 100 * T then
2022-03-06 01:42:47 +02:00
boost = 1.5
2022-07-31 11:40:10 +02:00
else
boost = 1
2022-03-01 17:57:23 +02:00
end
2022-07-31 14:08:22 +02:00
else
boost = 1
2021-10-13 10:21:53 +02:00
end
return boost * (
2023-02-21 13:27:48 +02:00
2 * Common.difficulty_scale ( ) * ( Common.overworldx ( ) / 40 ) ^ ( 1.8 ) * ( Public.crew_scale ( ) ) ^ ( 1 / 5 ) -- There is no _explicit_ T dependence, but it depends almost the same way on the crew_scale as T does.
2022-12-02 21:23:41 +02:00
)
2021-10-13 10:21:53 +02:00
end
2022-03-17 03:40:18 +02:00
function Public . base_evolution_leagues ( leagues )
2022-03-13 20:19:59 +02:00
local evo
2022-03-17 03:40:18 +02:00
local overworldx = leagues
2022-03-13 20:19:59 +02:00
2022-03-14 14:44:30 +02:00
if overworldx == 0 then
2022-03-13 20:19:59 +02:00
evo = 0
else
2023-02-19 15:05:34 +02:00
-- evo = (0.0201 * (overworldx/40)) * Math.sloped(Common.difficulty_scale(), 1/5)
-- local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(Common.difficulty_scale())
-- if difficulty_name == 'normal' then
-- evo = evo + 0.01
-- elseif difficulty_name == 'hard' then
-- evo = evo + 0.02
-- elseif difficulty_name == 'nightmare' then
-- evo = evo + 0.04
-- end
-- if overworldx > 600 and overworldx < 1000 then
-- evo = evo + (0.0025 * (overworldx - 600)/40)
-- elseif overworldx >= 1000 then
-- evo = evo + 0.0025 * 10
-- end --extra slope from 600 to 1000 adds 2.5% evo
evo = ( 0.0201 * ( overworldx / 40 ) ) * Math.sloped ( Common.difficulty_scale ( ) , 0.4 )
evo = evo + 0.02 * Common.difficulty_scale ( )
2022-03-13 03:44:32 +02:00
end
2022-03-13 20:19:59 +02:00
2021-10-13 10:21:53 +02:00
return evo
end
function Public . expected_time_evo ( )
2022-07-30 11:29:17 +02:00
return 0.125 --tuned
2021-10-13 10:21:53 +02:00
end
function Public . evolution_per_second ( )
local destination = Common.current_destination ( )
local T = Public.expected_time_on_island ( ) --always greater than 0
local rate = Public.expected_time_evo ( ) / T
if Common.overworldx ( ) == 0 then rate = 0 end
-- scale by biter nests remaining:
if destination and destination.dynamic_data then
local initial_spawner_count = destination.dynamic_data . initial_spawner_count
if initial_spawner_count and initial_spawner_count > 0 then
local surface = game.surfaces [ destination.surface_name ]
if surface and surface.valid then
rate = rate * Common.spawner_count ( surface ) / destination.dynamic_data . initial_spawner_count
end
end
end
2022-03-04 20:24:04 +02:00
-- if _DEBUG then
-- local surface = game.surfaces[destination.surface_name]
-- game.print(Common.spawner_count(surface) .. ' ' .. destination.dynamic_data.initial_spawner_count)
-- end
2022-03-04 19:57:58 +02:00
2021-10-13 10:21:53 +02:00
return rate
end
2022-03-09 01:36:03 +02:00
function Public . evolution_per_nest_kill ( ) --it's important to have evo go up with biter base kills, to provide resistance if you try to plow through all the bases
2021-10-13 10:21:53 +02:00
local destination = Common.current_destination ( )
if Common.overworldx ( ) == 0 then return 0 end
if destination and destination.dynamic_data and destination.dynamic_data . timer and destination.dynamic_data . timer > 0 and destination.dynamic_data . initial_spawner_count and destination.dynamic_data . initial_spawner_count > 0 then
local initial_spawner_count = destination.dynamic_data . initial_spawner_count
2022-07-31 16:07:53 +02:00
local base_evo_jump = 0.04 * ( 1 / initial_spawner_count ) --extra friction to make them hard to mow through, even at late times
2021-10-13 10:21:53 +02:00
local time = destination.dynamic_data . timer
2022-03-09 01:36:03 +02:00
-- local time_to_jump_to = Public.expected_time_on_island() * ((1/Public.expected_time_fraction)^(2/3))
local time_to_jump_to = Public.max_time_on_island_formula ( )
2022-07-31 16:07:53 +02:00
if time > time_to_jump_to then return base_evo_jump
2021-10-13 10:21:53 +02:00
else
-- evo it 'would have' contributed:
2022-07-31 16:07:53 +02:00
return ( 1 / initial_spawner_count ) * Public.expected_time_evo ( ) * ( time_to_jump_to - time ) / time_to_jump_to + base_evo_jump
2021-10-13 10:21:53 +02:00
end
else
return 0
end
2022-05-03 14:52:21 +02:00
-- return 0.003 * Common.difficulty_scale()
2021-10-13 10:21:53 +02:00
end
function Public . evolution_per_full_silo_charge ( )
2022-03-28 01:40:32 +02:00
--too low and you always charge immediately, too high and you always charge late
-- return 0.05
-- observed x=2000 run, changed this to:
2022-05-08 11:25:21 +02:00
-- return 0.05 + 0.03 * Common.overworldx()/1000
2022-11-13 23:17:46 +02:00
return 0.06 + 0.025 * Common.overworldx ( ) / 1000
2021-10-13 10:21:53 +02:00
end
2022-05-06 02:47:27 +02:00
-- function Public.bonus_damage_to_humans()
-- local ret = 0.025
-- local diff = Common.difficulty_scale()
-- if diff <= 0.7 then ret = 0 end
-- if diff >= 1.3 then ret = 0.050 end
-- return ret
-- end
2022-05-23 03:01:01 +02:00
function Public . biter_timeofday_bonus_damage ( darkness ) -- a surface having min_brightness of 0.2 will cap darkness at 0.8
2023-02-19 20:38:54 +02:00
return 0.5 * darkness
2021-10-13 10:21:53 +02:00
end
2023-01-29 23:01:48 +02:00
-- function Public.periodic_free_resources_per_x()
-- return {
-- }
-- -- return {
-- -- {name = 'iron-plate', count = Math.ceil(5 * (Common.overworldx()/40)^(2/3))},
-- -- {name = 'copper-plate', count = Math.ceil(1 * (Common.overworldx()/40)^(2/3))},
-- -- }
-- end
2021-10-13 10:21:53 +02:00
2023-01-29 23:01:48 +02:00
-- function Public.periodic_free_resources_per_destination_5_seconds()
-- return {
-- }
-- -- return {
-- -- {name = 'iron-ore', count = Math.ceil(7 * (Common.overworldx()/40)^(0.6))},
-- -- {name = 'copper-ore', count = Math.ceil(3 * (Common.overworldx()/40)^(0.6))},
-- -- }
-- end
2021-10-13 10:21:53 +02:00
function Public . biter_base_density_scale ( )
2022-03-04 19:57:58 +02:00
local p = Public.crew_scale ( )
if p >= 1 then
return p ^ ( 1 / 2 )
2021-10-13 10:21:53 +02:00
else
2022-03-04 19:57:58 +02:00
return Math.max ( ( p * 10 / 6 ) ^ ( 1 / 2 ) , 0.6 )
2021-10-13 10:21:53 +02:00
end
end
2022-05-07 22:41:45 +02:00
function Public . rocket_launch_fuel_reward ( )
2023-02-19 20:38:54 +02:00
return Math.ceil ( 2000 * Public.island_richness_avg_multiplier ( ) )
2022-05-03 14:52:21 +02:00
-- return Math.ceil(1000 * (1 + 0.1 * (Common.overworldx()/40)^(8/10)) / Math.sloped(Common.difficulty_scale(), 1/4))
2021-10-13 10:21:53 +02:00
end
2023-02-19 20:38:54 +02:00
function Public . rocket_launch_coin_reward ( )
return Math.ceil ( 3000 * Public.island_richness_avg_multiplier ( ) )
end
2021-10-13 10:21:53 +02:00
function Public . quest_reward_multiplier ( )
2023-02-19 21:08:21 +02:00
return 0.9 * Public.island_richness_avg_multiplier ( )
2021-10-13 10:21:53 +02:00
end
2023-02-19 18:57:38 +02:00
function Public . island_richness_avg_multiplier ( overworldx )
overworldx = overworldx or Common.overworldx ( )
-- local base = 0.73
-- local additional = 0.120 * Math.clamp(0, 10, (overworldx/40)^(65/100) * Math.sloped(Public.crew_scale(), 1/40)) --tuned tbh
local base = 0.5
local additional = 0.032 * ( overworldx / 40 )
2022-03-13 03:44:32 +02:00
2022-07-31 16:07:53 +02:00
-- now clamped, because it takes way too long to mine that many more resources
2022-03-13 03:44:32 +02:00
2022-07-31 16:07:53 +02:00
--we don't really have resources scaling by player count in this resource-constrained scenario, but we scale a little, to accommodate each player filling their inventory with useful tools. also, I would do higher than 1/40, but we go even slightly lower because we're applying this somewhat sooner than players actually get there.
2023-02-19 18:57:38 +02:00
-- return base + additional
return Math.clamp ( base , 1.5 , base + additional )
2022-03-13 03:44:32 +02:00
end
2021-10-13 10:21:53 +02:00
function Public . resource_quest_multiplier ( )
2023-02-13 22:41:00 +02:00
return ( 0.9 + 0.1 * ( Common.overworldx ( ) / 40 ) ^ ( 7 / 10 ) ) * Math.sloped ( Common.difficulty_scale ( ) , 1 / 3 ) * ( Public.crew_scale ( ) ) ^ ( 1 / 10 )
2021-10-13 10:21:53 +02:00
end
2022-07-30 11:29:17 +02:00
function Public . quest_market_entry_price_scale ( )
2022-10-12 21:02:12 +02:00
-- Whilst the scenario philosophy says that resource scales tend to be independent of crew size, we account slightly for the fact that more players tend to handcraft more
-- Idea behind formula: small scale for early islands, but scale linearly ~3-4 times every 25 islands (scaling and starting scale is more aggressive for higher difficulties)
-- Returned value examples
-- Assuming parameters:
-- crew_size = 3
-- difficulty = easy (0.5)
-- @NOTE: assuming starting island is 0th island
-- x = 40 (1st island): 0.419
-- x = 200 (5th island): 0.582
-- x = 600 (15th island): 0.992
-- x = 1000 (25th island): 1.401
2023-01-29 23:01:48 +02:00
-- return (1 + 0.05 * (Common.overworldx()/40 - 1)) * ((1 + Public.crew_scale())^(1/3)) * Math.sloped(Common.difficulty_scale(), 1/2) - 0.4
2023-02-12 00:01:53 +02:00
local scale = ( 1 + 0.05 * ( Common.overworldx ( ) / 40 - 1 ) ) * ( ( 0.6 + Public.crew_scale ( ) ) ^ ( 1 / 8 ) ) * Math.sloped ( Common.difficulty_scale ( ) , 1 / 2 ) - 0.5
return Math.max ( 0.1 , scale )
2022-05-29 13:36:27 +02:00
end
2022-07-30 11:29:17 +02:00
function Public . quest_furnace_entry_price_scale ( )
2022-10-12 21:02:12 +02:00
-- Slower increase with time, because this is more time-constrained than resource-constrained
-- Idea behind formula: small scale for early islands, but scale linearly ~2-3 times every 25 islands (scaling and starting scale is more aggressive for higher difficulties)
-- Returned value examples
-- Assuming parameters:
-- crew_size = 3
-- difficulty = easy (0.5)
-- @NOTE: assuming starting island is 0th island
-- x = 40 (1st island): 0.419
-- x = 200 (5th island): 0.517
-- x = 600 (15th island): 0.762
-- x = 1000 (25th island): 1.008
2023-01-29 23:01:48 +02:00
-- return (1 + 0.03 * (Common.overworldx()/40 - 1)) * ((1 + Public.crew_scale())^(1/3)) * Math.sloped(Common.difficulty_scale(), 1/2) - 0.4
2021-10-13 10:21:53 +02:00
2023-02-12 00:01:53 +02:00
local scale = ( 1 + 0.03 * ( Common.overworldx ( ) / 40 - 1 ) ) * ( ( 0.6 + Public.crew_scale ( ) ) ^ ( 1 / 8 ) ) * Math.sloped ( Common.difficulty_scale ( ) , 1 / 2 ) - 0.5
return Math.max ( 0.1 , scale )
2021-10-13 10:21:53 +02:00
end
2023-01-29 23:01:48 +02:00
-- function Public.apply_crew_buffs_per_league(force, leagues_travelled)
-- force.laboratory_productivity_bonus = force.laboratory_productivity_bonus + Math.max(0, 7/100 * leagues_travelled/40)
-- end
2022-06-02 13:46:05 +02:00
function Public . class_cost ( at_dock )
if at_dock then
2022-06-02 13:47:59 +02:00
return 10000
2022-06-02 13:46:05 +02:00
else
return 6000
end
2022-03-04 19:57:58 +02:00
-- return Math.ceil(10000 / (Public.crew_scale()*10/4)^(1/6))
2021-10-13 10:21:53 +02:00
end
2022-05-29 13:36:27 +02:00
Public.quest_structures_first_appear_at = 40
2021-10-13 10:21:53 +02:00
2023-02-12 00:01:53 +02:00
Public.coin_sell_amount = 300
2022-05-07 22:41:45 +02:00
2022-03-11 18:46:02 +02:00
Public.starting_fuel = 4000
2022-05-06 02:47:27 +02:00
Public.silo_max_hp = 5000
Public.silo_resistance_factor = 7
2021-10-13 10:21:53 +02:00
2023-07-01 20:51:14 +02:00
-- Pistol shooting speed = 4/s
-- Submachine gun shooting speed = 10/s
-- Pistol damage multiplier shouldn't be >= 2.5, otherwise Submachine gun isn't worth using.
2022-03-25 19:57:58 +02:00
function Public . pistol_damage_multiplier ( ) return 2.25 end --2.0 slightly too low, 2.5 causes players to yell at each other for not using pistol
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
Public.kraken_static_evo = 0.35
2021-10-13 10:21:53 +02:00
function Public . kraken_evo_increase_per_shot ( )
2022-07-30 11:29:17 +02:00
-- return 1/100 * 0.08
return 0
end
function Public . kraken_evo_increase_per_second ( )
2022-08-01 00:38:57 +02:00
return ( 1 / 100 ) / 20
2021-10-13 10:21:53 +02:00
end
2022-03-17 03:40:18 +02:00
function Public . sandworm_evo_increase_per_spawn ( )
if _DEBUG then
return 1 / 100
else
2022-08-01 00:38:57 +02:00
return ( 1 / 100 ) * ( 1 / 7 ) * Math.sloped ( Common.difficulty_scale ( ) , 3 / 5 )
2022-03-17 03:40:18 +02:00
end
end
2022-05-05 10:55:48 +02:00
function Public . kraken_kill_reward_items ( )
2023-02-19 20:38:54 +02:00
return {
{ name = ' coin ' , count = Math.ceil ( 800 * Public.island_richness_avg_multiplier ( ) ) } ,
{ name = ' utility-science-pack ' , count = Math.ceil ( 8 * Public.island_richness_avg_multiplier ( ) ) }
}
2022-05-05 10:55:48 +02:00
end
2023-02-19 20:38:54 +02:00
2022-05-05 10:55:48 +02:00
function Public . kraken_kill_reward_fuel ( )
2023-02-19 20:38:54 +02:00
return Math.ceil ( 150 * Public.island_richness_avg_multiplier ( ) )
2021-10-13 10:21:53 +02:00
end
function Public . kraken_health ( )
2023-01-29 23:01:48 +02:00
-- return Math.ceil(3500 * Math.max(1, 1 + 0.075 * (Common.overworldx()/40)^(13/10)) * (Public.crew_scale()^(4/8)) * Math.sloped(Common.difficulty_scale(), 3/4))
2022-05-05 10:55:48 +02:00
-- return Math.ceil(3500 * Math.max(1, 1 + 0.08 * ((Common.overworldx()/40)^(13/10)-6)) * (Public.crew_scale()^(5/8)) * Math.sloped(Common.difficulty_scale(), 3/4))
2023-01-29 23:01:48 +02:00
2023-02-19 21:08:21 +02:00
return Math.ceil ( 2200 * Math.max ( 1 , 1 + 0.075 * ( Common.overworldx ( ) / 40 ) ^ ( 13 / 10 ) ) * ( Public.crew_scale ( ) ^ ( 1 / 5 ) ) * Math.sloped ( Common.difficulty_scale ( ) , 3 / 4 ) )
2021-10-13 10:21:53 +02:00
end
2022-03-01 17:57:23 +02:00
Public.kraken_regen_scale = 0.1 --starting off low
2022-02-27 01:33:19 +02:00
2022-03-19 23:20:55 +02:00
function Public . krakens_per_slot ( )
2021-10-13 10:21:53 +02:00
local rng = Math.random ( )
if rng < 0.03 then
return 2
elseif rng < 0.25 then
return 1
else
return 0
end
end
function Public . krakens_per_free_slot ( overworldx )
local rng = Math.random ( )
2021-10-31 22:34:18 +02:00
local multiplier = 1
if overworldx and overworldx > 600 then
multiplier = 1 + ( overworldx - 600 ) / 600
end
2022-03-09 01:36:03 +02:00
if rng < 0.0025 * multiplier then
return 3
elseif rng < 0.075 * multiplier then
2023-06-25 14:34:56 +02:00
return 2
2021-10-31 22:34:18 +02:00
elseif rng < 0.5 * multiplier then
2021-10-13 10:21:53 +02:00
return 1
else
return 0
end
end
2023-01-29 23:01:48 +02:00
function Public . biter_boat_health ( )
2023-02-01 16:24:42 +02:00
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 ) )
2023-01-29 23:01:48 +02:00
end
2021-10-13 10:21:53 +02:00
function Public . main_shop_cost_multiplier ( )
return 1
end
function Public . barter_decay_parameter ( )
return 0.95
end
2022-03-04 20:09:28 +02:00
function Public . sandworm_speed ( )
2022-05-03 14:52:21 +02:00
return 6.4 * Math.sloped ( Common.difficulty_scale ( ) , 1 / 5 )
2022-03-04 20:09:28 +02:00
end
2021-10-13 10:21:53 +02:00
-- function Public.island_otherresources_prospect_decay_parameter()
-- return 0.95
-- end
2022-03-09 01:36:03 +02:00
Public.research_buffs = { --currently disabled anyway
2021-10-13 10:21:53 +02:00
-- these already give .1 productivity so we're adding .1 to get to 20%
2022-07-30 11:29:17 +02:00
[ ' mining-productivity-1 ' ] = { [ ' mining_drill_productivity_bonus ' ] = .1 } ,
[ ' mining-productivity-2 ' ] = { [ ' mining_drill_productivity_bonus ' ] = .1 } ,
[ ' mining-productivity-3 ' ] = { [ ' mining_drill_productivity_bonus ' ] = .1 } ,
[ ' mining-productivity-4 ' ] = { [ ' mining_drill_productivity_bonus ' ] = .1 } ,
2022-03-01 23:59:48 +02:00
-- -- these already give .1 productivity so we're adding .1 to get to 20%
-- ['mining-productivity-1'] = {['mining-drill-productivity-bonus'] = .1, ['character-inventory-slots-bonus'] = 5},
-- ['mining-productivity-2'] = {['mining-drill-productivity-bonus'] = .1, ['character-inventory-slots-bonus'] = 5},
-- ['mining-productivity-3'] = {['mining-drill-productivity-bonus'] = .1, ['character-inventory-slots-bonus'] = 5},
-- ['mining-productivity-4'] = {['mining-drill-productivity-bonus'] = .1, ['character-inventory-slots-bonus'] = 5},
2021-10-13 10:21:53 +02:00
}
2022-03-09 01:36:03 +02:00
function Public . flamers_tech_multipliers ( )
2023-02-19 15:05:34 +02:00
return 0.7
2022-03-09 01:36:03 +02:00
end
2021-10-13 10:21:53 +02:00
2022-03-10 23:09:06 +02:00
function Public . flamers_base_nerf ( )
2023-02-19 15:05:34 +02:00
return - 0.4
2022-03-10 23:09:06 +02:00
end
2021-10-13 10:21:53 +02:00
function Public . player_ammo_damage_modifiers ( ) -- modifiers are fractional. bullet affects gun turrets, but flamethrower does not affect flamer turrets
local data = {
[ ' artillery-shell ' ] = 0 ,
[ ' biological ' ] = 0 ,
[ ' bullet ' ] = 0.1 ,
[ ' cannon-shell ' ] = 0 ,
[ ' capsule ' ] = 0 ,
[ ' electric ' ] = 0 ,
[ ' flamethrower ' ] = 0 , --these nerfs are elsewhere for finer control
2022-02-28 18:36:46 +02:00
[ ' grenade ' ] = - 0.05 ,
2021-10-13 10:21:53 +02:00
[ ' landmine ' ] = 0 ,
[ ' melee ' ] = 0 , -- doesn't do anything apparently
[ ' rocket ' ] = 0 ,
[ ' shotgun-shell ' ] = 0
}
return data
end
function Public . player_turret_attack_modifiers ( )
local data = {
[ ' gun-turret ' ] = 0 ,
[ ' artillery-turret ' ] = 0 ,
[ ' laser-turret ' ] = 0 ,
}
return data
end
function Public . player_gun_speed_modifiers ( )
local data = {
[ ' artillery-shell ' ] = 0 ,
[ ' biological ' ] = 0 ,
[ ' bullet ' ] = 0 ,
[ ' cannon-shell ' ] = 0 ,
[ ' capsule ' ] = 0 ,
[ ' electric ' ] = 0 ,
[ ' flamethrower ' ] = 0 , --these nerfs are elsewhere for finer control
[ ' grenade ' ] = - 0.25 ,
[ ' landmine ' ] = 0 ,
2022-03-07 11:50:25 +02:00
[ ' melee ' ] = 0 , -- doesn't do anything apparently
2021-10-13 10:21:53 +02:00
[ ' rocket ' ] = 0 ,
2022-03-09 01:36:03 +02:00
[ ' shotgun-shell ' ] = 0
2021-10-13 10:21:53 +02:00
}
return data
end
2022-10-21 19:16:42 +02:00
Public.starting_items_player = {
[ ' pistol ' ] = 1 ,
[ ' firearm-magazine ' ] = 20 ,
[ ' raw-fish ' ] = 4 ,
[ ' medium-electric-pole ' ] = 20 ,
[ ' iron-plate ' ] = 50 ,
[ ' copper-plate ' ] = 20 ,
[ ' iron-gear-wheel ' ] = 6 ,
[ ' copper-cable ' ] = 20 ,
[ ' burner-inserter ' ] = 2 ,
[ ' gun-turret ' ] = 1
}
2021-10-13 10:21:53 +02:00
2022-10-21 19:16:42 +02:00
Public.starting_items_player_late = {
[ ' pistol ' ] = 1 ,
[ ' firearm-magazine ' ] = 10 ,
[ ' raw-fish ' ] = 4 ,
[ ' small-electric-pole ' ] = 20 ,
[ ' iron-plate ' ] = 50 ,
[ ' copper-plate ' ] = 20 ,
[ ' iron-gear-wheel ' ] = 6 ,
[ ' copper-cable ' ] = 20 ,
[ ' burner-inserter ' ] = 2 ,
[ ' gun-turret ' ] = 1
}
2021-10-13 10:21:53 +02:00
function Public . starting_items_crew_upstairs ( )
return {
{ [ ' steel-plate ' ] = 38 } ,
{ [ ' stone-brick ' ] = 60 } ,
{ [ ' grenade ' ] = 3 } ,
{ [ ' shotgun ' ] = 2 , [ ' shotgun-shell ' ] = 36 } ,
2022-03-12 00:53:36 +02:00
-- {['raw-fish'] = 5},
2022-06-02 13:57:15 +02:00
{ [ ' coin ' ] = 1000 } ,
2021-10-13 10:21:53 +02:00
}
end
function Public . starting_items_crew_downstairs ( )
return {
2022-03-01 23:59:48 +02:00
{ [ ' transport-belt ' ] = Math.random ( 600 , 650 ) } ,
2021-10-24 16:27:57 +02:00
{ [ ' underground-belt ' ] = 80 } ,
2022-03-01 23:59:48 +02:00
{ [ ' splitter ' ] = Math.random ( 50 , 56 ) } ,
{ [ ' inserter ' ] = Math.random ( 120 , 140 ) } ,
2022-05-05 10:55:48 +02:00
{ [ ' storage-tank ' ] = 2 } ,
2021-10-13 10:21:53 +02:00
{ [ ' medium-electric-pole ' ] = Math.random ( 15 , 21 ) } ,
2022-06-02 13:57:15 +02:00
{ [ ' coin ' ] = 1000 } ,
2022-03-12 13:51:11 +02:00
{ [ ' solar-panel ' ] = 3 } ,
2021-10-13 10:21:53 +02:00
}
end
2022-07-18 14:50:18 +02:00
function Public . pick_random_drilling_ore ( )
local number = Math.random ( 10 )
if number <= 4 then -- 40%
return ' iron-ore '
elseif number <= 7 then -- 30%
return ' copper-ore '
elseif number <= 9 then -- 20%
return ' coal '
else -- 10%
return ' stone '
end
end
2021-10-13 10:21:53 +02:00
2022-07-18 14:50:18 +02:00
function Public . pick_drilling_ore_amount ( )
2023-02-19 20:38:54 +02:00
return Math.ceil ( 100 * Public.island_richness_avg_multiplier ( ) * Math.random_float_in_range ( 0.9 , 1.1 ) )
2022-07-18 14:50:18 +02:00
end
2022-05-14 00:35:12 +02:00
2022-07-30 01:37:34 +02:00
-- Note: 3333 crude oil amount ~= 1% = 0.1/sec
2022-10-02 23:37:54 +02:00
function Public . pick_default_oil_amount ( )
2023-02-19 20:38:54 +02:00
return Math.ceil ( 30000 * Public.island_richness_avg_multiplier ( ) * Math.random_float_in_range ( 0.9 , 1.1 ) )
2022-07-30 01:37:34 +02:00
end
2023-02-19 20:38:54 +02:00
2023-02-08 19:41:52 +02:00
-- Returns frequency in seconds
function Public . biter_boat_average_arrival_rate ( )
return Math.ceil ( ( 7.5 * 60 ) / Math.sloped ( Common.difficulty_scale ( ) , 0.5 ) )
end
2023-02-19 22:42:07 +02:00
function Public . coin_amount_from_tree ( )
return Math.ceil ( 8 * Public.island_richness_avg_multiplier ( ) * Math.random_float_in_range ( 0.7 , 1.3 ) )
end
function Public . coin_amount_from_rock ( )
return Math.ceil ( 35 * Public.island_richness_avg_multiplier ( ) * Math.random_float_in_range ( 0.8 , 1.2 ) )
end
2021-10-13 10:21:53 +02:00
return Public