From 5ef262006fad9c83e7bc7f27826b91189e44d27c Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:19:03 +0200 Subject: [PATCH 01/15] Warn players on join if they need a warning --- utils/datastore/warning_on_join_data.lua | 143 +++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 utils/datastore/warning_on_join_data.lua diff --git a/utils/datastore/warning_on_join_data.lua b/utils/datastore/warning_on_join_data.lua new file mode 100644 index 00000000..c353a793 --- /dev/null +++ b/utils/datastore/warning_on_join_data.lua @@ -0,0 +1,143 @@ +local Token = require 'utils.token' +local Server = require 'utils.server' +local Event = require 'utils.event' +local Gui = require 'utils.gui' + +local dataset = 'warnings' +local set_data = Server.set_data +local try_get_data = Server.try_get_data +local warning_frame_name = Gui.uid_name() +local discard_button_name = Gui.uid_name() + +local Public = {} + +local function draw_warning_frame(player, message) + local main_frame, inside_table = Gui.add_main_frame_with_toolbar(player, 'screen', warning_frame_name, nil, nil, 'Warning', true, 2) + + if not main_frame or not inside_table then + return + end + + local main_frame_style = main_frame.style + main_frame_style.width = 400 + main_frame.auto_center = true + + local content_flow = inside_table.add {type = 'flow', direction = 'horizontal'} + content_flow.style.top_padding = 16 + content_flow.style.bottom_padding = 16 + content_flow.style.left_padding = 24 + content_flow.style.right_padding = 24 + content_flow.style.horizontally_stretchable = false + + local sprite_flow = content_flow.add {type = 'flow'} + sprite_flow.style.vertical_align = 'center' + sprite_flow.style.vertically_stretchable = false + + sprite_flow.add {type = 'sprite', sprite = 'utility/warning_icon'} + + local label_flow = content_flow.add {type = 'flow'} + label_flow.style.horizontal_align = 'left' + label_flow.style.top_padding = 10 + label_flow.style.left_padding = 24 + + local warning_message = '[font=heading-2]Message from Comfy to: ' .. player.name .. '[/font]\n' .. message + + label_flow.style.horizontally_stretchable = false + local label = label_flow.add {type = 'label', caption = warning_message} + label.style.single_line = false + + local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'}) + + local left_flow = bottom_flow.add({type = 'flow'}) + left_flow.style.horizontal_align = 'left' + left_flow.style.horizontally_stretchable = true + + local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'Understood'}) + close_button.style = 'back_button' + + player.opened = main_frame +end + +local fetch = + Token.register( + function(data) + local key = data.key + if not key then + return + end + + local value = data.value + if not value then + return + end + + local player = game.get_player(key) + if not player or not player.valid then + return + end + draw_warning_frame(player, value) + end +) + +--- Tries to get data from the webpanel and applies the value to the player. +-- @param data_set player token +function Public.fetch(key) + local secs = Server.get_current_time() + if not secs then + local player = game.players[key] + if not player or not player.valid then + return + end + return + else + try_get_data(dataset, key, fetch) + end +end + +Event.add( + defines.events.on_player_joined_game, + function(event) + local player = game.get_player(event.player_index) + if not player or not player.valid then + return + end + + Public.fetch(player.name) + end +) + +Gui.on_click( + discard_button_name, + function(event) + local player = event.player + local screen = player.gui.screen + local frame = screen[warning_frame_name] + if not player or not player.valid then + return + end + + if frame and frame.valid then + frame.destroy() + set_data(dataset, player.name) + end + end +) + +Server.on_data_set_changed( + dataset, + function(data) + if not data then + return + end + + local key = data.key + local value = data.value + local player = game.get_player(key) + if not player or not player.valid then + return + end + draw_warning_frame(player, value) + end +) + +return Public From f3c9c9cbca210304e3de4459cbee079321c35077 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:19:20 +0200 Subject: [PATCH 02/15] WD - new module for enemies --- modules/wave_defense/enemy_states.lua | 859 ++++++++++++++++++++++++++ 1 file changed, 859 insertions(+) create mode 100644 modules/wave_defense/enemy_states.lua diff --git a/modules/wave_defense/enemy_states.lua b/modules/wave_defense/enemy_states.lua new file mode 100644 index 00000000..2a2a7e7e --- /dev/null +++ b/modules/wave_defense/enemy_states.lua @@ -0,0 +1,859 @@ +-- track state of units by Gerkiz +local Event = require 'utils.event' +local Global = require 'utils.global' +local Task = require 'utils.task' +local Token = require 'utils.token' +local Public = require 'modules.wave_defense.table' +local Difficulty = require 'modules.difficulty_vote_by_amount' + +local de = defines.events +local ev = Public.events +local random = math.random +local abs = math.abs +local floor = math.floor +local set_timeout_in_ticks = Task.set_timeout_in_ticks + +local this = { + states = {}, + state_count = 0, + settings = { + frenzy_length = 3600, + frenzy_burst_length = 160, + update_rate = 60 + }, + target_settings = {} +} + +Public._esp = {} + +Global.register( + this, + function(tbl) + this = tbl + for _, state in pairs(this.states) do + setmetatable(state, {__index = Public._esp}) + end + end +) + +local projectiles = { + 'slowdown-capsule', + 'defender-capsule', + 'slowdown-capsule', + 'destroyer-capsule', + 'distractor-capsule', + 'slowdown-capsule', + 'rocket', + 'slowdown-capsule', + 'explosive-rocket', + 'grenade', + 'rocket', + 'grenade' +} + +local tiers = { + ['small-biter'] = 'medium-biter', + ['medium-biter'] = 'big-biter', + ['big-biter'] = 'behemoth-biter', + ['behemoth-biter'] = 'behemoth-biter', + ['small-spitter'] = 'medium-spitter', + ['medium-spitter'] = 'big-spitter', + ['big-spitter'] = 'behemoth-spitter', + ['behemoth-spitter'] = 'behemoth-spitter' +} + +local tier_damage = { + ['small-biter'] = {min = 25, max = 50}, + ['medium-biter'] = {min = 50, max = 100}, + ['big-biter'] = {min = 75, max = 150}, + ['behemoth-biter'] = {min = 100, max = 200}, + ['small-spitter'] = {min = 25, max = 50}, + ['medium-spitter'] = {min = 50, max = 100}, + ['big-spitter'] = {min = 75, max = 150}, + ['behemoth-spitter'] = {min = 100, max = 200} +} + +--- A token to register tasks that entities are given +local work_token +work_token = + Token.register( + function(event) + if not event then + return + end + + local state = Public.get_unit(event.unit_number) + local tick = game.tick + if not state then + return + end + + if state:validate() then + state:work(tick) + + set_timeout_in_ticks(this.settings.update_rate, work_token, event) + else + state:remove() + end + end +) + +--- Restores a given entity to their original force +local restore_force_token = + Token.register( + function(event) + if not event then + return + end + local force_name = event.force_name + if not force_name then + return + end + + local state = Public.get_unit(event.unit_number) + if state then + state:set_force() + state.frenzied = false + end + end +) + +local function aoe_punch(entity, target, damage) + if not (target and target.valid) then + return + end + + local base_vector = {target.position.x - entity.position.x, target.position.y - entity.position.y} + + local vector = {base_vector[1], base_vector[2]} + vector[1] = vector[1] * 1000 + vector[2] = vector[2] * 1000 + + entity.surface.create_entity({name = 'blood-explosion-huge', position = target.position}) + + if abs(vector[1]) > abs(vector[2]) then + local d = abs(vector[1]) + if abs(vector[1]) > 0 then + vector[1] = vector[1] / d + end + if abs(vector[2]) > 0 then + vector[2] = vector[2] / d + end + else + local d = abs(vector[2]) + if abs(vector[2]) > 0 then + vector[2] = vector[2] / d + end + if abs(vector[1]) > 0 and d > 0 then + vector[1] = vector[1] / d + end + end + + vector[1] = vector[1] * 1.5 + vector[2] = vector[2] * 1.5 + + local a = 0.20 + + local cs = entity.surface + local cp = entity.position + + local valid_enemy_forces = Public.get('valid_enemy_forces') + + for i = 1, 16, 1 do + for x = i * -1 * a, i * a, 1 do + for y = i * -1 * a, i * a, 1 do + local p = {cp.x + x + vector[1] * i, cp.y + y + vector[2] * i} + cs.create_trivial_smoke({name = 'train-smoke', position = p}) + for _, e in pairs(cs.find_entities({{p[1] - a, p[2] - a}, {p[1] + a, p[2] + a}})) do + if e.valid then + if e.health then + if e.destructible and e.minable and not valid_enemy_forces[e.force.name] then + if e.force.index ~= entity.force.index then + if e.valid then + e.health = e.health - damage * 0.05 + if e.health <= 0 then + e.die(e.force.name, entity) + end + end + end + end + end + end + end + end + end + end +end + +local function do_projectile(surface, name, _position, _force, target, max_range) + surface.create_entity( + { + name = name, + position = _position, + force = _force, + source = _position, + target = target or nil, + max_range = max_range or nil, + speed = 0.4, + fast_replace = true, + create_build_effect_smoke = false + } + ) + return true +end + +local function area_of_effect(entity, radius, callback, find_entities) + if not radius then + return + end + + local function get_area(pos, dist) + local area = { + left_top = { + x = pos.x - dist, + y = pos.y - dist + }, + right_bottom = { + x = pos.x + dist, + y = pos.y + dist + } + } + return area + end + + local cs = entity.surface + local cp = entity.position + + if radius and radius > 256 then + radius = 256 + end + + local area = get_area(cp, radius) + + for x = area.left_top.x, area.right_bottom.x, 1 do + for y = area.left_top.y, area.right_bottom.y, 1 do + local d = floor((cp.x - x) ^ 2 + (cp.y - y) ^ 2) + if d < radius then + local p = {x = x, y = y} + if find_entities then + for _, e in pairs(cs.find_entities({{p.x - 1, p.y - 1}, {p.x + 1, p.y + 1}})) do + if e and e.valid and e.name ~= 'character' and e.health and e.destructible then + callback(e, p) + end + end + else + callback(p) + end + cs.create_trivial_smoke({name = 'fire-smoke', position = p}) + end + end + end +end + +local function set_commands() + local unit = this.target_settings.main_target + if not unit or not unit.valid then + return + end + + local commands = {} + + if this.target_settings.last_set_target == 'main' then + this.target_settings.last_set_target = 'random' + commands[#commands + 1] = { + type = defines.command.attack_area, + destination = {x = unit.position.x, y = unit.position.y}, + radius = 12, + distraction = defines.distraction.by_enemy + } + commands[#commands + 1] = { + type = defines.command.build_base, + destination = {x = unit.position.x, y = unit.position.y} + } + else + this.target_settings.last_set_target = 'main' + commands[#commands + 1] = { + type = defines.command.attack, + target = unit, + distraction = defines.distraction.by_anything + } + end + + local command = { + type = defines.command.compound, + structure_type = defines.compound_command.return_last, + commands = commands + } + + local surface = unit.surface + + surface.set_multi_command({command = command, unit_count = 5000, force = 'aggressors'}) + this.target_settings.commands = command +end + +local function on_init() + this.states = {} + this.state_count = 0 + this.settings = { + frenzy_length = 3600, + frenzy_burst_length = 160, + update_rate = 60 + } + this.target_settings = {} + + local aggressors = game.forces.aggressors + local aggressors_frenzy = game.forces.aggressors_frenzy + local enemy = game.forces.enemy + + if not aggressors then + aggressors = game.create_force('aggressors') + end + if not aggressors_frenzy then + aggressors_frenzy = game.create_force('aggressors_frenzy') + end + + aggressors.set_gun_speed_modifier('biological', 1) + aggressors.set_gun_speed_modifier('melee', 0.2) + aggressors.set_friend('aggressors_frenzy', true) + aggressors.set_friend('enemy', true) + + aggressors_frenzy.set_gun_speed_modifier('biological', 10) + aggressors_frenzy.set_gun_speed_modifier('melee', 5) + aggressors_frenzy.set_friend('aggressors', true) + aggressors_frenzy.set_friend('enemy', true) + + enemy.set_friend('aggressors', true) + enemy.set_friend('aggressors_frenzy', true) +end + +local function on_wave_created(event) + local wave_number = event.wave_number + if not wave_number then + return + end + + this.settings.wave_number = wave_number + + if wave_number % 50 == 0 then + local state = Public.get_any() + if state then + local old = state:get_melee_speed() + state:set_attack_speed(old + 0.05) + end + elseif wave_number % 100 == 0 then + Public.enemy_weapon_damage('aggressors') + Public.enemy_weapon_damage('aggressors_frenzy') + end +end + +local function on_unit_group_created(event) + local unit_group = event.unit_group + if not unit_group or not unit_group.valid then + return + end + + for _, entity in pairs(unit_group.members) do + if not Public.get_unit(entity.unit_number) then + local data = { + entity = entity + } + local state = Public.new(data) + state:set_burst_frenzy() + end + end +end + +local function on_target_aquired(event) + local target = event.target + if not target or not target.valid then + return + end + + if this.target_settings.main_target and this.target_settings.main_target.valid then + if this.target_settings.main_target.unit_number ~= target.unit_number then + this.target_settings.main_target = event.target + end + else + this.target_settings.main_target = event.target + end + + local tick = game.tick + + if not this.target_settings.last_set_commands then + set_commands() + this.target_settings.last_set_commands = tick + 200 + this.target_settings.last_set_target = 'main' + end + + if tick > this.target_settings.last_set_commands then + set_commands() + end +end + +local function on_entity_created(event) + local entity = event.entity + if not entity or not entity.valid then + return + end + + local state = Public.get_unit(entity.unit_number) + + if not state then + local data = { + entity = entity + } + state = Public.new(data) + state:set_burst_frenzy() + if event.boss_unit then + state:set_boss() + end + else + if event.boss_unit then + state:set_boss() + end + end +end + +local function on_evolution_factor_changed(event) + local evolution_factor = event.evolution_factor + if not evolution_factor then + return + end + + local forces = game.forces + + forces.aggressors.evolution_factor = evolution_factor + forces.aggressors_frenzy.evolution_factor = evolution_factor +end + +local function on_entity_died(event) + local entity = event.entity + if not entity.valid then + return + end + + local state = Public.get_unit(entity.unit_number) + if state then + state:remove() + end +end + +local function on_entity_damaged(event) + local entity = event.entity + if not (entity and entity.valid) then + return + end + local state = Public.get_unit(entity.unit_number) + if not state then + return + end + + local max = entity.prototype.max_health + + if state.boss_unit then + state:spawn_children() + end + + if entity.health <= max / 2 and state.teleported < 5 then + if random(1, 4) == 1 then + state:switch_position() + end + end +end + +--- Creates a new state for a boss unit. +---@param data table +---@return table +function Public.new(data) + local state = setmetatable({}, {__index = Public._esp}) + local tick = game.tick + state.entity = data.entity + state.surface_id = state.entity.surface_index + state.force = game.forces.aggressors + state.unit_number = state.entity.unit_number + state.teleported = 0 + state.id = state.entity.unit_number + if data.delayed then + state.delayed = tick + data.delayed + state.ttl = data.ttl or (tick + data.delayed) + 7200 -- 2 minutes duration + else + state.ttl = data.ttl or tick + 3600 -- 1 minutes duration + state:validate() + end + + set_timeout_in_ticks(this.settings.update_rate, work_token, {unit_number = state.unit_number}) + + this.states[state.id] = state + this.state_count = this.state_count + 1 + + return state +end + +-- Adjusts the damage +function Public.enemy_weapon_damage(force) + if not force then + return + end + + local e = game.forces[force] + + local data = { + ['artillery-shell'] = 0.05, + ['biological'] = 0.06, + ['beam'] = 0.08, + ['bullet'] = 0.08, + ['capsule'] = 0.08, + ['electric'] = 0.08, + ['flamethrower'] = 0.08, + ['laser'] = 0.08, + ['landmine'] = 0.08, + ['melee'] = 0.08 + } + + for k, v in pairs(data) do + local new = Difficulty.get().value * v + + local e_old = e.get_ammo_damage_modifier(k) + + e.set_ammo_damage_modifier(k, new + e_old) + end +end + +-- Gets a given unit +--- @param unit_number number +---@return table|nil +function Public.get_unit(unit_number) + return this.states[unit_number] +end + +-- Gets a boss unit +---@return table|nil +function Public.get_boss_unit() + for _, state in pairs(this.states) do + if state and state.boss_unit then + return state + end + end +end + +-- Gets a first matched unit +---@return table|nil +function Public.get_any() + for _, state in pairs(this.states) do + if state then + return state + end + end +end + +-- Removes the given entity from tracking +function Public._esp:remove() + this.states[self.id] = nil + this.state_count = this.state_count - 1 +end + +-- Sets the entity force +function Public._esp:set_force() + local entity = self.entity + if not entity or not entity.valid then + return + end + + entity.force = game.forces.aggressors + self.force = entity.force +end + +-- Grants the unit a frenzy attack speed +function Public._esp:set_frenzy() + local entity = self.entity + if not entity or not entity.valid then + return + end + + if self.frenzied then + return + end + + self.frenzied = true + + entity.force = game.forces.aggressors_frenzy + self.force = entity.force +end + +-- Grants the unit a frenzy attack speed for a short time +function Public._esp:set_burst_frenzy() + local entity = self.entity + if not entity or not entity.valid then + return + end + + if self.frenzied then + return + end + + self.frenzied = true + set_timeout_in_ticks(this.settings.frenzy_burst_length, restore_force_token, {force_name = self.force.name, unit_number = self.unit_number}) + + entity.force = game.forces.aggressors_frenzy + self.force = entity.force +end + +-- Spawns biters that are one tier higher than the entity +function Public._esp:spawn_children() + local entity = self.entity + if not entity or not entity.valid then + return + end + + local tier = tiers[entity.name] + + if not tier then + return + end + + local max = entity.prototype.max_health + + if entity.health <= max / 2 and not self.spawned_children then + self.spawned_children = true + Public.buried_biter(entity.surface, entity.position, 1, tier) + end +end + +-- Sets unit_group for the given unit if any +function Public._esp:unit_group(unit_group) + local entity = self.entity + if not entity or not entity.valid then + return + end + + if not unit_group then + return + end + + self.unit_group = unit_group +end + +--- Creates a fire entity. +function Public._esp:fire_damage() + local entity = self.entity + if not entity or not entity.valid then + return + end + + local position = {entity.position.x + (-5 + random(0, 10)), entity.position.y + (-5 + random(0, 10))} + + entity.surface.create_entity({name = 'fire-flame', position = position}) + if random(1, 5) == 1 then + entity.surface.create_entity( + { + name = 'medium-scorchmark', + position = position, + force = 'aggressors' + } + ) + end +end + +--- Creates a projectile. +function Public._esp:fire_projectile() + local entity = self.entity + if not entity or not entity.valid then + return + end + + local position = {entity.position.x + (-10 + random(0, 20)), entity.position.y + (-10 + random(0, 20))} + + entity.surface.create_entity( + { + name = projectiles[random(1, #projectiles)], + position = entity.position, + force = entity.force.name, + source = entity.position, + target = position, + max_range = 16, + speed = 0.01 + } + ) +end + +--- Creates a aoe attack. +function Public._esp:aoe_attack() + local entity = self.entity + if not entity or not entity.valid then + return + end + + local position = {x = entity.position.x + (-10 + random(0, 20)), y = entity.position.y + (-10 + random(0, 20))} + + local target = { + valid = true, + position = position + } + + local damage = tier_damage[entity.name] + if not damage then + return + end + + aoe_punch(entity, target, random(damage.min, damage.max)) +end + +--- Creates aoe attack. +function Public._esp:area_of_spit_attack(range) + local entity = self.entity + if not entity or not entity.valid then + return + end + + area_of_effect( + entity, + range or 10, + function(p) + do_projectile(entity.surface, 'acid-stream-spitter-big', p, entity.force, p) + end, + false + ) +end + +--- Attack target +function Public._esp:attack_target() + local entity = self.entity + if not entity or not entity.valid then + return + end + local tick = game.tick + local orders = self.moving_to_attack_target + if not orders then + self.moving_to_attack_target = tick + 300 + orders = self.moving_to_attack_target + end + + -- if entity.distraction_command and entity.distraction_command.target.name then + -- log(serpent.block(entity.distraction_command.target.name)) + -- end + + if tick > orders then + self.moving_to_attack_target = tick + 300 + entity.set_command(this.target_settings.commands) + end +end + +-- Sets the attack speed for the given force +function Public._esp:set_attack_speed(speed) + if not speed then + speed = 1 + end + + self.force.set_gun_speed_modifier('melee', speed) + self.force.set_gun_speed_modifier('biological', speed * 2) +end + +-- Gets the melee speed for the given force +---@return number +function Public._esp:get_melee_speed() + return self.force.get_gun_speed_modifier('melee') +end + +--- Sets a new position near the LuaEntity. +---@return table|nil +function Public._esp:switch_position() + local entity = self.entity + if not entity or not entity.valid then + return + end + + local position = {entity.position.x + (-5 + random(0, 15)), entity.position.y + (-5 + random(0, 15))} + + local rand = entity.surface.find_non_colliding_position(entity.name, position, 0.2, 0.5) + if rand then + self.entity.teleport(rand) + end + + return position +end + +--- Validates if a state is valid. +---@return boolean|integer +function Public._esp:validate() + if not self.id then + self:remove() + return false + end + if self.entity and self.entity.valid then + return true + else + self:remove() + return false + end +end + +--- Sets a unit as a boss unit +function Public._esp:set_boss() + local entity = self.entity + if not entity or not entity.valid then + return + end + + self.boss_unit = true + + if this.settings.wave_number > 499 then + if this.settings.wave_number % 100 == 0 then + self.go_havoc = true + end + end +end + +function Public._esp:work(tick) + if self.go_frenzy then + self:set_frenzy() + end + + if self.go_havoc then + self:fire_projectile() + self:area_of_spit_attack() + self:aoe_attack() + if not self.clear_go_havoc then + self.clear_go_havoc = game.tick + 3600 + end + end + + if self.boss_unit then + if random(1, 20) == 1 then + self:fire_damage() + elseif random(1, 30) == 1 then + self:set_burst_frenzy() + elseif random(1, 50) == 1 then + self:fire_projectile() + elseif random(1, 100) == 1 then + self:attack_target() + elseif random(1, 200) == 1 then + if this.settings.wave_number >= 1000 then + self:area_of_spit_attack() + end + elseif random(1, 300) == 1 then + if this.settings.wave_number >= 1000 then + self:aoe_attack() + end + end + elseif tick < self.ttl then + if random(1, 20) == 1 then + self:fire_damage() + elseif random(1, 50) == 1 then + self:set_burst_frenzy() + elseif random(1, 100) == 1 then + self:attack_target() + end + else + self:remove() + end +end + +Event.on_init(on_init) +Event.add(de.on_entity_died, on_entity_died) +Event.add(de.on_entity_damaged, on_entity_damaged) +Event.add(ev.on_wave_created, on_wave_created) +Event.add(ev.on_unit_group_created, on_unit_group_created) +Event.add(ev.on_entity_created, on_entity_created) +Event.add(ev.on_target_aquired, on_target_aquired) +Event.add(ev.on_evolution_factor_changed, on_evolution_factor_changed) +Event.add(ev.on_game_reset, on_init) From 50564073c31f0bcc9f065bb168cfefcc0ae734bd Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:20:24 +0200 Subject: [PATCH 03/15] Add new module to control --- control.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/control.lua b/control.lua index 7a7fcbd9..cd8b4a96 100644 --- a/control.lua +++ b/control.lua @@ -15,6 +15,7 @@ require 'utils.datastore.color_data' require 'utils.datastore.session_data' require 'utils.datastore.jail_data' require 'utils.datastore.quickbar_data' +require 'utils.datastore.warning_on_join_data' require 'utils.datastore.message_on_join_data' require 'utils.datastore.player_tag_data' require 'utils.datastore.supporters' From 3cd6bde2b222b31e4b66630bce99139be498bdab Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:21:33 +0200 Subject: [PATCH 04/15] RPG - fix weird settings not auto centering --- modules/rpg/settings.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/rpg/settings.lua b/modules/rpg/settings.lua index dd6d1b23..46f8ca9a 100644 --- a/modules/rpg/settings.lua +++ b/modules/rpg/settings.lua @@ -710,6 +710,7 @@ function Public.extra_settings(player) Gui.set_data(save_button, data) player.opened = main_frame + main_frame.auto_center = true end function Public.settings_tooltip(player) From aabd656ebb44a97d2734cbdd293e410b7ec9c782 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:21:57 +0200 Subject: [PATCH 05/15] RPG - fix aoe punch not triggering --- modules/rpg/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rpg/main.lua b/modules/rpg/main.lua index 81fb7916..9262ff39 100644 --- a/modules/rpg/main.lua +++ b/modules/rpg/main.lua @@ -519,7 +519,7 @@ local function on_entity_damaged(event) ) end - local get_health_pool = Public.has_health_boost(entity, damage, final_damage_amount, cause) + local get_health_pool = Public.has_health_boost(entity, damage, final_damage_amount, cause, true) --Cause a one punch. if enable_aoe_punch then From fa5553060afbc05251ef8a06ac096e3ab1d1dcc8 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:22:14 +0200 Subject: [PATCH 06/15] Event - remove unused args --- utils/event.lua | 10 +++++----- utils/event_core.lua | 32 +++++++------------------------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/utils/event.lua b/utils/event.lua index 8debdde8..ab46a37a 100644 --- a/utils/event.lua +++ b/utils/event.lua @@ -112,6 +112,7 @@ local raise_event = script.raise_event local script_on_event = script.on_event local script_on_nth_tick = script.on_nth_tick local generate_event_name = script.generate_event_name +local get_event_filter = script.get_event_filter local function_table = function_table local function_nth_tick_table = function_nth_tick_table @@ -162,13 +163,12 @@ end -- See documentation at top of file for details on using events. -- @param event_name -- @param handler --- @optional param filters -function Event.add(event_name, handler, filters) +function Event.add(event_name, handler) if _LIFECYCLE == 8 then error('Calling Event.add after on_init() or on_load() has run is a desync risk.', 2) end - core_add(event_name, handler, filters) + core_add(event_name, handler) end --- Register a handler for the script.on_init event. @@ -528,7 +528,7 @@ function Event.generate_event_name(name) end function Event.add_event_filter(event, filter) - local current_filters = script.get_event_filter(event) + local current_filters = get_event_filter(event) if not current_filters then current_filters = {filter} @@ -550,7 +550,7 @@ local function add_handlers() for event_name, tokens in pairs(token_handlers) do for i = 1, #tokens do local handler = Token.get(tokens[i]) - core_add(event_name, handler) + core_add(event_name, handler.data, handler.filter) end end diff --git a/utils/event_core.lua b/utils/event_core.lua index 50655fe3..19b1d3c7 100644 --- a/utils/event_core.lua +++ b/utils/event_core.lua @@ -12,15 +12,6 @@ local event_handlers = {} -- map of nth_tick to handlers[] local on_nth_tick_event_handlers = {} ---[[ local interface = { - get_handler = function() - return event_handlers - end -} - -if not remote.interfaces['interface'] then - remote.add_interface('interface', interface) -end ]] local xpcall = xpcall local trace = debug.traceback local log = log @@ -33,13 +24,11 @@ local function handler_error(err) end local function call_handlers(handlers, event) - if _DEBUG then - for i = 1, #handlers do + for i = 1, #handlers do + if _DEBUG then local handler = handlers[i] handler(event) - end - else - for i = 1, #handlers do + else xpcall(handlers[i], handler_error, event) end end @@ -91,23 +80,16 @@ local function on_nth_tick_event(event) end --- Do not use this function, use Event.add instead as it has safety checks. -function Public.add(event_name, handler, filters) +function Public.add(event_name, handler) local handlers = event_handlers[event_name] + if not handlers then event_handlers[event_name] = {handler} - if filters then - script_on_event(event_name, on_event, filters) - else - script_on_event(event_name, on_event) - end + script_on_event(event_name, on_event) else table.insert(handlers, handler) if #handlers == 1 then - if filters then - script_on_event(event_name, on_event, filters) - else - script_on_event(event_name, on_event) - end + script_on_event(event_name, on_event) end end end From ae54312f2fd30ac7f27fba2a7b1a6d2e5aeaff9a Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:22:51 +0200 Subject: [PATCH 07/15] WD - add support for new module and move out commands --- modules/wave_defense/buried_enemies.lua | 10 +- modules/wave_defense/commands.lua | 29 +++-- modules/wave_defense/core.lua | 3 + modules/wave_defense/main.lua | 134 ++++++++++++++---------- modules/wave_defense/table.lua | 13 +++ modules/wave_defense/threat_events.lua | 40 +++++-- 6 files changed, 159 insertions(+), 70 deletions(-) diff --git a/modules/wave_defense/buried_enemies.lua b/modules/wave_defense/buried_enemies.lua index 118a4469..a85d2cf4 100644 --- a/modules/wave_defense/buried_enemies.lua +++ b/modules/wave_defense/buried_enemies.lua @@ -59,6 +59,7 @@ end local function spawn_biters(data) local surface = data.surface local position = data.position + local entity_name = data.entity_name local h = floor(abs(position.y)) if not position then @@ -77,6 +78,10 @@ local function spawn_biters(data) unit_to_create = Public.wave_defense_roll_biter_name() end + if entity_name then + unit_to_create = entity_name + end + local modified_unit_health = Public.get('modified_unit_health') local modified_boss_unit_health = Public.get('modified_boss_unit_health') @@ -119,7 +124,7 @@ local function spawn_worms(data) end end -function Public.buried_biter(surface, position, max) +function Public.buried_biter(surface, position, max, entity_name) if not surface then return end @@ -137,6 +142,7 @@ function Public.buried_biter(surface, position, max) end local amount = 8 + local a = 0 max = max or random(4, 6) @@ -157,7 +163,7 @@ function Public.buried_biter(surface, position, max) a = a + 1 this[game.tick + t][#this[game.tick + t] + 1] = { callback = 'spawn_biters', - data = {surface = surface, position = {x = position.x, y = position.y}} + data = {surface = surface, position = {x = position.x, y = position.y}, entity_name = entity_name} } if a >= max then break diff --git a/modules/wave_defense/commands.lua b/modules/wave_defense/commands.lua index 2dd9cba4..10e9c685 100644 --- a/modules/wave_defense/commands.lua +++ b/modules/wave_defense/commands.lua @@ -18,26 +18,41 @@ commands.add_command( return end - if param == 'spawn_wave' then - return Public.spawn_unit_group(true, true) + if param == 'skip' then + Public.get('enable_grace_time').enabled = false + return end - if param == 'set_next_wave' then - for _ = 1, 100 do + if param == 'spawn_wave' then + Public.spawn_unit_group(true, true) + return + end + + if param == 'next_wave' then + Public.set_next_wave() + Public.spawn_unit_group(true, true) + return + end + + if param == 'set_next_50' then + for _ = 1, 50 do Public.set_next_wave() end - return Public.spawn_unit_group(true, true) + Public.spawn_unit_group(true, true) + return end if param == 'set_wave_1500' then for _ = 1, 1500 do Public.set_next_wave() end - return Public.spawn_unit_group(true, true) + Public.spawn_unit_group(true, true) + return end if param == 'log_all' then - return Public.toggle_debug() + Public.toggle_debug() + return end if param == 'debug_health' then diff --git a/modules/wave_defense/core.lua b/modules/wave_defense/core.lua index 830ac66b..43de8ebf 100644 --- a/modules/wave_defense/core.lua +++ b/modules/wave_defense/core.lua @@ -1,5 +1,8 @@ local Public = require 'modules.wave_defense.table' +local Enemy_states = require 'modules.wave_defense.enemy_states' +Public.enemy_states = Enemy_states + local Biter_Rolls = require 'modules.wave_defense.biter_rolls' Public.biter_rolls = Biter_Rolls diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua index 02d8080a..5a78dbd1 100644 --- a/modules/wave_defense/main.lua +++ b/modules/wave_defense/main.lua @@ -9,6 +9,7 @@ local random = math.random local floor = math.floor local sqrt = math.sqrt local round = math.round +local raise = Event.raise local function debug_print(msg) local debug = Public.get('debug') @@ -228,10 +229,6 @@ local function is_unit_valid(biter) debug_print('is_unit_valid - unit destroyed - invalid') return false end - if not biter.entity.unit_group then - debug_print('is_unit_valid - unit destroyed - no unitgroup') - return false - end if biter.spawn_tick + max_biter_age < game.tick then debug_print('is_unit_valid - unit destroyed - timed out') return false @@ -264,6 +261,7 @@ local function time_out_biters() local generated_units = Public.get('generated_units') local active_biter_count = Public.get('active_biter_count') local active_biter_threat = Public.get('active_biter_threat') + local valid_enemy_forces = Public.get('valid_enemy_forces') if active_biter_count >= 100 and #generated_units.active_biters <= 10 then Public.set('active_biter_count', 50) @@ -274,15 +272,14 @@ local function time_out_biters() for k, biter in pairs(generated_units.active_biters) do if not is_unit_valid(biter) then Public.set('active_biter_count', active_biter_count - 1) - if biter.entity then - if biter.entity.valid then - Public.set('active_biter_threat', active_biter_threat - round(Public.threat_values[biter.entity.name] * biter_health_boost, 2)) - if biter.entity.force.index == 2 then - biter.entity.destroy() - end - debug_print('time_out_biters: ' .. k .. ' got deleted.') + local entity = biter.entity + if entity and entity.valid then + Public.set('active_biter_threat', active_biter_threat - round(Public.threat_values[entity.name] * biter_health_boost, 2)) + if valid_enemy_forces[entity.force.name] then + entity.destroy() end end + debug_print('time_out_biters: ' .. k .. ' got deleted.') generated_units.active_biters[k] = nil end end @@ -343,6 +340,7 @@ local function set_main_target() local target = Public.get('target') if target then if target.valid then + raise(Public.events.on_target_aquired, {target = target}) return end end @@ -358,10 +356,12 @@ local function set_main_target() sec_target = get_random_character() end if not sec_target then + raise(Public.events.on_target_aquired, {target = target}) return end Public.set('target', sec_target) + raise(Public.events.on_target_aquired, {target = target}) debug_print('set_main_target -- New main target ' .. sec_target.name .. ' at position x' .. sec_target.position.x .. ' y' .. sec_target.position.y .. ' selected.') end @@ -408,6 +408,7 @@ local function set_enemy_evolution() end enemy.evolution_factor = evolution_factor + raise(Public.events.on_evolution_factor_changed, {evolution_factor = evolution_factor}) end local function can_units_spawn() @@ -519,14 +520,18 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_se BiterHealthBooster.add_unit(biter, final_health) end - if is_boss_biter and (wave_number >= boost_bosses_when_wave_is_above) then - local increase_boss_health_per_wave = Public.get('increase_boss_health_per_wave') - if increase_boss_health_per_wave then - local modified_boss_unit_health = Public.get('modified_boss_unit_health') - BiterHealthBooster.add_boss_unit(biter, modified_boss_unit_health.current_value, 0.55) + if is_boss_biter then + if (wave_number >= boost_bosses_when_wave_is_above) then + local increase_boss_health_per_wave = Public.get('increase_boss_health_per_wave') + if increase_boss_health_per_wave then + local modified_boss_unit_health = Public.get('modified_boss_unit_health') + BiterHealthBooster.add_boss_unit(biter, modified_boss_unit_health.current_value, 0.55) + else + local sum = boosted_health * 5 + BiterHealthBooster.add_boss_unit(biter, sum, 0.55) + end else local sum = boosted_health * 5 - debug_print('Boss Health Boosted: ' .. sum) BiterHealthBooster.add_boss_unit(biter, sum, 0.55) end end @@ -567,9 +572,6 @@ local function increase_biters_health() return end - -- local boosted_health = BiterHealthBooster.get('biter_health_boost') - -- local wave_number = Public.get('wave_number') - -- this sets normal units health local modified_unit_health = Public.get('modified_unit_health') if modified_unit_health.current_value > modified_unit_health.limit_value then @@ -578,18 +580,6 @@ local function increase_biters_health() debug_print_health('modified_unit_health.current_value: ' .. modified_unit_health.current_value) Public.set('modified_unit_health').current_value = modified_unit_health.current_value + modified_unit_health.health_increase_per_boss_wave - -- this sets boss units health - -- if boosted_health == 1 then - -- boosted_health = 1.25 - -- end - - -- boosted_health = round(boosted_health * (wave_number * 0.04), 3) - -- debug_print_health('boosted_health: ' .. boosted_health) - -- if boosted_health >= 300 then - -- boosted_health = 300 - -- end - -- Public.set('modified_boss_unit_health', boosted_health) - -- this sets boss units health local modified_boss_unit_health = Public.get('modified_boss_unit_health') if modified_boss_unit_health.current_value > modified_boss_unit_health.limit_value then @@ -648,6 +638,8 @@ local function set_next_wave() Public.set('wave_number', wave_number + 1) wave_number = Public.get('wave_number') + local event_data = {} + local threat_gain_multiplier = Public.get('threat_gain_multiplier') local threat_gain = wave_number * threat_gain_multiplier @@ -661,10 +653,13 @@ local function set_next_wave() increase_max_active_unit_groups() end - if wave_number % 25 == 0 then + event_data.wave_number = wave_number + + if wave_number % 50 == 0 then increase_biter_damage() increase_biters_health() Public.set('boss_wave', true) + event_data.boss_wave = true Public.set('boss_wave_warning', true) local alert_boss_wave = Public.get('alert_boss_wave') local spawn_position = get_spawn_pos() @@ -695,10 +690,15 @@ local function set_next_wave() local wave_enforced = Public.get('wave_enforced') local next_wave = Public.get('next_wave') local wave_interval = Public.get('wave_interval') + event_data.next_wave = next_wave + event_data.wave_interval = wave_interval + event_data.threat_gain = threat_gain if not wave_enforced then Public.set('last_wave', next_wave) Public.set('next_wave', game.tick + wave_interval) end + + raise(Public.events.on_wave_created, event_data) end local function reform_group(group) @@ -746,6 +746,9 @@ local function get_side_targets(group) local step_length = unit_group_command_step_length local side_target = Public.get_side_target() + if not side_target then + return + end local target_position = side_target.position local distance_to_target = floor(sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2)) local steps = floor(distance_to_target / step_length) + 1 @@ -929,6 +932,9 @@ local function command_to_side_target(group) end local commands = get_side_targets(group) + if not commands then + return + end group.set_command( { @@ -1042,14 +1048,26 @@ local function spawn_unit_group(fs, only_bosses) debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y) + local event_data = {} + local generated_units = Public.get('generated_units') local unit_group = surface.create_unit_group({position = spawn_position, force = 'enemy'}) + + event_data.unit_group = unit_group + generated_units.unit_group_pos.index = generated_units.unit_group_pos.index + 1 generated_units.unit_group_pos.positions[unit_group.group_number] = {position = unit_group.position, index = 0} local average_unit_group_size = Public.get('average_unit_group_size') local unit_settings = Public.get('unit_settings') + event_data.unit_settings = unit_settings + local group_size = floor(average_unit_group_size * Public.group_size_modifier_raffle[random(1, Public.group_size_modifier_raffle_size)]) - if not only_bosses then + + event_data.group_size = group_size + event_data.boss_wave = false + + local boss_wave = Public.get('boss_wave') + if not boss_wave and not only_bosses then for _ = 1, group_size, 1 do local biter = spawn_biter(surface, spawn_position, fs, false, unit_settings) if not biter then @@ -1058,26 +1076,30 @@ local function spawn_unit_group(fs, only_bosses) end unit_group.add_member(biter) + raise(Public.events.on_entity_created, {entity = biter, boss_unit = false, target = target}) -- command_to_side_target(unit_group) end end - local boss_wave = Public.get('boss_wave') if boss_wave or only_bosses then + event_data.boss_wave = true local count = random(1, floor(wave_number * 0.01) + 2) if count > 16 then count = 16 end - if count <= 1 then + if count <= 4 then count = 4 end + event_data.spawn_count = count for _ = 1, count, 1 do local biter = spawn_biter(surface, spawn_position, fs, true, unit_settings) + game.print(serpent.block(biter and biter.unit_number)) if not biter then - debug_print('spawn_unit_group - No biters were found?') + debug_print('spawn_unit_group - No biter was found?') break end unit_group.add_member(biter) + raise(Public.events.on_entity_created, {entity = biter, boss_unit = true, target = target}) end Public.set('boss_wave', false) end @@ -1089,10 +1111,16 @@ local function spawn_unit_group(fs, only_bosses) Public.set('random_group', unit_group) end Public.set('spot', 'nil') + raise(Public.events.on_unit_group_created, event_data) return true end local function check_group_positions() + local resolve_pathing = Public.get('resolve_pathing') + if not resolve_pathing then + return + end + local generated_units = Public.get('generated_units') local target = Public.get('target') if not valid(target) then @@ -1126,6 +1154,11 @@ local function check_group_positions() end local function log_threat() + local enable_threat_log = Public.get('enable_threat_log') + if not enable_threat_log then + return + end + local threat_log_index = Public.get('threat_log_index') Public.set('threat_log_index', threat_log_index + 1) local threat_log = Public.get('threat_log') @@ -1140,9 +1173,14 @@ end local tick_tasks = { [30] = set_main_target, [60] = set_enemy_evolution, + [90] = check_group_positions, [120] = give_main_command_to_group, - [150] = Public.build_nest, - [180] = Public.build_worm, + [150] = log_threat, + [180] = Public.build_nest, + [210] = Public.build_worm +} + +local tick_tasks_t2 = { [1200] = give_side_commands_to_group, [3600] = time_out_biters, [7200] = refresh_active_unit_threat @@ -1187,23 +1225,11 @@ Event.on_nth_tick( if tick_tasks[t] then tick_tasks[t]() end - if tick_tasks[t2] then - tick_tasks[t2]() + + if tick_tasks_t2[t2] then + tick_tasks_t2[t2]() end - local resolve_pathing = Public.get('resolve_pathing') - if resolve_pathing then - if tick % 60 == 0 then - check_group_positions() - end - end - - local enable_threat_log = Public.get('enable_threat_log') - if enable_threat_log then - if tick % 60 == 0 then - log_threat() - end - end local players = game.connected_players for _, player in pairs(players) do Public.update_gui(player) diff --git a/modules/wave_defense/table.lua b/modules/wave_defense/table.lua index eea6deb7..14a1f287 100644 --- a/modules/wave_defense/table.lua +++ b/modules/wave_defense/table.lua @@ -3,6 +3,14 @@ local Event = require 'utils.event' local this = {} local Public = {} +Public.events = { + on_wave_created = Event.generate_event_name('on_wave_created'), + on_unit_group_created = Event.generate_event_name('on_unit_group_created'), + on_evolution_factor_changed = Event.generate_event_name('on_evolution_factor_changed'), + on_game_reset = Event.generate_event_name('on_game_reset'), + on_target_aquired = Event.generate_event_name('on_target_aquired'), + on_entity_created = Event.generate_event_name('on_entity_created') +} local insert = table.insert Global.register( @@ -153,6 +161,11 @@ function Public.reset_wave_defense() ['behemoth-worm-turret'] = 0.3 } } + this.valid_enemy_forces = { + ['enemy'] = true, + ['aggressors'] = true, + ['aggressors_frenzy'] = true + } end --- This gets values from our table diff --git a/modules/wave_defense/threat_events.lua b/modules/wave_defense/threat_events.lua index 9ff6a5c0..bf3a81a3 100644 --- a/modules/wave_defense/threat_events.lua +++ b/modules/wave_defense/threat_events.lua @@ -20,6 +20,9 @@ local immunity_spawner = local function is_boss(entity) local unit_number = entity.unit_number local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units') + if not biter_health_boost_units then + return + end local unit = biter_health_boost_units[unit_number] if unit and unit[3] and unit[3].healthbar_id then return true @@ -36,6 +39,10 @@ local function remove_unit(entity) end local m = 1 local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units') + if not biter_health_boost_units then + return + end + if biter_health_boost_units[unit_number] then m = 1 / biter_health_boost_units[unit_number][2] end @@ -144,7 +151,8 @@ function Public.build_worm() if threat < 512 then return end - local worm_building_chance = Public.get('worm_building_chance') + local worm_building_chance = Public.get('worm_building_chance') --[[@as integer]] + if math_random(1, worm_building_chance) ~= 1 then return end @@ -296,10 +304,28 @@ local function on_entity_died(event) end local disable_threat_below_zero = Public.get('disable_threat_below_zero') - local biter_health_boost = BiterHealthBooster.get('biter_health_boost') + local valid_enemy_forces = Public.get('valid_enemy_forces') + if not valid_enemy_forces then + return + end + + local modified_unit_health = Public.get('modified_unit_health') + if not modified_unit_health then + return + end + local modified_boss_unit_health = Public.get('modified_boss_unit_health') + if not modified_boss_unit_health then + return + end + + local boss = is_boss(entity) + + local boost_value = modified_unit_health.current_value + if boss then + boost_value = modified_boss_unit_health.current_value / 2 + end if entity.type == 'unit' then - --acid_nova(entity) if not Public.threat_values[entity.name] then return end @@ -310,19 +336,19 @@ local function on_entity_died(event) remove_unit(entity) return end - Public.set('threat', math.round(threat - Public.threat_values[entity.name] * biter_health_boost, 2)) + Public.set('threat', math.round(threat - Public.threat_values[entity.name] * boost_value, 2)) remove_unit(entity) else local threat = Public.get('threat') - Public.set('threat', math.round(threat - Public.threat_values[entity.name] * biter_health_boost, 2)) + Public.set('threat', math.round(threat - Public.threat_values[entity.name] * boost_value, 2)) remove_unit(entity) end else - if entity.force.index == 2 then + if valid_enemy_forces[entity.force.name] then if entity.health then if Public.threat_values[entity.name] then local threat = Public.get('threat') - Public.set('threat', math.round(threat - Public.threat_values[entity.name] * biter_health_boost, 2)) + Public.set('threat', math.round(threat - Public.threat_values[entity.name] * boost_value, 2)) end spawn_unit_spawner_inhabitants(entity) end From b5d989a977c789370299afca29b9ea1339cd33f0 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:23:27 +0200 Subject: [PATCH 08/15] Mtn v3 - fix coin bug on boosted worms --- maps/mountain_fortress_v3/biters_yield_coins.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/maps/mountain_fortress_v3/biters_yield_coins.lua b/maps/mountain_fortress_v3/biters_yield_coins.lua index d0ab457e..8a5ac83f 100644 --- a/maps/mountain_fortress_v3/biters_yield_coins.lua +++ b/maps/mountain_fortress_v3/biters_yield_coins.lua @@ -9,17 +9,17 @@ local random = math.random local coin_yield = { ['behemoth-biter'] = 5, ['behemoth-spitter'] = 5, - ['behemoth-worm-turret'] = 20, + ['behemoth-worm-turret'] = 10, ['big-biter'] = 3, ['big-spitter'] = 3, ['big-worm-turret'] = 16, ['biter-spawner'] = 32, ['medium-biter'] = 2, ['medium-spitter'] = 2, - ['medium-worm-turret'] = 12, + ['medium-worm-turret'] = 4, ['small-biter'] = 1, ['small-spitter'] = 1, - ['small-worm-turret'] = 8, + ['small-worm-turret'] = 2, ['spitter-spawner'] = 32 } @@ -67,7 +67,7 @@ local function on_entity_died(event) if not entity.valid then return end - if entity.force.index ~= 2 then + if not Public.valid_enemy_forces[entity.force.name] then return end From ce7abbe0e74742b87b9cb4abd70b72c0148a21c8 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:23:45 +0200 Subject: [PATCH 09/15] Mtn v3 - fix randomized pause wave --- maps/mountain_fortress_v3/functions.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/maps/mountain_fortress_v3/functions.lua b/maps/mountain_fortress_v3/functions.lua index 18c7db03..bee90abe 100644 --- a/maps/mountain_fortress_v3/functions.lua +++ b/maps/mountain_fortress_v3/functions.lua @@ -853,6 +853,18 @@ local boost_movement_speed_on_respawn = end ) +local function on_wave_created(event) + if not event or not event.wave_number then + return + end + + local wave_number = event.wave_number + + if wave_number % 50 == 0 then + WD.set_pause_wave_in_ticks(random(18000, 54000)) + end +end + function Public.set_difficulty() local game_lost = Public.get('game_lost') if game_lost then @@ -1698,5 +1710,6 @@ Event.add(defines.events.on_research_finished, on_research_finished) Event.add(defines.events.on_player_changed_position, on_player_changed_position) Event.add(defines.events.on_player_respawned, on_player_respawned) Event.on_nth_tick(10, tick) +Event.add(WD.events.on_wave_created, on_wave_created) return Public From cf6a6141dc7d3dde5d47632b9261abd3008b5ec4 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Fri, 26 May 2023 16:24:22 +0200 Subject: [PATCH 10/15] Other various fixes and changes --- maps/mountain_fortress_v3/entities.lua | 13 +- maps/mountain_fortress_v3/get_perlin.lua | 132 +++++++++--------- maps/mountain_fortress_v3/icw/functions.lua | 2 +- maps/mountain_fortress_v3/locomotive.lua | 2 +- .../locomotive/spawn_locomotive.lua | 30 ++-- maps/mountain_fortress_v3/main.lua | 4 +- .../resource_generator.lua | 14 +- maps/mountain_fortress_v3/table.lua | 8 ++ maps/mountain_fortress_v3/terrain.lua | 127 +++++++++-------- modules/biter_health_booster_v2.lua | 3 + modules/rpg/functions.lua | 32 +++-- 11 files changed, 203 insertions(+), 164 deletions(-) diff --git a/maps/mountain_fortress_v3/entities.lua b/maps/mountain_fortress_v3/entities.lua index dda86e40..1d573d12 100644 --- a/maps/mountain_fortress_v3/entities.lua +++ b/maps/mountain_fortress_v3/entities.lua @@ -289,7 +289,7 @@ local function protect_entities(data) local check_heavy_damage = Public.get('check_heavy_damage') if check_heavy_damage then - if entity.type == 'simple-entity' and dmg >= 500 then + if (entity.type == 'simple-entity' or entity.type == 'simple-entity-with-owner') and dmg >= 500 then entity.health = entity.health + dmg end end @@ -313,7 +313,7 @@ local function protect_entities(data) local carriages_numbers = Public.get('carriages_numbers') if is_protected(entity) then if (cause and cause.valid) then - if cause.force.index == 2 then + if Public.valid_enemy_forces[cause.force.name] then if carriages_numbers and carriages_numbers[entity.unit_number] then set_train_final_health(dmg, false) return @@ -323,7 +323,7 @@ local function protect_entities(data) end end elseif not (cause and cause.valid) then - if force and force.index == 2 then + if force and Public.valid_enemy_forces[force.name] then if carriages_numbers and carriages_numbers[entity.unit_number] then set_train_final_health(dmg, false) return @@ -743,7 +743,9 @@ local function on_player_mined_entity(event) give_coin(player) end else - give_coin(player) + if random(1, 6) == 1 then + give_coin(player) + end end if rpg_char.stone_path then entity.surface.set_tiles({{name = 'stone-path', position = entity.position}}, true) @@ -970,13 +972,14 @@ local function on_entity_died(event) on_entity_removed(d) local player + local valid_enemy_forces = Public.valid_enemy_forces if cause then if cause.valid then if (cause and cause.name == 'character' and cause.player) then player = cause.player end - if cause.force.index == 2 or cause.force.index == 3 then + if valid_enemy_forces[cause.force.name] or cause.force.index == 3 then entity.destroy() return end diff --git a/maps/mountain_fortress_v3/get_perlin.lua b/maps/mountain_fortress_v3/get_perlin.lua index 1bf0eb60..b3e2d963 100644 --- a/maps/mountain_fortress_v3/get_perlin.lua +++ b/maps/mountain_fortress_v3/get_perlin.lua @@ -4,102 +4,102 @@ local simplex_noise = require 'utils.simplex_noise'.d2 --add or use noise templates from here local noises = { ['bb_biterland'] = { - {modifier = 0.001, weight = 1}, - {modifier = 0.01, weight = 0.35}, - {modifier = 0.1, weight = 0.015} + {modifier = 0.0015, weight = 1.1}, + {modifier = 0.009, weight = 0.34}, + {modifier = 0.095, weight = 0.016} }, - ['bb_ore'] = {{modifier = 0.0042, weight = 1}, {modifier = 0.031, weight = 0.08}, {modifier = 0.1, weight = 0.025}}, - ['cave_ponds'] = {{modifier = 0.01, weight = 0.75}, {modifier = 0.15, weight = 0.08}}, - ['smol_areas'] = {{modifier = 0.005, weight = 0.85}, {modifier = 0.15, weight = 0.025}, {modifier = 0.15, weight = 0.035}}, - ['cave_worms'] = {{modifier = 0.001, weight = 1}, {modifier = 0.1, weight = 0.06}}, + ['bb_ore'] = {{modifier = 0.0046, weight = 0.95}, {modifier = 0.03, weight = 0.077}, {modifier = 0.09, weight = 0.023}}, + ['cave_ponds'] = {{modifier = 0.011, weight = 0.74}, {modifier = 0.14, weight = 0.079}}, + ['smol_areas'] = {{modifier = 0.0042, weight = 0.81}, {modifier = 0.129, weight = 0.021}, {modifier = 0.119, weight = 0.03}}, + ['cave_worms'] = {{modifier = 0.0011, weight = 0.99}, {modifier = 0.09, weight = 0.059}}, ['cave_rivers'] = { - {modifier = 0.007, weight = 0.75}, - {modifier = 0.0090, weight = 0.30}, - {modifier = 0.075, weight = 0.03} + {modifier = 0.0077, weight = 0.74}, + {modifier = 0.0089, weight = 0.29}, + {modifier = 0.072, weight = 0.028} }, ['cave_rivers_2'] = { - {modifier = 0.003, weight = 1}, - {modifier = 0.01, weight = 0.21}, - {modifier = 0.05, weight = 0.01} + {modifier = 0.0033, weight = 0.99}, + {modifier = 0.0099, weight = 0.2}, + {modifier = 0.049, weight = 0.009} }, ['cave_rivers_3'] = { - {modifier = 0.002, weight = 1}, - {modifier = 0.01, weight = 0.15}, - {modifier = 0.05, weight = 0.01} + {modifier = 0.0022, weight = 0.99}, + {modifier = 0.0099, weight = 0.14}, + {modifier = 0.049, weight = 0.009} }, ['cave_rivers_4'] = { - {modifier = 0.001, weight = 1}, - {modifier = 0.01, weight = 0.11}, - {modifier = 0.05, weight = 0.01} + {modifier = 0.0009, weight = 0.99}, + {modifier = 0.0099, weight = 0.1}, + {modifier = 0.049, weight = 0.009} }, - ['decoratives'] = {{modifier = 0.03, weight = 1}, {modifier = 0.05, weight = 0.25}, {modifier = 0.1, weight = 0.05}}, - ['dungeons'] = {{modifier = 0.003, weight = 1}, {modifier = 0.006, weight = 0.25}}, + ['decoratives'] = {{modifier = 0.031, weight = 1.05}, {modifier = 0.055, weight = 0.24}, {modifier = 0.11, weight = 0.055}}, + ['dungeons'] = {{modifier = 0.0033, weight = 1.05}, {modifier = 0.0066, weight = 0.24}}, ['dungeon_sewer'] = { - {modifier = 0.0005, weight = 1}, - {modifier = 0.005, weight = 0.015}, - {modifier = 0.025, weight = 0.0015} + {modifier = 0.00055, weight = 1.05}, + {modifier = 0.0055, weight = 0.014}, + {modifier = 0.0275, weight = 0.00135} }, ['large_caves'] = { - {modifier = 0.0033, weight = 1}, - {modifier = 0.01, weight = 0.22}, - {modifier = 0.05, weight = 0.05}, - {modifier = 0.1, weight = 0.04} + {modifier = 0.00363, weight = 1.05}, + {modifier = 0.01, weight = 0.23}, + {modifier = 0.055, weight = 0.045}, + {modifier = 0.11, weight = 0.042} }, - ['n1'] = {{modifier = 0.0001, weight = 1}}, - ['n2'] = {{modifier = 0.001, weight = 1}}, - ['n3'] = {{modifier = 0.01, weight = 1}}, - ['n4'] = {{modifier = 0.1, weight = 1}}, - ['n5'] = {{modifier = 0.07, weight = 1}}, + ['n1'] = {{modifier = 0.00011, weight = 1.1}}, + ['n2'] = {{modifier = 0.0011, weight = 1.1}}, + ['n3'] = {{modifier = 0.011, weight = 1.1}}, + ['n4'] = {{modifier = 0.11, weight = 1.1}}, + ['n5'] = {{modifier = 0.077, weight = 1.1}}, ['watery_world'] = { - {modifier = 0.0007, weight = 1}, - {modifier = 0.01, weight = 0.02}, - {modifier = 0.1, weight = 0.005} + {modifier = 0.00077, weight = 1.1}, + {modifier = 0.011, weight = 0.022}, + {modifier = 0.11, weight = 0.0055} }, ['no_rocks'] = { - {modifier = 0.0045, weight = 0.95}, - {modifier = 0.017, weight = 0.25}, - {modifier = 0.045, weight = 0.045}, - {modifier = 0.088, weight = 0.035} + {modifier = 0.00495, weight = 0.945}, + {modifier = 0.01665, weight = 0.2475}, + {modifier = 0.0435, weight = 0.0435}, + {modifier = 0.07968, weight = 0.0315} }, - ['no_rocks_2'] = {{modifier = 0.016, weight = 1.15}, {modifier = 0.13, weight = 0.095}}, + ['no_rocks_2'] = {{modifier = 0.0184, weight = 1.265}, {modifier = 0.143, weight = 0.1045}}, ['oasis'] = { - {modifier = 0.0015, weight = 1}, - {modifier = 0.0025, weight = 0.5}, - {modifier = 0.01, weight = 0.15}, - {modifier = 0.1, weight = 0.017} + {modifier = 0.00165, weight = 1.1}, + {modifier = 0.00275, weight = 0.55}, + {modifier = 0.011, weight = 0.165}, + {modifier = 0.11, weight = 0.0187} }, ['scrapyard'] = { - {modifier = 0.005, weight = 1}, - {modifier = 0.01, weight = 0.35}, - {modifier = 0.05, weight = 0.23}, - {modifier = 0.1, weight = 0.11} + {modifier = 0.0055, weight = 1.1}, + {modifier = 0.011, weight = 0.385}, + {modifier = 0.055, weight = 0.253}, + {modifier = 0.11, weight = 0.121} }, ['scrapyard_modified'] = { - {modifier = 0.006, weight = 1}, - {modifier = 0.04, weight = 0.15}, - {modifier = 0.22, weight = 0.05}, - {modifier = 0.05, weight = 0.32} + {modifier = 0.0066, weight = 1.1}, + {modifier = 0.044, weight = 0.165}, + {modifier = 0.242, weight = 0.055}, + {modifier = 0.055, weight = 0.352} }, ['big_cave'] = { - {modifier = 0.003, weight = 1}, - {modifier = 0.02, weight = 0.05}, - {modifier = 0.15, weight = 0.02} + {modifier = 0.0033, weight = 1.1}, + {modifier = 0.022, weight = 0.055}, + {modifier = 0.165, weight = 0.022} }, ['small_caves'] = { - {modifier = 0.006, weight = 1}, - {modifier = 0.04, weight = 0.15}, - {modifier = 0.22, weight = 0.05} + {modifier = 0.0066, weight = 1.1}, + {modifier = 0.044, weight = 0.165}, + {modifier = 0.242, weight = 0.055} }, ['small_caves_2'] = { - {modifier = 0.009, weight = 1}, - {modifier = 0.05, weight = 0.25}, - {modifier = 0.25, weight = 0.05} + {modifier = 0.0099, weight = 1.1}, + {modifier = 0.055, weight = 0.275}, + {modifier = 0.275, weight = 0.055} }, ['forest_location'] = { - {modifier = 0.006, weight = 1}, - {modifier = 0.01, weight = 0.25}, - {modifier = 0.05, weight = 0.15}, - {modifier = 0.1, weight = 0.05} + {modifier = 0.0066, weight = 1.1}, + {modifier = 0.011, weight = 0.275}, + {modifier = 0.055, weight = 0.165}, + {modifier = 0.11, weight = 0.0825} }, ['forest_density'] = { {modifier = 0.01, weight = 1}, diff --git a/maps/mountain_fortress_v3/icw/functions.lua b/maps/mountain_fortress_v3/icw/functions.lua index eabf8730..2c732234 100644 --- a/maps/mountain_fortress_v3/icw/functions.lua +++ b/maps/mountain_fortress_v3/icw/functions.lua @@ -35,7 +35,7 @@ local reconstruct_all_trains = local function get_tile_name() -- local main_tile_name = 'tutorial-grid' - local main_tile_name = 'black-refined-concrete' + local main_tile_name = 'stone-path' return main_tile_name end diff --git a/maps/mountain_fortress_v3/locomotive.lua b/maps/mountain_fortress_v3/locomotive.lua index 85574855..5b6c0ea4 100644 --- a/maps/mountain_fortress_v3/locomotive.lua +++ b/maps/mountain_fortress_v3/locomotive.lua @@ -49,7 +49,7 @@ local function add_random_loot_to_main_market(rarity) end end - for k, v in pairs(items) do + for _, v in pairs(items) do local price = v.price[1][2] + random(1, 15) * rarity local value = v.price[1][1] local stack = 1 diff --git a/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua b/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua index 8779c80c..89c76004 100644 --- a/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua +++ b/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua @@ -8,35 +8,47 @@ local random = math.random local function initial_cargo_boxes() return { - {name = 'loader', count = 2}, + {name = 'loader', count = 1}, + {name = 'stone-furnace', count = 2}, {name = 'coal', count = random(32, 64)}, {name = 'coal', count = random(32, 64)}, + {name = 'loader', count = 1}, {name = 'iron-ore', count = random(32, 128)}, {name = 'copper-ore', count = random(32, 128)}, - {name = 'empty-barrel', count = random(16, 32)}, - {name = 'submachine-gun', count = 1}, + {name = 'submachine-gun', count = 1}, + {name = 'loader', count = 1}, {name = 'submachine-gun', count = 1}, {name = 'submachine-gun', count = 1}, + {name = 'stone-furnace', count = 2}, {name = 'submachine-gun', count = 1}, {name = 'submachine-gun', count = 1}, + {name = 'loader', count = 1}, {name = 'submachine-gun', count = 1}, + {name = 'automation-science-pack', count = random(4, 32)}, {name = 'submachine-gun', count = 1}, + {name = 'stone-wall', count = random(4, 32)}, {name = 'shotgun', count = 1}, {name = 'shotgun', count = 1}, {name = 'shotgun', count = 1}, + {name = 'stone-wall', count = random(4, 32)}, {name = 'gun-turret', count = 1}, {name = 'gun-turret', count = 1}, {name = 'gun-turret', count = 1}, + {name = 'gun-turret', count = 1}, + {name = 'stone-wall', count = random(4, 32)}, {name = 'shotgun-shell', count = random(4, 5)}, {name = 'shotgun-shell', count = random(4, 5)}, {name = 'shotgun-shell', count = random(4, 5)}, + {name = 'gun-turret', count = 1}, {name = 'land-mine', count = random(6, 18)}, {name = 'grenade', count = random(2, 7)}, {name = 'grenade', count = random(2, 8)}, + {name = 'gun-turret', count = 1}, {name = 'grenade', count = random(2, 7)}, {name = 'light-armor', count = random(2, 4)}, {name = 'iron-gear-wheel', count = random(7, 15)}, {name = 'iron-gear-wheel', count = random(7, 15)}, + {name = 'gun-turret', count = 1}, {name = 'iron-gear-wheel', count = random(7, 15)}, {name = 'iron-gear-wheel', count = random(7, 15)}, {name = 'iron-plate', count = random(15, 23)}, @@ -72,7 +84,7 @@ local set_loco_tiles = ---@diagnostic disable-next-line: count-down-loop for x = position.x - 5, 1, 3 do for y = 1, position.y + 5, 2 do - if random(1, 4) == 1 then + if random(1, 3) == 1 then p[#p + 1] = {x = x, y = y} end end @@ -94,10 +106,10 @@ local set_loco_tiles = if not p[i] then break end - local name = 'wooden-chest' + local name = 'crash-site-chest-1' if random(1, 3) == 1 then - name = 'iron-chest' + name = 'crash-site-chest-2' end if surface.can_place_entity({name = name, position = p[i]}) then local e = surface.create_entity({name = name, position = p[i], force = 'player', create_build_effect_smoke = false}) @@ -125,7 +137,7 @@ function Public.locomotive_spawn(surface, position) rendering.draw_light( { sprite = 'utility/light_medium', - scale = 5.5, + scale = 6.5, intensity = 1, minimum_darkness = 0, oriented = true, @@ -168,7 +180,7 @@ function Public.locomotive_spawn(surface, position) local scale = random(50, 100) * 0.01 rendering.draw_sprite( { - sprite = 'item/raw-fish', + sprite = 'entity/small-biter', orientation = random(0, 100) * 0.01, x_scale = scale, y_scale = scale, @@ -181,7 +193,7 @@ function Public.locomotive_spawn(surface, position) ) end - this.locomotive.color = {0, 255, random(60, 255)} + this.locomotive.color = {random(2, 255), random(60, 255), random(60, 255)} this.locomotive.minable = false this.locomotive_cargo.minable = false this.locomotive_cargo.operable = true diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua index 88da13ed..9ae79e0c 100644 --- a/maps/mountain_fortress_v3/main.lua +++ b/maps/mountain_fortress_v3/main.lua @@ -52,7 +52,6 @@ local role_to_mention = Discord.role_mentions.mtn_fortress local floor = math.floor local remove = table.remove -local random = math.random RPG.disable_cooldowns_on_spells() local collapse_kill = { @@ -126,6 +125,8 @@ function Public.reset_map() Misc.set('creative_are_you_sure', false) Misc.set('creative_enabled', false) + Event.raise(WD.events.on_game_reset, {}) + this.active_surface_index = Public.create_surface() -- this.soft_reset_counter = Public.get_reset_counter() @@ -264,7 +265,6 @@ function Public.reset_map() WD.increase_average_unit_group_size(true) WD.increase_max_active_unit_groups(true) WD.enable_random_spawn_positions(true) - WD.set_pause_wave_in_ticks(random(18000, 54000)) Public.set_difficulty() Public.disable_creative() diff --git a/maps/mountain_fortress_v3/resource_generator.lua b/maps/mountain_fortress_v3/resource_generator.lua index 65999626..88724a3c 100644 --- a/maps/mountain_fortress_v3/resource_generator.lua +++ b/maps/mountain_fortress_v3/resource_generator.lua @@ -410,7 +410,7 @@ local testing_callback = { loot = testing_loot, weights = testing_weights, testing = true, - destructible = true + destructible = false } } @@ -419,7 +419,7 @@ local science_callback = { data = { loot = science_loot, weights = science_weights, - destructible = true + destructible = false } } @@ -428,7 +428,7 @@ local building_callback = { data = { loot = ammo_loot, weights = building_weights, - destructible = true + destructible = false } } @@ -437,7 +437,7 @@ local oil_callback = { data = { loot = oil_loot, weights = oil_weights, - destructible = true + destructible = false } } @@ -446,7 +446,7 @@ local oil_prod_callback = { data = { loot = oil_prod_loot, weights = oil_prod_weights, - destructible = true + destructible = false } } @@ -455,7 +455,7 @@ local resource_callback = { data = { loot = resource_loot, weights = resource_weights, - destructible = true + destructible = false } } @@ -464,7 +464,7 @@ local furnace_callback = { data = { loot = furnace_loot, weights = furnace_weights, - destructible = true + destructible = false } } diff --git a/maps/mountain_fortress_v3/table.lua b/maps/mountain_fortress_v3/table.lua index c39a78f8..11103a96 100644 --- a/maps/mountain_fortress_v3/table.lua +++ b/maps/mountain_fortress_v3/table.lua @@ -7,6 +7,7 @@ local this = { traps = {} } local Public = {} +local random = math.random Public.events = { reset_map = Event.generate_event_name('reset_map'), @@ -25,6 +26,12 @@ Public.zone_settings = { zone_width = 510 } +Public.valid_enemy_forces = { + ['enemy'] = true, + ['aggressors'] = true, + ['aggressors_frenzy'] = true +} + Public.pickaxe_upgrades = { 'Wood', 'Plastic', @@ -226,6 +233,7 @@ function Public.reset_main_table() this.check_afk_players = true this.winter_mode = false this.sent_to_discord = false + this.random_seed = random(23849829, 1283989182) this.difficulty = { multiply = 0.25, highest = 10, diff --git a/maps/mountain_fortress_v3/terrain.lua b/maps/mountain_fortress_v3/terrain.lua index f7d7dc10..528bf8fd 100644 --- a/maps/mountain_fortress_v3/terrain.lua +++ b/maps/mountain_fortress_v3/terrain.lua @@ -9,14 +9,21 @@ local ceil = math.ceil local zone_settings = Public.zone_settings local worm_level_modifier = 0.19 +local base_tile = 'grass-1' local start_ground_tiles = { - 'sand-1', - 'dirt-1', - 'dirt-2', + 'grass-1', + 'grass-1', + 'grass-2', 'sand-2', - 'dirt-3', - 'sand-3' + 'grass-1', + 'grass-4', + 'sand-2', + 'grass-3', + 'grass-4', + 'grass-2', + 'sand-3', + 'grass-4' } local wagon_raffle = { @@ -243,7 +250,7 @@ local function place_wagon(data, adjusted_zones) end for _, tile in pairs(location) do - tiles[#tiles + 1] = {name = 'nuclear-ground', position = tile.position} + tiles[#tiles + 1] = {name = base_tile, position = tile.position} if tile.position.y % 1 == 0 and tile.position.x % 1 == 0 then entities[#entities + 1] = { name = 'straight-rail', @@ -295,8 +302,8 @@ local function wall(p, data) local seed = data.seed local y = data.yv - local small_caves = Public.get_noise('small_caves', p, seed + 204000) - local cave_ponds = Public.get_noise('cave_rivers', p, seed + 120400) + local small_caves = Public.get_noise('small_caves', p, seed + seed) + local cave_ponds = Public.get_noise('cave_rivers', p, seed + seed) if y > 9 + cave_ponds * 6 and y < 23 + small_caves * 6 then if small_caves > 0.02 or cave_ponds > 0.02 then if small_caves > 0.005 then @@ -315,7 +322,7 @@ local function wall(p, data) entities[#entities + 1] = {name = 'fish', position = p} end else - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if random(1, 5) ~= 1 then entities[#entities + 1] = {name = rock_raffle[random(1, #rock_raffle)], position = p} @@ -329,7 +336,7 @@ local function wall(p, data) end end else - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if surface.can_place_entity( @@ -485,7 +492,7 @@ local function zone_14(x, y, data, _, adjusted_zones) local small_caves = Public.get_noise('small_caves', p, seed) local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 40000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Resource Spots if smol_areas < -0.71 then @@ -565,7 +572,7 @@ local function zone_13(x, y, data, _, adjusted_zones) local small_caves = Public.get_noise('small_caves', p, seed) local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 70000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Resource Spots if smol_areas < -0.72 then @@ -645,8 +652,8 @@ local function zone_12(x, y, data, void_or_lab, adjusted_zones) local treasure = data.treasure local noise_1 = Public.get_noise('small_caves', p, seed) - local noise_2 = Public.get_noise('no_rocks_2', p, seed + 20000) - local smol_areas = Public.get_noise('smol_areas', p, seed + 60000) + local noise_2 = Public.get_noise('no_rocks_2', p, seed + seed) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Resource Spots if smol_areas < -0.72 then @@ -731,8 +738,8 @@ local function zone_11(x, y, data, _, adjusted_zones) local treasure = data.treasure local noise_1 = Public.get_noise('small_caves', p, seed) - local noise_2 = Public.get_noise('no_rocks_2', p, seed + 10000) - local smol_areas = Public.get_noise('smol_areas', p, seed + 50000) + local noise_2 = Public.get_noise('no_rocks_2', p, seed + seed) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) if noise_1 > 0.7 then tiles[#tiles + 1] = {name = 'water', position = p} @@ -827,7 +834,7 @@ local function zone_10(x, y, data, _, adjusted_zones) data.forest_zone = true local scrapyard = Public.get_noise('scrapyard', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 45000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) if scrapyard < -0.70 or scrapyard > 0.70 then tiles[#tiles + 1] = {name = 'grass-3', position = p} @@ -943,7 +950,7 @@ local function zone_9(x, y, data, _, adjusted_zones) local maze_p = {x = floor(p.x - p.x % 10), y = floor(p.y - p.y % 10)} local maze_noise = Public.get_noise('no_rocks_2', maze_p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 40000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) if maze_noise > -0.35 and maze_noise < 0.35 then tiles[#tiles + 1] = {name = 'dirt-7', position = p} @@ -1015,7 +1022,7 @@ local function zone_scrap_2(x, y, data, void_or_lab, adjusted_zones) data.scrap_zone = true local scrapyard_modified = Public.get_noise('scrapyard_modified', p, seed) - local cave_rivers = Public.get_noise('cave_rivers', p, seed + 65030) + local cave_rivers = Public.get_noise('cave_rivers', p, seed + seed) --Chasms local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) @@ -1127,7 +1134,7 @@ local function zone_scrap_2(x, y, data, void_or_lab, adjusted_zones) entities[#entities + 1] = {name = 'crude-oil', position = p, amount = get_oil_amount(p)} end - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if random(1, 256) == 1 then entities[#entities + 1] = {name = 'land-mine', position = p, force = 'enemy'} end @@ -1144,7 +1151,7 @@ local function zone_scrap_1(x, y, data, void_or_lab, adjusted_zones) data.scrap_zone = true local scrapyard = Public.get_noise('scrapyard', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 35000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Chasms local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) @@ -1272,9 +1279,9 @@ local function zone_7(x, y, data, void_or_lab, adjusted_zones) local treasure = data.treasure local cave_rivers_3 = Public.get_noise('cave_rivers_3', p, seed) - local cave_rivers_4 = Public.get_noise('cave_rivers_4', p, seed + 50000) + local cave_rivers_4 = Public.get_noise('cave_rivers_4', p, seed + seed) local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 30000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) if cave_rivers_3 > -0.025 and cave_rivers_3 < 0.025 and no_rocks_2 > -0.6 then tiles[#tiles + 1] = {name = 'water', position = p} @@ -1292,7 +1299,7 @@ local function zone_7(x, y, data, void_or_lab, adjusted_zones) return end - local noise_ores = Public.get_noise('no_rocks_2', p, seed + 25000) + local noise_ores = Public.get_noise('no_rocks_2', p, seed + seed) if cave_rivers_3 > -0.20 and cave_rivers_3 < 0.20 then tiles[#tiles + 1] = {name = 'grass-' .. floor(cave_rivers_3 * 32) % 3 + 1, position = p} @@ -1391,7 +1398,7 @@ local function zone_forest_2(x, y, data, void_or_lab, adjusted_zones) local large_caves = Public.get_noise('large_caves', p, seed) local cave_rivers = Public.get_noise('cave_rivers', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 25000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Chasms local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) @@ -1525,7 +1532,7 @@ local function zone_5(x, y, data, void_or_lab, adjusted_zones) local small_caves = Public.get_noise('small_caves', p, seed) local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 20000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) if small_caves > -0.24 and small_caves < 0.24 then tiles[#tiles + 1] = {name = 'dirt-7', position = p} @@ -1619,7 +1626,7 @@ local function zone_4(x, y, data, void_or_lab, adjusted_zones) local noise_large_caves = Public.get_noise('large_caves', p, seed) local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) local small_caves = Public.get_noise('dungeons', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 15000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) if abs(noise_large_caves) > 0.7 then tiles[#tiles + 1] = {name = 'water', position = p} @@ -1715,7 +1722,7 @@ local function zone_4(x, y, data, void_or_lab, adjusted_zones) if noise_large_caves > -0.2 and noise_large_caves < 0.2 then --Main Rock Terrain - local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 75000) + local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + seed) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then tiles[#tiles + 1] = {name = 'dirt-' .. floor(no_rocks_2 * 8) % 2 + 5, position = p} if random(1, 512) == 1 then @@ -1747,12 +1754,12 @@ local function zone_3(x, y, data, void_or_lab, adjusted_zones) local markets = data.markets local treasure = data.treasure - local small_caves = Public.get_noise('dungeons', p, seed + 50000) - local small_caves_2 = Public.get_noise('small_caves_2', p, seed + 70000) - local noise_large_caves = Public.get_noise('large_caves', p, seed + 60000) + local small_caves = Public.get_noise('dungeons', p, seed + seed) + local small_caves_2 = Public.get_noise('small_caves_2', p, seed + seed) + local noise_large_caves = Public.get_noise('large_caves', p, seed + seed) local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) local cave_miner = Public.get_noise('cave_miner_01', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 60000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Resource Spots if smol_areas < 0.055 and smol_areas > -0.025 then @@ -1815,7 +1822,7 @@ local function zone_3(x, y, data, void_or_lab, adjusted_zones) end --Rivers - local cave_rivers = Public.get_noise('cave_rivers', p, seed + 100000) + local cave_rivers = Public.get_noise('cave_rivers', p, seed + seed) if cave_rivers < 0.024 and cave_rivers > -0.024 then if noise_cave_ponds > 0.2 then tiles[#tiles + 1] = {name = 'water-shallow', position = p} @@ -1841,7 +1848,7 @@ local function zone_3(x, y, data, void_or_lab, adjusted_zones) return end - local no_rocks = Public.get_noise('no_rocks', p, seed + 25000) + local no_rocks = Public.get_noise('no_rocks', p, seed + seed) --Worm oil Zones if no_rocks < 0.20 and no_rocks > -0.20 then if small_caves > 0.35 then @@ -1873,7 +1880,7 @@ local function zone_3(x, y, data, void_or_lab, adjusted_zones) end --Main Rock Terrain - local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 75000) + local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + seed) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then local success = place_wagon(data, adjusted_zones) if success then @@ -1915,7 +1922,7 @@ local function zone_2(x, y, data, void_or_lab, adjusted_zones) local small_caves = Public.get_noise('dungeons', p, seed) local noise_large_caves = Public.get_noise('large_caves', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 15000) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Resource Spots if smol_areas < 0.055 and smol_areas > -0.025 then @@ -1961,7 +1968,7 @@ local function zone_2(x, y, data, void_or_lab, adjusted_zones) end --Rivers - local cave_rivers = Public.get_noise('cave_rivers', p, seed + 100000) + local cave_rivers = Public.get_noise('cave_rivers', p, seed + seed) if cave_rivers < 0.037 and cave_rivers > -0.037 then if noise_cave_ponds < 0.1 then tiles[#tiles + 1] = {name = 'water-shallow', position = p} @@ -1989,7 +1996,7 @@ local function zone_2(x, y, data, void_or_lab, adjusted_zones) return end - local no_rocks = Public.get_noise('no_rocks', p, seed + 25000) + local no_rocks = Public.get_noise('no_rocks', p, seed + seed) --Worm oil Zones if no_rocks < 0.20 and no_rocks > -0.20 then if small_caves > 0.30 then @@ -2021,7 +2028,7 @@ local function zone_2(x, y, data, void_or_lab, adjusted_zones) end --Main Rock Terrain - local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 75000) + local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + seed) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then local success = place_wagon(data, adjusted_zones) if success then @@ -2058,9 +2065,9 @@ local function zone_forest_1(x, y, data, void_or_lab, adjusted_zones) local treasure = data.treasure data.forest_zone = true - local small_caves = Public.get_noise('dungeons', p, seed + 33322) + local small_caves = Public.get_noise('dungeons', p, seed + seed) local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed) - local smol_areas = Public.get_noise('smol_areas', p, seed + 33333) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) --Resource Spots if smol_areas < 0.055 and smol_areas > -0.025 then @@ -2112,7 +2119,7 @@ local function zone_forest_1(x, y, data, void_or_lab, adjusted_zones) end --Rivers - local cave_rivers = Public.get_noise('cave_rivers', p, seed + 200000) + local cave_rivers = Public.get_noise('cave_rivers', p, seed + seed) if cave_rivers < 0.041 and cave_rivers > -0.042 then if noise_cave_ponds > 0 then tiles[#tiles + 1] = {name = 'water-shallow', position = p} @@ -2134,7 +2141,7 @@ local function zone_forest_1(x, y, data, void_or_lab, adjusted_zones) return end - local no_rocks = Public.get_noise('no_rocks', p, seed + 30000) + local no_rocks = Public.get_noise('no_rocks', p, seed + seed) --Worm oil Zones if p.y < -64 + noise_cave_ponds * 10 then if no_rocks < 0.11 and no_rocks > -0.11 then @@ -2165,13 +2172,13 @@ local function zone_forest_1(x, y, data, void_or_lab, adjusted_zones) end --Main Rock Terrain - local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 5000) + local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + seed) if no_rocks_2 > 0.64 or no_rocks_2 < -0.64 then local success = place_wagon(data, adjusted_zones) if success then return end - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if random(1, 32) == 1 then entities[#entities + 1] = {name = 'tree-0' .. random(1, 9), position = p} end @@ -2294,7 +2301,7 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones) end --Rivers - local cave_rivers = Public.get_noise('cave_rivers', p, seed + 300000) + local cave_rivers = Public.get_noise('cave_rivers', p, seed + seed) if cave_rivers < 0.042 and cave_rivers > -0.042 then if noise_cave_ponds > 0 then tiles[#tiles + 1] = {name = 'water-shallow', position = p} @@ -2316,7 +2323,7 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones) return end - local no_rocks = Public.get_noise('no_rocks', p, seed + 50000) + local no_rocks = Public.get_noise('no_rocks', p, seed + seed) --Worm oil Zones if p.y < -64 + noise_cave_ponds * 10 then if no_rocks < 0.12 and no_rocks > -0.12 then @@ -2347,13 +2354,13 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones) end --Main Rock Terrain - local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 75000) + local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + seed) if no_rocks_2 > 0.66 or no_rocks_2 < -0.66 then local success = place_wagon(data, adjusted_zones) if success then return end - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if random(1, 32) == 1 then entities[#entities + 1] = {name = 'tree-0' .. random(1, 9), position = p} end @@ -2371,7 +2378,7 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones) if random_tiles > 0.095 then if random_tiles > 0.6 then if random(1, 100) > 42 then - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} end else if random(1, 100) > 42 then @@ -2383,7 +2390,7 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones) if random_tiles < -0.095 then if random_tiles < -0.6 then if random(1, 100) > 42 then - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} end else if random(1, 100) > 42 then @@ -2405,10 +2412,10 @@ local function starting_zone(x, y, data, void_or_lab, adjusted_zones) local markets = data.markets local treasure = data.treasure - local small_caves = Public.get_noise('dungeons', p, seed + 34883) - local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed + 28939) - local smol_areas = Public.get_noise('smol_areas', p, seed + 3992) - local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 1922) + local small_caves = Public.get_noise('dungeons', p, seed + seed) + local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed + seed) + local smol_areas = Public.get_noise('smol_areas', p, seed + seed) + local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + seed) local cave_rivers = Public.get_noise('cave_rivers', p, seed) local no_rocks = Public.get_noise('no_rocks', p, seed) @@ -2514,7 +2521,7 @@ local function starting_zone(x, y, data, void_or_lab, adjusted_zones) if success then return end - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if random(1, 18) == 1 then entities[#entities + 1] = {name = 'tree-0' .. random(1, 9), position = p} end @@ -2528,7 +2535,7 @@ local function starting_zone(x, y, data, void_or_lab, adjusted_zones) if random(1, 2048) == 1 then treasure[#treasure + 1] = {position = p, chest = 'iron-chest'} end - tiles[#tiles + 1] = {name = 'nuclear-ground', position = p} + tiles[#tiles + 1] = {name = base_tile, position = p} if random(1, 100) > 25 then entities[#entities + 1] = {name = rock_raffle[random(1, size_of_rock_raffle)], position = p} end @@ -2650,8 +2657,8 @@ local function border_chunk(p, data) entities[#entities + 1] = {name = trees[random(1, #trees)], position = pos} end - local noise = Public.get_noise('dungeons', pos, data.seed) - local index = floor(noise * 32) % 4 + 1 + local noise = Public.get_noise('dungeon_sewer', pos, data.seed) + local index = floor(noise * 32) % 11 + 1 tiles[#tiles + 1] = {name = start_ground_tiles[index], position = pos} local scrap_mineable_entities, scrap_mineable_entities_index = get_scrap_mineable_entities() @@ -2738,7 +2745,7 @@ function Public.heavy_functions(data) end if not data.seed then - data.seed = surface.map_gen_settings.seed + data.seed = Public.get('random_seed') end if get_tile.valid and get_tile.name == 'out-of-map' then diff --git a/modules/biter_health_booster_v2.lua b/modules/biter_health_booster_v2.lua index bbc6fa67..24ee69fe 100644 --- a/modules/biter_health_booster_v2.lua +++ b/modules/biter_health_booster_v2.lua @@ -240,6 +240,9 @@ end local function set_boss_healthbar(health, max_health, healthbar_id) local m = health / max_health + if m < 0 then + return + end local x_scale = rendering.get_y_scale(healthbar_id) * 15 rendering.set_x_scale(healthbar_id, x_scale * m) rendering.set_color(healthbar_id, {floor(255 - 255 * m), floor(200 * m), 0}) diff --git a/modules/rpg/functions.lua b/modules/rpg/functions.lua index 25530771..ef14071f 100644 --- a/modules/rpg/functions.lua +++ b/modules/rpg/functions.lua @@ -166,7 +166,7 @@ local function level_up(player) Public.level_up_effects(player) end -local function has_health_boost(entity, damage, final_damage_amount, cause) +local function has_health_boost(entity, damage, final_damage_amount, cause, callback_func) local biter_health_boost = BiterHealthBooster.get('biter_health_boost') local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units') @@ -194,7 +194,9 @@ local function has_health_boost(entity, damage, final_damage_amount, cause) if health_pool[1] <= 0 then local entity_number = entity.unit_number - entity.die(entity.force.name, cause) + if not callback_func then + entity.die(entity.force.name, cause) + end if biter_health_boost_units[entity_number] then biter_health_boost_units[entity_number] = nil @@ -204,7 +206,9 @@ local function has_health_boost(entity, damage, final_damage_amount, cause) entity.health = entity.health + final_damage_amount entity.health = entity.health - damage if entity.health <= 0 then - entity.die(cause.force.name, cause) + if not callback_func then + entity.die(cause.force.name, cause) + end end end else @@ -212,7 +216,9 @@ local function has_health_boost(entity, damage, final_damage_amount, cause) entity.health = entity.health + final_damage_amount entity.health = entity.health - damage if entity.health <= 0 then - entity.die(cause.force.name, cause) + if not callback_func then + entity.die(cause.force.name, cause) + end end end @@ -642,18 +648,18 @@ function Public.log_aoe_punch(callback) end --Melee damage modifier -function Public.aoe_punch(character, target, damage, get_health_pool) +function Public.aoe_punch(entity, target, damage, get_health_pool) if not (target and target.valid) then return end - local base_vector = {target.position.x - character.position.x, target.position.y - character.position.y} + local base_vector = {target.position.x - entity.position.x, target.position.y - entity.position.y} local vector = {base_vector[1], base_vector[2]} vector[1] = vector[1] * 1000 vector[2] = vector[2] * 1000 - character.surface.create_entity({name = 'blood-explosion-huge', position = target.position}) + entity.surface.create_entity({name = 'blood-explosion-huge', position = target.position}) if abs(vector[1]) > abs(vector[2]) then local d = abs(vector[1]) @@ -678,8 +684,8 @@ function Public.aoe_punch(character, target, damage, get_health_pool) local a = 0.20 - local cs = character.surface - local cp = character.position + local cs = entity.surface + local cp = entity.position for i = 1, 16, 1 do for x = i * -1 * a, i * a, 1 do @@ -690,7 +696,7 @@ function Public.aoe_punch(character, target, damage, get_health_pool) if e.valid then if e.health then if e.destructible and e.minable and e.force.index ~= 3 then - if e.force.index ~= character.force.index then + if e.force.index ~= entity.force.index then if get_health_pool then local max_unit_health = floor(get_health_pool * 0.00015) if max_unit_health <= 0 then @@ -700,15 +706,15 @@ function Public.aoe_punch(character, target, damage, get_health_pool) max_unit_health = 10 end local final = floor(damage * max_unit_health) - set_health_boost(e, final, character) + set_health_boost(e, final, entity) if e.valid and e.health <= 0 and get_health_pool <= 0 then - e.die(e.force.name, character) + e.die(e.force.name, entity) end else if e.valid then e.health = e.health - damage * 0.05 if e.health <= 0 then - e.die(e.force.name, character) + e.die(e.force.name, entity) end end end From 3771c1ac6667858fcc8fc79d85a1750659c08110 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Sat, 27 May 2023 17:43:18 +0200 Subject: [PATCH 11/15] Mtn v3 - fix coin bug --- maps/mountain_fortress_v3/entities.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/maps/mountain_fortress_v3/entities.lua b/maps/mountain_fortress_v3/entities.lua index 1d573d12..28123ef1 100644 --- a/maps/mountain_fortress_v3/entities.lua +++ b/maps/mountain_fortress_v3/entities.lua @@ -742,10 +742,12 @@ local function on_player_mined_entity(event) if random(1, 3) == 1 then give_coin(player) end - else + elseif entity.type == 'simple-entity-with-owner' then if random(1, 6) == 1 then give_coin(player) end + else + give_coin(player) end if rpg_char.stone_path then entity.surface.set_tiles({{name = 'stone-path', position = entity.position}}, true) From 1119849d9e0cf65fc165eec35e97787551aa8313 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Sat, 27 May 2023 20:20:02 +0200 Subject: [PATCH 12/15] Mtn v3 - fix biters attacking eachother --- maps/mountain_fortress_v3/main.lua | 11 -- modules/wave_defense/enemy_states.lua | 208 ++++++++++++++++++++------ 2 files changed, 166 insertions(+), 53 deletions(-) diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua index 9ae79e0c..82037e5d 100644 --- a/maps/mountain_fortress_v3/main.lua +++ b/maps/mountain_fortress_v3/main.lua @@ -73,16 +73,6 @@ local collapse_kill = { enabled = true } -local init_protectors_force = function() - local protectors = game.forces.protectors - local enemy = game.forces.enemy - if not protectors then - protectors = game.create_force('protectors') - end - protectors.set_friend('enemy', true) - enemy.set_friend('protectors', true) -end - local init_bonus_drill_force = function() local bonus_drill = game.forces.bonus_drill local player = game.forces.player @@ -172,7 +162,6 @@ function Public.reset_map() Group.alphanumeric_only(false) Public.disable_tech() - init_protectors_force() init_bonus_drill_force() local surface = game.surfaces[this.active_surface_index] diff --git a/modules/wave_defense/enemy_states.lua b/modules/wave_defense/enemy_states.lua index 2a2a7e7e..72fd9e39 100644 --- a/modules/wave_defense/enemy_states.lua +++ b/modules/wave_defense/enemy_states.lua @@ -12,6 +12,7 @@ local random = math.random local abs = math.abs local floor = math.floor local set_timeout_in_ticks = Task.set_timeout_in_ticks +local deepcopy = table.deepcopy local this = { states = {}, @@ -118,6 +119,21 @@ local restore_force_token = end ) +local function is_closer(pos1, pos2, pos) + return ((pos1.x - pos.x) ^ 2 + (pos1.y - pos.y) ^ 2) < ((pos2.x - pos.x) ^ 2 + (pos2.y - pos.y) ^ 2) +end + +local function shuffle_distance(tbl, position) + local size = #tbl + for i = size, 1, -1 do + local rand = random(size) + if is_closer(tbl[i].position, tbl[rand].position, position) and i > rand then + tbl[i], tbl[rand] = tbl[rand], tbl[i] + end + end + return tbl +end + local function aoe_punch(entity, target, damage) if not (target and target.valid) then return @@ -263,7 +279,17 @@ local function set_commands() commands[#commands + 1] = { type = defines.command.attack_area, destination = {x = unit.position.x, y = unit.position.y}, - radius = 12, + radius = 15, + distraction = defines.distraction.by_enemy + } + commands[#commands + 1] = { + type = defines.command.build_base, + destination = {x = unit.position.x, y = unit.position.y} + } + commands[#commands + 1] = { + type = defines.command.attack_area, + destination = {x = unit.position.x, y = unit.position.y}, + radius = 15, distraction = defines.distraction.by_enemy } commands[#commands + 1] = { @@ -271,12 +297,42 @@ local function set_commands() destination = {x = unit.position.x, y = unit.position.y} } else - this.target_settings.last_set_target = 'main' commands[#commands + 1] = { type = defines.command.attack, target = unit, distraction = defines.distraction.by_anything } + commands[#commands + 1] = { + type = defines.command.attack_area, + destination = {x = unit.position.x, y = unit.position.y}, + radius = 15, + distraction = defines.distraction.by_enemy + } + commands[#commands + 1] = { + type = defines.command.build_base, + destination = {x = unit.position.x, y = unit.position.y} + } + commands[#commands + 1] = { + type = defines.command.attack, + target = unit, + distraction = defines.distraction.by_anything + } + commands[#commands + 1] = { + type = defines.command.attack_area, + destination = {x = unit.position.x, y = unit.position.y}, + radius = 15, + distraction = defines.distraction.by_enemy + } + commands[#commands + 1] = { + type = defines.command.build_base, + destination = {x = unit.position.x, y = unit.position.y} + } + commands[#commands + 1] = { + type = defines.command.attack, + target = unit, + distraction = defines.distraction.by_anything + } + this.target_settings.last_set_target = 'main' end local command = { @@ -288,7 +344,34 @@ local function set_commands() local surface = unit.surface surface.set_multi_command({command = command, unit_count = 5000, force = 'aggressors'}) - this.target_settings.commands = command + this.target_settings.commands = commands +end + +local function set_forces() + local aggressors = game.forces.aggressors + local aggressors_frenzy = game.forces.aggressors_frenzy + local enemy = game.forces.enemy + if not aggressors then + aggressors = game.create_force('aggressors') + end + if not aggressors_frenzy then + aggressors_frenzy = game.create_force('aggressors_frenzy') + end + + aggressors.set_friend('aggressors_frenzy', true) + aggressors.set_cease_fire('aggressors_frenzy', true) + aggressors.set_friend('enemy', true) + aggressors.set_cease_fire('enemy', true) + + aggressors_frenzy.set_friend('aggressors', true) + aggressors_frenzy.set_cease_fire('aggressors', true) + aggressors_frenzy.set_friend('enemy', true) + aggressors_frenzy.set_cease_fire('enemy', true) + + enemy.set_friend('aggressors', true) + enemy.set_cease_fire('aggressors', true) + enemy.set_friend('aggressors_frenzy', true) + enemy.set_cease_fire('aggressors_frenzy', true) end local function on_init() @@ -301,29 +384,7 @@ local function on_init() } this.target_settings = {} - local aggressors = game.forces.aggressors - local aggressors_frenzy = game.forces.aggressors_frenzy - local enemy = game.forces.enemy - - if not aggressors then - aggressors = game.create_force('aggressors') - end - if not aggressors_frenzy then - aggressors_frenzy = game.create_force('aggressors_frenzy') - end - - aggressors.set_gun_speed_modifier('biological', 1) - aggressors.set_gun_speed_modifier('melee', 0.2) - aggressors.set_friend('aggressors_frenzy', true) - aggressors.set_friend('enemy', true) - - aggressors_frenzy.set_gun_speed_modifier('biological', 10) - aggressors_frenzy.set_gun_speed_modifier('melee', 5) - aggressors_frenzy.set_friend('aggressors', true) - aggressors_frenzy.set_friend('enemy', true) - - enemy.set_friend('aggressors', true) - enemy.set_friend('aggressors_frenzy', true) + set_forces() end local function on_wave_created(event) @@ -634,7 +695,7 @@ function Public._esp:unit_group(unit_group) end --- Creates a fire entity. -function Public._esp:fire_damage() +function Public._esp:spew_damage() local entity = self.entity if not entity or not entity.valid then return @@ -642,7 +703,7 @@ function Public._esp:fire_damage() local position = {entity.position.x + (-5 + random(0, 10)), entity.position.y + (-5 + random(0, 10))} - entity.surface.create_entity({name = 'fire-flame', position = position}) + entity.surface.create_entity({name = 'acid-stream-spitter-medium', position = position, target = position, source = position}) if random(1, 5) == 1 then entity.surface.create_entity( { @@ -715,27 +776,92 @@ function Public._esp:area_of_spit_attack(range) ) end +function Public._esp:find_targets() + local entity = self.entity + if not entity or not entity.valid then + return + end + + local unit_group_command_step_length = Public.get('unit_group_command_step_length') + local step_length = unit_group_command_step_length + + local obstacles = + entity.surface.find_entities_filtered { + position = entity.position, + radius = step_length / 2, + type = {'simple-entity', 'tree'}, + limit = 50 + } + if obstacles then + shuffle_distance(obstacles, entity.position) + self.commands = self.commands or {} + for ii = 1, #obstacles, 1 do + if obstacles[ii].valid then + self.commands[#self.commands + 1] = { + type = defines.command.attack, + target = obstacles[ii], + distraction = defines.distraction.by_anything + } + end + end + end +end + --- Attack target function Public._esp:attack_target() local entity = self.entity if not entity or not entity.valid then return end + local tick = game.tick local orders = self.moving_to_attack_target - if not orders then - self.moving_to_attack_target = tick + 300 - orders = self.moving_to_attack_target + + if this.target_settings.commands and this.target_settings.commands.commands then + this.target_settings.commands = nil + return end - -- if entity.distraction_command and entity.distraction_command.target.name then - -- log(serpent.block(entity.distraction_command.target.name)) - -- end + if not this.target_settings.commands then + return + end + + local compound_commands = deepcopy(this.target_settings.commands) + + if not orders then + self:find_targets() + self.moving_to_attack_target = tick + 200 + orders = self.moving_to_attack_target + if self.commands and next(self.commands) then + for _, entry in pairs(self.commands) do + compound_commands[#compound_commands + 1] = entry + end + end + local command = { + type = defines.command.compound, + structure_type = defines.compound_command.return_last, + commands = compound_commands + } + entity.set_command(command) + end if tick > orders then - self.moving_to_attack_target = tick + 300 - entity.set_command(this.target_settings.commands) + self:find_targets() + self.moving_to_attack_target = tick + 200 + if self.commands and next(self.commands) then + for _, entry in pairs(self.commands) do + compound_commands[#compound_commands + 1] = entry + end + end + + local command = { + type = defines.command.compound, + structure_type = defines.compound_command.return_last, + commands = compound_commands + } + entity.set_command(command) end + self.commands = nil end -- Sets the attack speed for the given force @@ -817,16 +943,16 @@ function Public._esp:work(tick) end end + self:attack_target() + if self.boss_unit then if random(1, 20) == 1 then - self:fire_damage() + self:spew_damage() elseif random(1, 30) == 1 then self:set_burst_frenzy() elseif random(1, 50) == 1 then self:fire_projectile() elseif random(1, 100) == 1 then - self:attack_target() - elseif random(1, 200) == 1 then if this.settings.wave_number >= 1000 then self:area_of_spit_attack() end @@ -837,11 +963,9 @@ function Public._esp:work(tick) end elseif tick < self.ttl then if random(1, 20) == 1 then - self:fire_damage() + self:spew_damage() elseif random(1, 50) == 1 then self:set_burst_frenzy() - elseif random(1, 100) == 1 then - self:attack_target() end else self:remove() From 5e5654bccd5971ab1d642db95aeb75fe336eb127 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Sat, 27 May 2023 23:19:44 +0200 Subject: [PATCH 13/15] WD - removing debug code from prod --- modules/wave_defense/main.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua index 5a78dbd1..d1d5208a 100644 --- a/modules/wave_defense/main.lua +++ b/modules/wave_defense/main.lua @@ -1093,7 +1093,6 @@ local function spawn_unit_group(fs, only_bosses) event_data.spawn_count = count for _ = 1, count, 1 do local biter = spawn_biter(surface, spawn_position, fs, true, unit_settings) - game.print(serpent.block(biter and biter.unit_number)) if not biter then debug_print('spawn_unit_group - No biter was found?') break From a41257334e955f4c702348fd1a5fcb0f037dde6f Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Sun, 28 May 2023 14:05:38 +0200 Subject: [PATCH 14/15] Push hotfix changes for Mtn v3 and WD --- modules/wave_defense/commands.lua | 33 +++++-- modules/wave_defense/enemy_states.lua | 131 ++++++++++++++++++++------ modules/wave_defense/main.lua | 10 +- 3 files changed, 136 insertions(+), 38 deletions(-) diff --git a/modules/wave_defense/commands.lua b/modules/wave_defense/commands.lua index 10e9c685..4810cde1 100644 --- a/modules/wave_defense/commands.lua +++ b/modules/wave_defense/commands.lua @@ -1,36 +1,49 @@ local Public = require 'modules.wave_defense.table' +local module_name = '[WD]' commands.add_command( 'wd_debug_module', '', function(cmd) + local p local player = game.player + + if not player or not player.valid then + p = print + else + p = player.print + if not player.admin then + return + end + end + local param = tostring(cmd.parameter) if param == nil then return end - if not (player and player.valid) then - return - end - - if not player.admin then - return - end - if param == 'skip' then Public.get('enable_grace_time').enabled = false + p(module_name .. ' grace skipped!') + return + end + + if param == 'toggle_es' then + Public.set_module_status() + p(module_name .. ' ES has been toggled!') return end if param == 'spawn_wave' then Public.spawn_unit_group(true, true) + p(module_name .. ' wave spawned!') return end if param == 'next_wave' then Public.set_next_wave() Public.spawn_unit_group(true, true) + p(module_name .. ' wave spawned!') return end @@ -39,6 +52,7 @@ commands.add_command( Public.set_next_wave() end Public.spawn_unit_group(true, true) + p(module_name .. ' wave spawned!') return end @@ -47,11 +61,13 @@ commands.add_command( Public.set_next_wave() end Public.spawn_unit_group(true, true) + p(module_name .. ' wave spawned!') return end if param == 'log_all' then Public.toggle_debug() + p(module_name .. ' debug toggled!') return end @@ -64,6 +80,7 @@ commands.add_command( this.wave_interval = 200 this.wave_enforced = true this.debug_only_on_wave_500 = true + p(module_name .. ' debug health toggled!') end end ) diff --git a/modules/wave_defense/enemy_states.lua b/modules/wave_defense/enemy_states.lua index 72fd9e39..a21dd9ee 100644 --- a/modules/wave_defense/enemy_states.lua +++ b/modules/wave_defense/enemy_states.lua @@ -5,6 +5,7 @@ local Task = require 'utils.task' local Token = require 'utils.token' local Public = require 'modules.wave_defense.table' local Difficulty = require 'modules.difficulty_vote_by_amount' +local Beams = require 'modules.render_beam' local de = defines.events local ev = Public.events @@ -20,7 +21,8 @@ local this = { settings = { frenzy_length = 3600, frenzy_burst_length = 160, - update_rate = 60 + update_rate = 60, + enabled = false }, target_settings = {} } @@ -145,8 +147,6 @@ local function aoe_punch(entity, target, damage) vector[1] = vector[1] * 1000 vector[2] = vector[2] * 1000 - entity.surface.create_entity({name = 'blood-explosion-huge', position = target.position}) - if abs(vector[1]) > abs(vector[2]) then local d = abs(vector[1]) if abs(vector[1]) > 0 then @@ -266,6 +266,12 @@ local function area_of_effect(entity, radius, callback, find_entities) end end +local function shoot_laser(surface, source, enemy) + local force = source.force + surface.create_entity {name = 'laser-beam', position = source.position, force = 'player', target = enemy, source = source, max_length = 32, duration = 60} + enemy.damage(20 * (1 + force.get_ammo_damage_modifier('laser') + force.get_gun_speed_modifier('laser')), force, 'laser', source) +end + local function set_commands() local unit = this.target_settings.main_target if not unit or not unit.valid then @@ -377,17 +383,19 @@ end local function on_init() this.states = {} this.state_count = 0 - this.settings = { - frenzy_length = 3600, - frenzy_burst_length = 160, - update_rate = 60 - } + this.settings.frenzy_length = 3600 + this.settings.frenzy_burst_length = 160 + this.settings.update_rate = 60 this.target_settings = {} set_forces() end local function on_wave_created(event) + if not this.settings.enabled then + return + end + local wave_number = event.wave_number if not wave_number then return @@ -408,6 +416,10 @@ local function on_wave_created(event) end local function on_unit_group_created(event) + if not this.settings.enabled then + return + end + local unit_group = event.unit_group if not unit_group or not unit_group.valid then return @@ -425,6 +437,10 @@ local function on_unit_group_created(event) end local function on_target_aquired(event) + if not this.settings.enabled then + return + end + local target = event.target if not target or not target.valid then return @@ -452,6 +468,10 @@ local function on_target_aquired(event) end local function on_entity_created(event) + if not this.settings.enabled then + return + end + local entity = event.entity if not entity or not entity.valid then return @@ -476,6 +496,10 @@ local function on_entity_created(event) end local function on_evolution_factor_changed(event) + if not this.settings.enabled then + return + end + local evolution_factor = event.evolution_factor if not evolution_factor then return @@ -488,6 +512,10 @@ local function on_evolution_factor_changed(event) end local function on_entity_died(event) + if not this.settings.enabled then + return + end + local entity = event.entity if not entity.valid then return @@ -500,6 +528,9 @@ local function on_entity_died(event) end local function on_entity_damaged(event) + if not this.settings.enabled then + return + end local entity = event.entity if not (entity and entity.valid) then return @@ -515,7 +546,8 @@ local function on_entity_damaged(event) state:spawn_children() end - if entity.health <= max / 2 and state.teleported < 5 then + if state.boss_unit and entity.health <= max / 2 and state.teleported < 5 then + state.teleported = state.teleported + 1 if random(1, 4) == 1 then state:switch_position() end @@ -694,7 +726,40 @@ function Public._esp:unit_group(unit_group) self.unit_group = unit_group end ---- Creates a fire entity. +--- Creates a beam. +function Public._esp:beam() + local entity = self.entity + if not entity or not entity.valid then + return + end + + Beams.new_beam_delayed(entity.surface, random(500, 3000)) +end + +--- Creates a laser. +function Public._esp:laser(boss) + local entity = self.entity + if not entity or not entity.valid then + return + end + + local limit = boss or 3 + + local surface = entity.surface + + local enemies = surface.find_entities_filtered {radius = 10, limit = limit, force = 'player', position = entity.position} + if enemies == nil or #enemies == 0 then + return + end + for i = 1, #enemies, 1 do + local enemy = enemies[i] + if enemy and enemy.valid and enemy.health and enemy.health > 0 and enemy.destructible then + shoot_laser(surface, entity, enemy) + end + end +end + +--- Creates spew. function Public._esp:spew_damage() local entity = self.entity if not entity or not entity.valid then @@ -704,15 +769,6 @@ function Public._esp:spew_damage() local position = {entity.position.x + (-5 + random(0, 10)), entity.position.y + (-5 + random(0, 10))} entity.surface.create_entity({name = 'acid-stream-spitter-medium', position = position, target = position, source = position}) - if random(1, 5) == 1 then - entity.surface.create_entity( - { - name = 'medium-scorchmark', - position = position, - force = 'aggressors' - } - ) - end end --- Creates a projectile. @@ -888,7 +944,7 @@ function Public._esp:switch_position() return end - local position = {entity.position.x + (-5 + random(0, 15)), entity.position.y + (-5 + random(0, 15))} + local position = {entity.position.x + (-5 + random(0, 15)), entity.position.y + (5 + random(0, 15))} local rand = entity.surface.find_non_colliding_position(entity.name, position, 0.2, 0.5) if rand then @@ -920,11 +976,14 @@ function Public._esp:set_boss() return end + local tick = game.tick + self.boss_unit = true - if this.settings.wave_number > 499 then + if this.settings.wave_number > 1499 then if this.settings.wave_number % 100 == 0 then self.go_havoc = true + self.havoc_interval = tick + 50 end end end @@ -934,10 +993,15 @@ function Public._esp:work(tick) self:set_frenzy() end - if self.go_havoc then - self:fire_projectile() - self:area_of_spit_attack() - self:aoe_attack() + if self.go_havoc and self.clear_go_havoc > tick then + if tick > self.havoc_interval then + self:fire_projectile() + self:area_of_spit_attack() + if random(1, 10) == 1 then + self:aoe_attack() + end + self.havoc_interval = tick + 50 + end if not self.clear_go_havoc then self.clear_go_havoc = game.tick + 3600 end @@ -952,26 +1016,35 @@ function Public._esp:work(tick) self:set_burst_frenzy() elseif random(1, 50) == 1 then self:fire_projectile() - elseif random(1, 100) == 1 then + elseif random(1, 60) == 1 then + self:laser(6) + elseif random(1, 80) == 1 then if this.settings.wave_number >= 1000 then self:area_of_spit_attack() end - elseif random(1, 300) == 1 then + elseif random(1, 100) == 1 then if this.settings.wave_number >= 1000 then self:aoe_attack() end end elseif tick < self.ttl then - if random(1, 20) == 1 then + if random(1, 40) == 1 then self:spew_damage() elseif random(1, 50) == 1 then self:set_burst_frenzy() + elseif random(1, 60) == 1 then + self:laser() end else self:remove() end end +Public.set_module_status = function() + on_init() + this.settings.enabled = not this.settings.enabled +end + Event.on_init(on_init) Event.add(de.on_entity_died, on_entity_died) Event.add(de.on_entity_damaged, on_entity_damaged) @@ -981,3 +1054,5 @@ Event.add(ev.on_entity_created, on_entity_created) Event.add(ev.on_target_aquired, on_target_aquired) Event.add(ev.on_evolution_factor_changed, on_evolution_factor_changed) Event.add(ev.on_game_reset, on_init) + +return Public diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua index d1d5208a..244fecc2 100644 --- a/modules/wave_defense/main.lua +++ b/modules/wave_defense/main.lua @@ -63,8 +63,8 @@ local function find_initial_spot(surface, position) if random(1, 2) == 1 then local random_pos = { {x = pos.x - 10, y = pos.y - 5}, - {x = pos.x + 10, y = pos.y + 5}, - {x = pos.x - 10, y = pos.y + 5}, + {x = pos.x + 10, y = pos.y - 5}, + {x = pos.x - 10, y = pos.y - 5}, {x = pos.x + 10, y = pos.y - 5} } local actual_pos = shuffle(random_pos) @@ -184,6 +184,12 @@ local function get_spawn_pos() local initial_position = Public.get('spawn_position') + if random(1, 2) == 1 then + initial_position = {x = initial_position.x, y = initial_position.y - 30} + else + initial_position = {x = initial_position.x, y = initial_position.y - 20} + end + local located_position = find_initial_spot(surface, initial_position) local valid_position = surface.find_non_colliding_position('stone-furnace', located_position, 32, 1) local debug = Public.get('debug') From d918f045e7c85ca5fdea61c17fa5116bb6c99784 Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Sun, 28 May 2023 14:18:33 +0200 Subject: [PATCH 15/15] WD - Minor fix --- modules/wave_defense/enemy_states.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/wave_defense/enemy_states.lua b/modules/wave_defense/enemy_states.lua index a21dd9ee..6245aeca 100644 --- a/modules/wave_defense/enemy_states.lua +++ b/modules/wave_defense/enemy_states.lua @@ -984,6 +984,7 @@ function Public._esp:set_boss() if this.settings.wave_number % 100 == 0 then self.go_havoc = true self.havoc_interval = tick + 50 + self.clear_go_havoc = tick + 3600 end end end @@ -1002,9 +1003,6 @@ function Public._esp:work(tick) end self.havoc_interval = tick + 50 end - if not self.clear_go_havoc then - self.clear_go_havoc = game.tick + 3600 - end end self:attack_target()