diff --git a/features/create_particles.lua b/features/create_particles.lua index 57e47d87..c2be7612 100644 --- a/features/create_particles.lua +++ b/features/create_particles.lua @@ -37,6 +37,22 @@ function CreateParticles.destroy_rock(create_entity, particle_count, position) end end +---@param create_entity function a reference to a surface.create_entity +---@param particle_count number particle count to spawn +---@param position Position +function CreateParticles.blood_explosion(create_entity, particle_count, position) + for _ = particle_count, 1, -1 do + create_entity({ + position = position, + name = 'blood-particle', + movement = {random(-5, 5) * 0.01, random(-5, 5) * 0.01}, + frame_speed = 1, + vertical_speed = random(10, 12) * 0.01, + height = random(5, 15) * 0.1, + }) + end +end + ---@param create_entity function a reference to a surface.create_entity ---@param particle_count number particle count to spawn ---@param position Position diff --git a/map_gen/Diggy/Config.lua b/map_gen/Diggy/Config.lua index 2f8abf73..8ecdac53 100644 --- a/map_gen/Diggy/Config.lua +++ b/map_gen/Diggy/Config.lua @@ -318,26 +318,25 @@ local Config = { -- chance of spawning aliens when mining alien_probability = 0.05, - -- spawns the following units when they die. To disable change it to: - --hail_hydra = nil, + -- spawns the following units when they die. To disable, remove the contents -- any non-rounded number will turn into a chance to spawn an additional alien -- example: 2.5 would spawn 2 for sure and 50% chance to spawn one additionally hail_hydra = { -- spitters - ['small-spitter'] = {['small-worm-turret'] = 0.4}, - ['medium-spitter'] = {['medium-worm-turret'] = 0.4}, - ['big-spitter'] = {['big-worm-turret'] = 0.4}, - ['behemoth-spitter'] = {['big-worm-turret'] = 0.6}, + ['small-spitter'] = {['small-worm-turret'] = 0.2}, + ['medium-spitter'] = {['medium-worm-turret'] = 0.2}, + ['big-spitter'] = {['big-worm-turret'] = 0.2}, + ['behemoth-spitter'] = {['big-worm-turret'] = 0.4}, -- biters - ['medium-biter'] = {['small-biter'] = 1.7}, - ['big-biter'] = {['medium-biter'] = 1.7}, - ['behemoth-biter'] = {['big-biter'] = 1.7}, + ['medium-biter'] = {['small-biter'] = 1.2}, + ['big-biter'] = {['medium-biter'] = 1.2}, + ['behemoth-biter'] = {['big-biter'] = 1.2}, -- worms ['small-worm-turret'] = {['small-biter'] = 2.5}, - ['medium-worm-turret'] = {['small-biter'] = 2.5, ['medium-biter'] = 0.5}, - ['big-worm-turret'] = {['small-biter'] = 3.5, ['medium-biter'] = 1, ['big-biter'] = 0.5}, + ['medium-worm-turret'] = {['small-biter'] = 2.5, ['medium-biter'] = 0.6}, + ['big-worm-turret'] = {['small-biter'] = 3.8, ['medium-biter'] = 1.3, ['big-biter'] = 1.1}, }, }, diff --git a/map_gen/Diggy/Feature/AlienSpawner.lua b/map_gen/Diggy/Feature/AlienSpawner.lua index d7401976..a2e11a1c 100644 --- a/map_gen/Diggy/Feature/AlienSpawner.lua +++ b/map_gen/Diggy/Feature/AlienSpawner.lua @@ -3,6 +3,7 @@ ]] -- dependencies +require 'utils.table' local Event = require 'utils.event' local Global = require 'utils.global' local Token = require 'utils.token' @@ -14,7 +15,7 @@ local CreateParticles = require 'features.create_particles' local random = math.random local floor = math.floor local ceil = math.ceil -local insert = table.insert +local size = table.size local raise_event = script.raise_event -- this @@ -43,7 +44,23 @@ end, function(tbl) alien_size_chart = tbl.alien_size_chart end) -local rocks_to_find = {'sand-rock-big', 'rock-huge', 'rock-big'} +local rocks_to_find = Template.diggy_rocks + +local function create_attack_command(position, target) + local command = {type = defines.command.attack_area, destination = position, radius = 10} + if target then + command = { + type = defines.command.compound, + structure_type = defines.compound_command.logical_or, + commands = { + {type = defines.command.attack, target = target}, + command, + } + } + end + + return command +end ---Triggers mining at the collision_box of the alien, to free it local do_alien_mining = Token.register(function(params) @@ -152,44 +169,55 @@ function AlienSpawner.register(config) local alien_probability = config.alien_probability local hail_hydra = config.hail_hydra - if hail_hydra then + if size(hail_hydra) > 0 then Event.add(defines.events.on_entity_died, function (event) local entity = event.entity local name = entity.name - local force - local position - local surface - local create_entity - local find_non_colliding_position + local hydras = hail_hydra[name] + if not hydras then + return + end - for alien, hydras in pairs(hail_hydra) do - if name == alien then - for hydra_spawn, amount in pairs(hydras) do - local extra_chance = amount % 1 - if extra_chance > 0 then - if random() <= extra_chance then - amount = ceil(amount) - else - amount = floor(amount) - end - end + local position = entity.position + local force = entity.force + local evolution_factor = force.evolution_factor + local cause = event.cause - while amount > 0 do - force = force or entity.force - position = position or entity.position - surface = surface or entity.surface - create_entity = create_entity or surface.create_entity - -- always spawn worms on their designated position - if not hydra_spawn:match('worm-turret') then - find_non_colliding_position = find_non_colliding_position or surface.find_non_colliding_position - position = find_non_colliding_position(hydra_spawn, position, 2, 0.4) or position - end - create_entity({name = hydra_spawn, force = force, position = position}) - amount = amount - 1 - end + local surface = entity.surface + local create_entity = surface.create_entity + local find_non_colliding_position = surface.find_non_colliding_position + + local command = create_attack_command(position, cause) + + for hydra_spawn, amount in pairs(hydras) do + amount = amount + evolution_factor + local extra_chance = amount % 1 + if extra_chance > 0 then + if random() <= extra_chance then + amount = ceil(amount) + else + amount = floor(amount) + end + end + local particle_count + + if amount > 4 then + particle_count = 60 + else + particle_count = amount * 15 + end + + CreateParticles.blood_explosion(create_entity, particle_count, position) + + for _ = amount, 1, -1 do + position = find_non_colliding_position(hydra_spawn, position, 2, 0.4) or position + local spawned = create_entity({name = hydra_spawn, force = force, position = position}) + if spawned and spawned.type == 'unit' then + spawned.set_command(command) + elseif spawned and cause then + spawned.shooting_target = cause end - break end end end) @@ -210,6 +238,10 @@ function AlienSpawner.register(config) local aliens = AlienEvolutionProgress.getBitersByEvolution(random(1, 2), evolution_factor) for name, amount in pairs(AlienEvolutionProgress.getSpittersByEvolution(random(1, 2), evolution_factor)) do + local existing = aliens[name] + if existing then + amount = amount + existing + end aliens[name] = amount end diff --git a/map_gen/Diggy/Feature/Experience.lua b/map_gen/Diggy/Feature/Experience.lua index 36475bce..3266f36f 100644 --- a/map_gen/Diggy/Feature/Experience.lua +++ b/map_gen/Diggy/Feature/Experience.lua @@ -9,7 +9,6 @@ local Gui = require 'utils.gui' local force_control = require 'features.force_control' local utils = require 'utils.core' local format = string.format -local string_format = string.format local floor = math.floor local log = math.log local insert = table.insert @@ -164,19 +163,24 @@ local rock_huge_xp ---@param event LuaEvent local function on_player_mined_entity(event) local entity = event.entity + local name = entity.name local player_index = event.player_index local force = Game.get_player_by_index(player_index).force local level = ForceControl.get_force_data(force).current_level - local exp - if entity.name == 'sand-rock-big' then + local exp = 0 + if name == 'sand-rock-big' then exp = sand_rock_xp + floor(level / 5) - elseif entity.name == 'rock-huge' then + elseif name == 'rock-big' then + exp = rock_big_xp + floor(level / 5) + elseif name == 'rock-huge' then exp = rock_huge_xp + floor(level / 5) - else + end + + if exp == 0 then return end - local text = string_format('+%d XP', exp) - Game.print_player_floating_text_position(player_index, text, gain_xp_color,0, -0.5) + + Game.print_player_floating_text_position(player_index, format('+%d XP', exp), gain_xp_color,0, -0.5) ForceControl.add_experience(force, exp) end @@ -193,7 +197,7 @@ local function on_research_finished(event) award_xp = award_xp + reward end local exp = award_xp * research.research_unit_count - local text = string_format('Research completed! +%d XP', exp) + local text = format('Research completed! +%d XP', exp) for _, p in pairs(game.connected_players) do local player_index = p.index Game.print_player_floating_text_position(player_index, text, gain_xp_color, -1, -0.5) @@ -223,10 +227,10 @@ end local function on_rocket_launched(event) local force = event.rocket.force local exp = ForceControl.add_experience_percentage(force, config.XP['rocket_launch']) - local text = string_format('Rocket launched! +%d XP', exp) + local text = format('Rocket launched! +%d XP', exp) for _, p in pairs(game.connected_players) do local player_index = p.index - Game.print_player_floating_text_position(player_index, text, gain_xp_color,-1, -0.5) + Game.print_player_floating_text_position(player_index, text, gain_xp_color, -1, -0.5) end end @@ -238,16 +242,16 @@ local function on_entity_died (event) local cause = event.cause --For bot mining and turrets - if not cause or cause.type ~= 'player' or not cause.valid then - local exp + if not cause or not cause.valid or cause.type ~= 'player' then + local exp = 0 + local floating_text_position + + -- stuff killed by the player force, but not the player if force and force.name == 'player' then local entity_name = entity.name if cause and (cause.name == 'artillery-turret' or cause.name == 'gun-turret' or cause.name == 'laser-turret' or cause.name == 'flamethrower-turret') then - exp = config.XP['enemy_killed'] * config.alien_experience_modifiers[entity_name] - local text = string_format('+ %d XP', exp) - Game.print_floating_text(cause.surface, cause.position, text, gain_xp_color) - ForceControl.add_experience(force, exp) - return + exp = config.XP['enemy_killed'] * (config.alien_experience_modifiers[entity_name] or 1) + floating_text_position = cause.position else local level = ForceControl.get_force_data(force).current_level if entity_name == 'sand-rock-big' then @@ -256,26 +260,24 @@ local function on_entity_died (event) exp = floor((rock_big_xp + level * 0.2) * 0.5) elseif entity_name == 'rock-huge' then exp = floor((rock_huge_xp + level * 0.2) * 0.5) - else - return end end end - if exp then - local text = string_format('+ %d XP', exp) - Game.print_floating_text(entity.surface, entity.position, text, gain_xp_color) + + if exp > 0 then + Game.print_floating_text(entity.surface, entity.position, format('+%d XP', exp), gain_xp_color) ForceControl.add_experience(force, exp) end + return end if entity.force.name ~= 'enemy' then return end - local exp = config.XP['enemy_killed'] * config.alien_experience_modifiers[entity.name] - local text = string_format('+ %d XP', exp) - local player_index = cause.player.index - Game.print_player_floating_text_position(player_index, text, gain_xp_color,-1, -0.5) + + local exp = config.XP['enemy_killed'] * (config.alien_experience_modifiers[entity.name] or 1) + Game.print_player_floating_text_position(cause.player.index, format('+%d XP', exp), gain_xp_color, -1, -0.5) ForceControl.add_experience(force, exp) end @@ -283,9 +285,8 @@ end ---@param event LuaEvent local function on_player_respawned(event) local player = Game.get_player_by_index(event.player_index) - local force = player.force - local exp = ForceControl.remove_experience_percentage(force, config.XP['death-penalty'], 50) - local text = string_format('%s resurrected! -%d XP', player.name, exp) + local exp = ForceControl.remove_experience_percentage(player.force, config.XP['death-penalty'], 50) + local text = format('%s resurrected! -%d XP', player.name, exp) for _, p in pairs(game.connected_players) do Game.print_player_floating_text_position(p.index, text, lose_xp_color, -1, -0.5) end @@ -409,13 +410,13 @@ local function redraw_buff(data) local buff_caption local effect_value = effects.value if name == 'mining_speed' then - buff_caption = format('+ %d mining speed', effect_value) + buff_caption = format('+%d mining speed', effect_value) elseif name == 'inventory_slot' then - buff_caption = format('+ %d inventory slot%s', effect_value, effect_value > 1 and 's' or '') + buff_caption = format('+%d inventory slot%s', effect_value, effect_value > 1 and 's' or '') elseif name == 'health_bonus' then - buff_caption = format('+ %d max health', effect_value) + buff_caption = format('+%d max health', effect_value) else - buff_caption = format('+ %d %s', effect_value, name) + buff_caption = format('+%d %s', effect_value, name) end local buffs_label = list.add({type = 'label', caption = buff_caption}) @@ -508,7 +509,7 @@ function Experience.register(cfg) --Adds a function that'll be executed at every level up ForceControlBuilder.register_on_every_level(function (level_reached, force) - force.print(string_format('%s Leveled up to %d!', '## - ', level_reached)) + force.print(format('%s Leveled up to %d!', '## - ', level_reached)) force.play_sound{path='utility/new_objective', volume_modifier = 1 } Experience.update_inventory_slots(force, level_reached) Experience.update_mining_speed(force, level_reached)