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

wave size rng bugfix

This commit is contained in:
danielmartin0 2022-05-01 11:52:43 +01:00
parent cba8f26b21
commit a39d00c24c
11 changed files with 120 additions and 106 deletions

View File

@ -111,7 +111,7 @@ require 'utils.freeplay'
--require 'maps.chronosphere.main'
--![[Adventure as a crew of pirates]]--
--require 'maps.pirates.main'
require 'maps.pirates.main'
--![[Launch rockets in increasingly harder getting worlds.]]--
--require 'maps.journey.main'

View File

@ -123,89 +123,96 @@ function Public.eat_up_fraction_of_all_pollution(surface, fraction_of_global_pol
memory.floating_pollution = pollution_available
end
function Public.try_main_attack()
function Public.wave_size_rng() -- random variance in attack sizes
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
if Math.random(10) >= 5 then
log('attack aborted by chance')
return nil
end --variance in attack sizes
if Math.random(10) == 1 then wave_size_multiplier = 1.7 end --variance in attack sizes
if Math.random(70) == 1 then wave_size_multiplier = 3.2 end --variance in attack sizes
if Math.random(500) == 1 then wave_size_multiplier = 5 end --variance in attack sizes
local rng = Math.random(1000)
if rng <= 600 then
wave_size_multiplier = 0
elseif rng <= 960 then
wave_size_multiplier = 1
elseif rng <= 990 then
wave_size_multiplier = 1.5
elseif rng <= 994 then
wave_size_multiplier = 2
elseif rng <= 998 then
wave_size_multiplier = 2.5
else
wave_size_multiplier = 3
end
end
local group = Public.spawn_group_of_scripted_biters(2/3, 6, 180, wave_size_multiplier)
local target = Public.generate_main_attack_target()
if not group or not group.valid or not target or not target.valid then return end
return wave_size_multiplier
end
-- group.set_command(Public.attack_target(target))
function Public.try_main_attack()
local wave_size_multiplier = Public.wave_size_rng()
Public.group_set_commands(group, Public.attack_target(target))
if wave_size_multiplier == 0 then
-- log('attack aborted by chance')
return nil
else
local group = Public.spawn_group_of_scripted_biters(2/3, 6, 180, wave_size_multiplier)
local target = Public.generate_main_attack_target()
if not group or not group.valid or not target or not target.valid then return end
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
end
function Public.try_secondary_attack()
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
if Math.random(10) >= 5 then
log('attack aborted by chance')
return nil
end --variance in attack sizes
if Math.random(10) == 1 then wave_size_multiplier = 1.7 end --variance in attack sizes
if Math.random(70) == 1 then wave_size_multiplier = 3.2 end --variance in attack sizes
if Math.random(500) == 1 then wave_size_multiplier = 5 end --variance in attack sizes
end
local wave_size_multiplier = Public.wave_size_rng()
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(2/3, 12, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target
if Math.random(2) == 1 then
target = Public.generate_main_attack_target()
if wave_size_multiplier == 0 then
-- log('attack aborted by chance')
return nil
else
target = Public.generate_side_attack_target(surface, group.position)
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(2/3, 12, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target
if Math.random(2) == 1 then
target = Public.generate_main_attack_target()
else
target = Public.generate_side_attack_target(surface, group.position)
end
if not group or not group.valid or not target or not target.valid then log('target invalid') return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
if not group or not group.valid or not target or not target.valid then log('target invalid') return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
function Public.try_rogue_attack()
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
if Math.random(10) >= 5 then
log('attack aborted by chance')
return nil
end --variance in attack sizes
if Math.random(10) == 1 then wave_size_multiplier = 1.7 end --variance in attack sizes
if Math.random(70) == 1 then wave_size_multiplier = 3.2 end --variance in attack sizes
if Math.random(500) == 1 then wave_size_multiplier = 5 end --variance in attack sizes
local wave_size_multiplier = Public.wave_size_rng()
if wave_size_multiplier == 0 then
-- log('attack aborted by chance')
return nil
else
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(1/2, 6, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target = Public.generate_side_attack_target(surface, group.position)
if not (target and target.valid) then return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending rogue attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(1/2, 6, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target = Public.generate_side_attack_target(surface, group.position)
if not (target and target.valid) then return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending rogue attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
@ -342,7 +349,7 @@ function Public.spawn_group_of_scripted_biters(fraction_of_floating_pollution, m
nearby_units_to_bring = {}
end
local new_units = Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawner.position, fraction_of_floating_pollution, minimum_avg_units, maximum_units, 1/wave_size_multiplier)
local new_units = Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawner.position, fraction_of_floating_pollution, minimum_avg_units, maximum_units, wave_size_multiplier)
if (new_units and nearby_units_to_bring and (#new_units + #nearby_units_to_bring) == 0) then return end
@ -360,7 +367,7 @@ function Public.spawn_group_of_scripted_biters(fraction_of_floating_pollution, m
end
function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawnposition, fraction_of_floating_pollution, minimum_avg_units, maximum_units, unit_pollutioncost_multiplier, enforce_type)
function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawnposition, fraction_of_floating_pollution, minimum_avg_units, maximum_units, wave_size_multiplier, enforce_type)
maximum_units = maximum_units or 256
-- log('ai spawning attempt params: ' .. (fraction_of_floating_pollution or '') .. ' ' .. (minimum_avg_units or '') .. ' ' .. (maximum_units or '') .. ' ' .. (unit_pollutioncost_multiplier or '') .. ' ' .. (enforce_type or ''))
@ -382,7 +389,7 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
local initialpollution = memory.floating_pollution
-- local initialbudget = budget
local base_pollution_cost_multiplier = 1
local map_pollution_cost_multiplier = 1
local destination = Common.current_destination()
if destination.dynamic_data and destination.dynamic_data.initial_spawner_count then
@ -399,40 +406,40 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
-- end
-- base_pollution_cost_multiplier = (initial_spawner_count/spawnerscount)^(1/2)
-- Now directly proportional:
base_pollution_cost_multiplier = initial_spawner_count/spawnerscount
map_pollution_cost_multiplier = initial_spawner_count/spawnerscount
if memory.overworldx == 0 then
base_pollution_cost_multiplier = Math.max(1, base_pollution_cost_multiplier)
map_pollution_cost_multiplier = Math.max(1, map_pollution_cost_multiplier)
end -- The first map not being fully loaded when you get there commonly means it records too few initial spawners, which this helps fix
else
base_pollution_cost_multiplier = 1000000
map_pollution_cost_multiplier = 1000000
end
end
end
if memory.overworldx == 0 then
-- less biters:
base_pollution_cost_multiplier = base_pollution_cost_multiplier * 2.30 --tuned to teach players to defend, but then to feel relaxing once they do
end
-- if memory.overworldx == 0 then
-- -- less biters:
-- base_pollution_cost_multiplier = base_pollution_cost_multiplier * 2.30 --tuned to teach players to defend, but then to feel relaxing once they do
-- end -- moved to scripted_biters_pollution_cost_multiplier
base_pollution_cost_multiplier = base_pollution_cost_multiplier * unit_pollutioncost_multiplier
local base_scripted_biters_pollution_cost_multiplier = Balance.scripted_biters_pollution_cost_multiplier()
base_pollution_cost_multiplier = base_pollution_cost_multiplier * Balance.scripted_biters_pollution_cost_multiplier()
map_pollution_cost_multiplier = map_pollution_cost_multiplier * base_scripted_biters_pollution_cost_multiplier
if destination.subtype and destination.subtype == IslandsCommon.enum.SWAMP then
base_pollution_cost_multiplier = base_pollution_cost_multiplier * 0.9 --biters 10% more aggressive
map_pollution_cost_multiplier = map_pollution_cost_multiplier * 0.95 --biters 5% more aggressive
end
-- if destination.subtype and destination.subtype == IslandsCommon.enum.MAZE then
-- base_pollution_cost_multiplier = base_pollution_cost_multiplier * 1.2 --biters 20% less aggressive
-- end
if budget >= minimum_avg_units * Common.averageUnitPollutionCost(evolution) * base_pollution_cost_multiplier then
if budget >= minimum_avg_units * Common.averageUnitPollutionCost(evolution) * map_pollution_cost_multiplier then
local function spawn(name2)
units_created_count = units_created_count + 1
local unittype_pollutioncost = CoreData.biterPollutionValues[name2] * base_pollution_cost_multiplier
local unit_pollutioncost = CoreData.biterPollutionValues[name2] * map_pollution_cost_multiplier / wave_size_multiplier
local p = surface.find_non_colliding_position(name2, spawnposition, 60, 1)
if not p then
@ -445,10 +452,10 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
units_created[#units_created + 1] = biter
memory.scripted_biters[biter.unit_number] = {entity = biter, created_at = game.tick}
temp_floating_pollution = temp_floating_pollution - unittype_pollutioncost
budget = budget - unittype_pollutioncost
temp_floating_pollution = temp_floating_pollution - unit_pollutioncost
budget = budget - unit_pollutioncost
-- flow statistics should reflect the number of biters generated. Therefore it should mismatch the actual pollution spent, because it should miss all the factors that can vary:
game.pollution_statistics.on_flow(name2, - CoreData.biterPollutionValues[name2] * Balance.scripted_biters_pollution_cost_multiplier())
game.pollution_statistics.on_flow(name2, - CoreData.biterPollutionValues[name2])
return biter.unit_number
end
@ -459,7 +466,7 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
local whilesafety = 1000
local next_name = enforce_type or Common.get_random_unit_type(evolution)
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[next_name] * base_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[next_name] * map_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
whilesafety = whilesafety - 1
spawn(next_name)
next_name = enforce_type or Common.get_random_unit_type(evolution)
@ -468,17 +475,19 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
local name = enforce_type or Common.get_random_unit_type(evolution)
local whilesafety = 1000
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[name] * base_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[name] * map_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
whilesafety = whilesafety - 1
spawn(name)
end
end
memory.floating_pollution = temp_floating_pollution
end
-- else
-- log('insufficient pollution for wave')
end
if units_created_count > 0 then
log('Spent ' .. Math.floor(100 * (initialpollution - temp_floating_pollution) / initialpollution) .. '% of ' .. Math.ceil(initialpollution) .. ' pollution budget on biters, at ' .. Math.ceil(base_pollution_cost_multiplier*100)/100 .. 'x price.')
log('Spent ' .. Math.floor(100 * (initialpollution - temp_floating_pollution) / initialpollution) .. '% of ' .. Math.ceil(initialpollution) .. ' pollution budget on biters, at ' .. Math.ceil(map_pollution_cost_multiplier/wave_size_multiplier*100)/100 .. 'x price.')
end
return units_created

View File

@ -28,7 +28,12 @@ Public.EEI_stages = { --multipliers
function Public.scripted_biters_pollution_cost_multiplier()
return 1.3 --tuned
-- return 1.3 --tuned
-- return 1.33
-- return 1.45 --We started getting too strong biter attacks once we staggered the waves more
-- caught a bug with the wave multiplier! going back to 1.3
return 1.3 * (1 + 1.3 / ((1 + (Common.overworldx()/40))^(1.5+Common.difficulty()))) -- the factor in brackets makes the early-game easier; in particular the first island, but on easier difficulties the next few islands as well
end
function Public.cost_to_leave_multiplier()
@ -116,7 +121,7 @@ function Public.fuel_depletion_rate_static()
local rate
if Common.overworldx() > 0 then
rate = 550 * (0 + (Common.overworldx()/40)^(9/10)) * Public.crew_scale()^(1/7) * Math.sloped(Common.difficulty(), 65/100) / T --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 = 575 * (0 + (Common.overworldx()/40)^(9/10)) * Public.crew_scale()^(1/7) * Math.sloped(Common.difficulty(), 65/100) / T --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
else
rate = 0
end
@ -127,7 +132,7 @@ end
function Public.fuel_depletion_rate_sailing()
if (not Common.overworldx()) then return 0 end
return - 7.55 * (1 + 0.135 * (Common.overworldx()/40)^(100/100)) * Math.sloped(Common.difficulty(), 1/20) --shouldn't depend on difficulty much if at all, as available resources don't depend much on difficulty
return - 7.65 * (1 + 0.135 * (Common.overworldx()/40)^(100/100)) * Math.sloped(Common.difficulty(), 1/20) --shouldn't depend on difficulty much if at all, as available resources don't depend much on difficulty
end
function Public.silo_total_pollution()
@ -287,7 +292,7 @@ end
function Public.launch_fuel_reward()
return Math.ceil(1100 * (1 + 0.13 * (Common.overworldx()/40)^(9/10)))
return Math.ceil(1250 * (1 + 0.13 * (Common.overworldx()/40)^(9/10)))
-- return Math.ceil(1000 * (1 + 0.1 * (Common.overworldx()/40)^(8/10)) / Math.sloped(Common.difficulty(), 1/4))
end
@ -315,7 +320,7 @@ function Public.apply_crew_buffs_per_x(force)
end
function Public.class_cost()
return 10000
return 9000
-- return Math.ceil(10000 / (Public.crew_scale()*10/4)^(1/6))
end
@ -519,7 +524,7 @@ Public.covered1_entry_price_data_raw = { --watch out that the raw_materials ches
{1, 0.1, 1, false, {
price = {name = 'assembling-machine-1', count = 80},
raw_materials = {{name = 'iron-plate', count = 1760}, {name = 'copper-plate', count = 360}}}, {}},
{1, 0, 0.15, false, {
{0.25, 0, 0.15, false, {
price = {name = 'burner-mining-drill', count = 150},
raw_materials = {{name = 'iron-plate', count = 1350}}}, {}},
{0.75, 0, 0.6, false, {
@ -531,7 +536,7 @@ Public.covered1_entry_price_data_raw = { --watch out that the raw_materials ches
{1, 0, 1, false, {
price = {name = 'firearm-magazine', count = 700},
raw_materials = {{name = 'iron-plate', count = 2800}}}, {}},
{1, 0, 1, false, {
{0.6, 0, 1, false, {
price = {name = 'constant-combinator', count = 276},
raw_materials = {{name = 'iron-plate', count = 552}, {name = 'copper-plate', count = 1518}}}, {}},

View File

@ -5,8 +5,8 @@ local _inspect = require 'utils.inspect'.inspect
local Public = {}
Public.scenario_id_name = 'pirates'
Public.version_string = '1.1.2.0.0'
Public.version_float = 1.1200
Public.version_string = '1.1.2.0.3'
Public.version_float = 1.1203
Public.blueprint_library_allowed = true
Public.blueprint_importing_allowed = true

View File

@ -865,7 +865,7 @@ local function base_kill_rewards(event)
if revenge_target then
Common.give(revenge_target.player, stack, revenge_target.player.position, entity.surface, entity.position)
else
if event.cause.position then
if event.cause and event.cause.valid and event.cause.position then
Common.give(nil, stack, event.cause.position, entity.surface, entity.position)
else
Common.give(nil, stack, entity.position, entity.surface)

View File

@ -38,7 +38,7 @@ Public.market_barters = {
}
Public.market_permanent_offers = {
{price = {{'pistol', 1}}, offer = {type = 'give-item', item = 'coin', count = 450}},
{price = {{'pistol', 1}}, offer = {type = 'give-item', item = 'coin', count = 400}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'iron-ore', count = 800}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'copper-ore', count = 800}},
{price = {{'coin', 3500}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 100}},

View File

@ -97,7 +97,7 @@ Public.Data.surfacename_rendering_pos = {x = -0.5, y = -15}
Public.cabin_shop_data = {
{
price = {{'electronic-circuit', 25}, {'coin', 1200}},
price = {{'electronic-circuit', 30}, {'coin', 800}},
offer = {type='give-item', item = 'rail-signal', count = 100},
},
{
@ -105,7 +105,7 @@ Public.cabin_shop_data = {
offer = {type='give-item', item = 'artillery-shell', count = 8},
},
{
price = {{'stone-brick', 100}, {'coin', 1000}},
price = {{'stone-brick', 30}, {'coin', 800}},
offer = {type='give-item', item = 'uranium-238', count = 10},
},
{

View File

@ -114,10 +114,10 @@ function Public.chunk_structures(args)
local noises = Public.noises{p = p, noise_generator = args.noise_generator, static_params = args.static_params, seed = args.seed}
return {
placeable = noises.farness(p) > 0.35,
placeable = noises.farness(p) > 0.36,
spawners_indestructible = false,
-- spawners_indestructible = noises.farness(p) > 0.7,
density_perchunk = 10 * Math.slopefromto(noises.mood(p), 0.12, -0.18) * Math.slopefromto(noises.farness(p), 0.35, 1) * args.biter_base_density_scale,
density_perchunk = 9 * Math.slopefromto(noises.mood(p), 0.12, -0.18) * Math.slopefromto(noises.farness(p), 0.36, 1) * args.biter_base_density_scale,
}
end

View File

@ -232,7 +232,7 @@ function Public.position_away_from_players_1(_, radius)
local tile = surface.get_tile(p2)
if tile and tile.valid and tile.name then
if not Utils.contains(CoreData.tiles_that_conflict_with_resource_layer, tile.name) then
if not Utils.contains(CoreData.tiles_that_conflict_with_resource_layer_extended, tile.name) then
local nearby_characters = surface.find_entities_filtered{position = p2, radius = radius, name = 'character'}
if (not nearby_characters) or (#nearby_characters == 0) then
p_ret = p2

View File

@ -200,7 +200,7 @@ function Public.destination_on_collide(destination)
-- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_bonus_evolution = 0.52}
end
end
elseif memory.overworldx == 200 or _DEBUG then
elseif memory.overworldx == 200 then
local times
if playercount <= 2 then
times = {1, 5, 10, 15, 20}

View File

@ -622,7 +622,7 @@ function Public.place_cached_structures(tickinterval)
covered_data.market.rotatable = false
covered_data.market.destructible = false
covered_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = 450}}
covered_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = 400}}
covered_data.market.add_market_item{price={{'burner-mining-drill', 1}}, offer={type = 'give-item', item = 'iron-plate', count = 9}}
local how_many_coin_offers = 4