From e50243a20b4c4ae289a6200bdce966483c06315c Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Thu, 12 May 2022 22:19:00 +0200
Subject: [PATCH 01/13] wave defense - fixes

---
 modules/wave_defense/biter_rolls.lua    |   6 +-
 modules/wave_defense/buried_enemies.lua | 103 +++++++++---------------
 modules/wave_defense/commands.lua       |  83 ++++++++++---------
 modules/wave_defense/main.lua           |  10 ++-
 modules/wave_defense/threat_events.lua  |   4 +-
 5 files changed, 95 insertions(+), 111 deletions(-)

diff --git a/modules/wave_defense/biter_rolls.lua b/modules/wave_defense/biter_rolls.lua
index e627ab9d..3296ccd9 100644
--- a/modules/wave_defense/biter_rolls.lua
+++ b/modules/wave_defense/biter_rolls.lua
@@ -3,7 +3,7 @@ local Public = require 'modules.wave_defense.table'
 function Public.wave_defense_roll_biter_name()
     local biter_raffle = Public.get('biter_raffle')
     local max_chance = 0
-    for k, v in pairs(biter_raffle) do
+    for _, v in pairs(biter_raffle) do
         max_chance = max_chance + v
     end
     local r = math.random(0, math.floor(max_chance))
@@ -19,7 +19,7 @@ end
 function Public.wave_defense_roll_spitter_name()
     local spitter_raffle = Public.get('spitter_raffle')
     local max_chance = 0
-    for k, v in pairs(spitter_raffle) do
+    for _, v in pairs(spitter_raffle) do
         max_chance = max_chance + v
     end
     local r = math.random(0, math.floor(max_chance))
@@ -80,7 +80,7 @@ end
 function Public.wave_defense_roll_worm_name()
     local worm_raffle = Public.get('worm_raffle')
     local max_chance = 0
-    for k, v in pairs(worm_raffle) do
+    for _, v in pairs(worm_raffle) do
         max_chance = max_chance + v
     end
     local r = math.random(0, math.floor(max_chance))
diff --git a/modules/wave_defense/buried_enemies.lua b/modules/wave_defense/buried_enemies.lua
index 76518ca3..e4400cbb 100644
--- a/modules/wave_defense/buried_enemies.lua
+++ b/modules/wave_defense/buried_enemies.lua
@@ -2,14 +2,13 @@ local Public = require 'modules.wave_defense.table'
 local Event = require 'utils.event'
 local Global = require 'utils.global'
 local BiterHealthBooster = require 'modules.biter_health_booster_v2'
-local Diff = require 'modules.difficulty_vote_by_amount'
 
-local traps = {}
+local this = {}
 
 Global.register(
-    traps,
+    this,
     function(t)
-        traps = t
+        this = t
     end
 )
 
@@ -29,7 +28,7 @@ local random_particles = {
     'coal-particle'
 }
 
-local s_random_particles = #random_particles
+local size_random_particles = #random_particles
 
 local function create_particles(data)
     local surface = data.surface
@@ -39,13 +38,13 @@ local function create_particles(data)
     if not surface or not surface.valid then
         return
     end
-    for i = 1, amount, 1 do
+    for _ = 1, amount, 1 do
         local m = random(6, 12)
         local m2 = m * 0.005
 
         surface.create_particle(
             {
-                name = random_particles[random(1, s_random_particles)],
+                name = random_particles[random(1, size_random_particles)],
                 position = position,
                 frame_speed = 0.1,
                 vertical_speed = 0.1,
@@ -60,8 +59,6 @@ local function spawn_biters(data)
     local surface = data.surface
     local position = data.position
     local h = floor(abs(position.y))
-    local wave_number = Public.get('wave_number')
-    local d = Diff.get()
 
     if not position then
         position = surface.find_non_colliding_position('small-biter', position, 10, 1)
@@ -70,64 +67,44 @@ local function spawn_biters(data)
         end
     end
 
-    local m = 0.0015
-    if d.difficulty_vote_index then
-        if not d.strength_modifier then
-            m = m * 1.05
-        else
-            m = m * d.strength_modifier
-        end
+    local unit_to_create
+
+    if random(1, 3) == 1 then
+        unit_to_create = Public.wave_defense_roll_spitter_name()
+    else
+        unit_to_create = Public.wave_defense_roll_biter_name()
     end
 
-    local boosted_health = 1 + (wave_number * (m * 2))
-
-    if wave_number >= 100 then
-        boosted_health = boosted_health * 2
-    end
+    local modified_unit_health = Public.get('modified_unit_health')
+    local modified_boss_unit_health = Public.get('modified_boss_unit_health')
 
     Public.wave_defense_set_unit_raffle(h * 0.20)
 
-    local unit
-    if random(1, 3) == 1 then
-        unit = surface.create_entity({name = Public.wave_defense_roll_spitter_name(), position = position})
-    else
-        unit = surface.create_entity({name = Public.wave_defense_roll_biter_name(), position = position})
-    end
+    local unit = surface.create_entity({name = unit_to_create, position = position})
 
-    if random(1, 45) == 1 then
-        BiterHealthBooster.add_unit(unit, boosted_health)
-    elseif random(1, 64) == 1 then
-        BiterHealthBooster.add_boss_unit(unit, boosted_health, 0.38)
+    if random(1, 30) == 1 then
+        BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
+    else
+        BiterHealthBooster.add_unit(unit, modified_unit_health.current_value * 2)
     end
 end
 
 local function spawn_worms(data)
-    local wave_number = Public.get('wave_number')
-    local d = Diff.get()
-    local m = 0.0015
-    if d.difficulty_vote_index then
-        if not d.strength_modifier then
-            m = m * 1.05
-        else
-            m = m * d.strength_modifier
-        end
-    end
-
-    local boosted_health = 1 + (wave_number * (m * 2))
-
-    if wave_number >= 100 then
-        boosted_health = boosted_health * 2
-    end
+    local modified_unit_health = Public.get('modified_unit_health')
+    local modified_boss_unit_health = Public.get('modified_boss_unit_health')
 
     local surface = data.surface
     local position = data.position
     Public.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
-    local unit = surface.create_entity({name = Public.wave_defense_roll_worm_name(), position = position})
 
-    if random(1, 45) == 1 then
-        BiterHealthBooster.add_unit(unit, boosted_health)
-    elseif random(1, 64) == 1 then
-        BiterHealthBooster.add_boss_unit(unit, boosted_health, 0.38)
+    local unit_to_create = Public.wave_defense_roll_worm_name(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
+
+    local unit = surface.create_entity({name = unit_to_create, position = position})
+
+    if random(1, 30) == 1 then
+        BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
+    else
+        BiterHealthBooster.add_unit(unit, modified_unit_health.current_value * 2)
     end
 end
 
@@ -155,11 +132,11 @@ function Public.buried_biter(surface, position, max)
     local ticks = amount * 30
     ticks = ticks + 90
     for t = 1, ticks, 1 do
-        if not traps[game.tick + t] then
-            traps[game.tick + t] = {}
+        if not this[game.tick + t] then
+            this[game.tick + t] = {}
         end
 
-        traps[game.tick + t][#traps[game.tick + t] + 1] = {
+        this[game.tick + t][#this[game.tick + t] + 1] = {
             callback = 'create_particles',
             data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4}
         }
@@ -167,7 +144,7 @@ function Public.buried_biter(surface, position, max)
         if t > 90 then
             if t % 30 == 29 then
                 a = a + 1
-                traps[game.tick + t][#traps[game.tick + t] + 1] = {
+                this[game.tick + t][#this[game.tick + t] + 1] = {
                     callback = 'spawn_biters',
                     data = {surface = surface, position = {x = position.x, y = position.y}}
                 }
@@ -202,17 +179,17 @@ function Public.buried_worm(surface, position)
     ticks = ticks + 90
     local a = false
     for t = 1, ticks, 1 do
-        if not traps[game.tick + t] then
-            traps[game.tick + t] = {}
+        if not this[game.tick + t] then
+            this[game.tick + t] = {}
         end
 
-        traps[game.tick + t][#traps[game.tick + t] + 1] = {
+        this[game.tick + t][#this[game.tick + t] + 1] = {
             callback = 'create_particles',
             data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4}
         }
 
         if not a then
-            traps[game.tick + t][#traps[game.tick + t] + 1] = {
+            this[game.tick + t][#this[game.tick + t] + 1] = {
                 callback = 'spawn_worms',
                 data = {surface = surface, position = {x = position.x, y = position.y}}
             }
@@ -229,10 +206,10 @@ local callbacks = {
 
 local function on_tick()
     local t = game.tick
-    if not traps[t] then
+    if not this[t] then
         return
     end
-    for _, token in pairs(traps[t]) do
+    for _, token in pairs(this[t]) do
         local callback = token.callback
         local data = token.data
         local cbl = callbacks[callback]
@@ -240,7 +217,7 @@ local function on_tick()
             cbl(data)
         end
     end
-    traps[t] = nil
+    this[t] = nil
 end
 
 Event.add(defines.events.on_tick, on_tick)
diff --git a/modules/wave_defense/commands.lua b/modules/wave_defense/commands.lua
index e8d505a0..bae3a443 100644
--- a/modules/wave_defense/commands.lua
+++ b/modules/wave_defense/commands.lua
@@ -1,44 +1,49 @@
 local Public = require 'modules.wave_defense.table'
 
-if _DEBUG then
-    commands.add_command(
-        'wd_debug_module',
-        '',
-        function(cmd)
-            local player = game.player
-            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 == 'spawn_wave' then
-                return Public.spawn_unit_group(true, true)
-            end
-
-            if param == 'log_all' then
-                return Public.toggle_debug()
-            end
-
-            if param == 'debug_health' then
-                local this = Public.get()
-
-                Public.toggle_debug_health()
-
-                this.next_wave = 1000
-                this.wave_interval = 200
-                this.wave_enforced = true
-                this.debug_only_on_wave_500 = true
-            end
+commands.add_command(
+    'wd_debug_module',
+    '',
+    function(cmd)
+        local player = game.player
+        local param = tostring(cmd.parameter)
+        if param == nil then
+            return
         end
-    )
-end
+
+        if not (player and player.valid) then
+            return
+        end
+
+        if not player.admin then
+            return
+        end
+
+        if param == 'spawn_wave' then
+            return Public.spawn_unit_group(true, true)
+        end
+
+        if param == 'set_next_wave' then
+            for _ = 1, 100 do
+                Public.set_next_wave()
+            end
+            return Public.spawn_unit_group(true, true)
+        end
+
+        if param == 'log_all' then
+            return Public.toggle_debug()
+        end
+
+        if param == 'debug_health' then
+            local this = Public.get()
+
+            Public.toggle_debug_health()
+
+            this.next_wave = 1000
+            this.wave_interval = 200
+            this.wave_enforced = true
+            this.debug_only_on_wave_500 = true
+        end
+    end
+)
 
 return Public
diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua
index 65f871d3..93bd8fed 100644
--- a/modules/wave_defense/main.lua
+++ b/modules/wave_defense/main.lua
@@ -118,7 +118,7 @@ local function remove_trees(entity)
     local area = {{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}}
     local trees = surface.find_entities_filtered {area = area, type = 'tree'}
     if #trees > 0 then
-        for i, tree in pairs(trees) do
+        for _, tree in pairs(trees) do
             if tree and tree.valid then
                 tree.destroy()
             end
@@ -136,7 +136,7 @@ local function remove_rocks(entity)
     local area = {{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}}
     local rocks = surface.find_entities_filtered {area = area, type = 'simple-entity'}
     if #rocks > 0 then
-        for i, rock in pairs(rocks) do
+        for _, rock in pairs(rocks) do
             if rock and rock.valid then
                 rock.destroy()
             end
@@ -1113,10 +1113,10 @@ Event.on_nth_tick(
         local t2 = tick % 18000
 
         if tick_tasks[t] then
-            tick_tasks[t](true)
+            tick_tasks[t]()
         end
         if tick_tasks[t2] then
-            tick_tasks[t2](true)
+            tick_tasks[t2]()
         end
 
         local resolve_pathing = Public.get('resolve_pathing')
@@ -1163,4 +1163,6 @@ Event.on_nth_tick(
     end
 )
 
+Public.set_next_wave = set_next_wave
+
 return Public
diff --git a/modules/wave_defense/threat_events.lua b/modules/wave_defense/threat_events.lua
index 1258c9da..9ff6a5c0 100644
--- a/modules/wave_defense/threat_events.lua
+++ b/modules/wave_defense/threat_events.lua
@@ -109,7 +109,7 @@ local function place_nest_near_unit_group()
     Task.set_timeout_in_ticks(200, immunity_spawner, {entity = spawner})
 
     if boss then
-        BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value)
+        BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
     else
         BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
     end
@@ -206,7 +206,7 @@ function Public.build_worm()
     local modified_boss_unit_health = Public.get('modified_boss_unit_health')
 
     if boss then
-        BiterHealthBooster.add_boss_unit(u, modified_boss_unit_health.current_value)
+        BiterHealthBooster.add_boss_unit(u, modified_boss_unit_health.current_value, 0.5)
     else
         local final_health = round(modified_unit_health.current_value * worm_unit_settings.scale_units_by_health[worm], 3)
         if final_health < 1 then

From 88ca12976941c9b605f2244112a42ace47ab6f32 Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Thu, 12 May 2022 22:21:15 +0200
Subject: [PATCH 02/13] fix movement speed bug

---
 maps/mountain_fortress_v3/functions.lua | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/maps/mountain_fortress_v3/functions.lua b/maps/mountain_fortress_v3/functions.lua
index caa70565..797788c7 100644
--- a/maps/mountain_fortress_v3/functions.lua
+++ b/maps/mountain_fortress_v3/functions.lua
@@ -8,6 +8,7 @@ local Global = require 'utils.global'
 local Alert = require 'utils.alert'
 local WPT = require 'maps.mountain_fortress_v3.table'
 local WD = require 'modules.wave_defense.table'
+local RPG = require 'modules.rpg.main'
 local Collapse = require 'modules.collapse'
 local Difficulty = require 'modules.difficulty_vote_by_amount'
 local ICW_Func = require 'maps.mountain_fortress_v3.icw.functions'
@@ -818,6 +819,8 @@ local retry_final_boost_movement_speed_on_respawn =
         end
         player.character.character_running_speed_modifier = old_speed
         player.print('Movement speed bonus removed!', Color.info)
+        local rpg_t = RPG.get_value_from_player(player.index)
+        rpg_t.has_custom_spell_active = nil
     end
 )
 
@@ -835,6 +838,8 @@ local retry_boost_movement_speed_on_respawn =
         end
         player.character.character_running_speed_modifier = old_speed
         player.print('Movement speed bonus removed!', Color.info)
+        local rpg_t = RPG.get_value_from_player(player.index)
+        rpg_t.has_custom_spell_active = nil
     end
 )
 
@@ -852,6 +857,8 @@ local remove_boost_movement_speed_on_respawn =
         end
         player.character.character_running_speed_modifier = old_speed
         player.print('Movement speed bonus removed!', Color.info)
+        local rpg_t = RPG.get_value_from_player(player.index)
+        rpg_t.has_custom_spell_active = nil
     end
 )
 
@@ -866,6 +873,9 @@ local boost_movement_speed_on_respawn =
             return
         end
 
+        local rpg_t = RPG.get_value_from_player(player.index)
+        rpg_t.has_custom_spell_active = true
+
         local old_speed = player.character_running_speed_modifier
         local new_speed = player.character_running_speed_modifier + 1
 

From 6167ab4ec1bfa09c34bdb2e71d371cc5a95b096d Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Thu, 12 May 2022 22:21:36 +0200
Subject: [PATCH 03/13] fix that buried biters were not scaled with normal wave
 defense module

---
 maps/mountain_fortress_v3/buried_enemies.lua | 119 ++++++++-----------
 1 file changed, 47 insertions(+), 72 deletions(-)

diff --git a/maps/mountain_fortress_v3/buried_enemies.lua b/maps/mountain_fortress_v3/buried_enemies.lua
index 49c2763c..8fea82a8 100644
--- a/maps/mountain_fortress_v3/buried_enemies.lua
+++ b/maps/mountain_fortress_v3/buried_enemies.lua
@@ -1,17 +1,15 @@
 local Event = require 'utils.event'
 local Global = require 'utils.global'
-local BiterRolls = require 'modules.wave_defense.biter_rolls'
 local BiterHealthBooster = require 'modules.biter_health_booster_v2'
 local WD = require 'modules.wave_defense.table'
 local WPT = require 'maps.mountain_fortress_v3.table'
-local Diff = require 'modules.difficulty_vote_by_amount'
 
-local traps = {}
+local this = {}
 
 Global.register(
-    traps,
+    this,
     function(t)
-        traps = t
+        this = t
     end
 )
 
@@ -59,41 +57,10 @@ local function create_particles(data)
     end
 end
 
-local function trigger_health()
-    local wave_number = WD.get('wave_number')
-    local d = Diff.get()
-    local m = 0.0015
-    if d.difficulty_vote_index then
-        if not d.strength_modifier then
-            m = m * 1.05
-        else
-            m = m * d.strength_modifier
-        end
-    end
-
-    local boosted_health = 1.25
-
-    if wave_number <= 10 then
-        wave_number = 10
-    end
-
-    boosted_health = boosted_health * (wave_number * 0.02)
-
-    local sum = boosted_health * 5
-
-    sum = sum + m
-
-    if sum >= 100 then
-        sum = 100
-    end
-
-    return sum
-end
-
 local function spawn_biters(data)
     local surface = data.surface
     if not (surface and surface.valid) then
-        return
+        return false
     end
     local position = data.position
     local h = floor(abs(position.y))
@@ -101,58 +68,66 @@ local function spawn_biters(data)
     local max_biters = WPT.get('biters')
 
     if max_biters.amount >= max_biters.limit then
-        return
+        return false
     end
 
     if not position then
         position = surface.find_non_colliding_position('small-biter', position, 10, 1)
         if not position then
-            return
+            return false
         end
     end
 
-    BiterRolls.wave_defense_set_unit_raffle(h * 0.20)
+    local unit_to_create
 
-    local unit
     if random(1, 3) == 1 then
-        unit = surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = position})
-        max_biters.amount = max_biters.amount + 1
+        unit_to_create = WD.wave_defense_roll_spitter_name()
     else
-        unit = surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position})
-        max_biters.amount = max_biters.amount + 1
+        unit_to_create = WD.wave_defense_roll_biter_name()
     end
 
-    if random(1, 45) == 1 then
-        local sum = trigger_health()
-        BiterHealthBooster.add_unit(unit, sum)
-    elseif random(1, 64) == 1 then
-        local sum = trigger_health()
-        BiterHealthBooster.add_boss_unit(unit, sum, 0.38)
+    local modified_unit_health = WD.get('modified_unit_health')
+    local modified_boss_unit_health = WD.get('modified_boss_unit_health')
+
+    WD.wave_defense_set_unit_raffle(h * 0.20)
+
+    local unit = surface.create_entity({name = unit_to_create, position = position})
+    max_biters.amount = max_biters.amount + 1
+
+    if random(1, 30) == 1 then
+        BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
+    else
+        BiterHealthBooster.add_unit(unit, modified_unit_health.current_value)
     end
+    return true
 end
 
 local function spawn_worms(data)
+    local modified_unit_health = WD.get('modified_unit_health')
+    local modified_boss_unit_health = WD.get('modified_boss_unit_health')
     local max_biters = WPT.get('biters')
 
     if max_biters.amount >= max_biters.limit then
         return
     end
 
+    local unit_to_create = WD.wave_defense_roll_worm_name()
+
     local surface = data.surface
     if not (surface and surface.valid) then
         return
     end
     local position = data.position
-    BiterRolls.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
-    local unit = surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = position})
+
+    WD.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
+
+    local unit = surface.create_entity({name = unit_to_create, position = position})
     max_biters.amount = max_biters.amount + 1
 
-    if random(1, 45) == 1 then
-        local sum = trigger_health()
-        BiterHealthBooster.add_unit(unit, sum)
-    elseif random(1, 64) == 1 then
-        local sum = trigger_health()
-        BiterHealthBooster.add_boss_unit(unit, sum, 0.38)
+    if random(1, 30) == 1 then
+        BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
+    else
+        BiterHealthBooster.add_unit(unit, modified_unit_health.current_value)
     end
 end
 
@@ -171,17 +146,17 @@ function Public.buried_biter(surface, position)
     end
 
     for t = 1, 60, 1 do
-        if not traps[game.tick + t] then
-            traps[game.tick + t] = {}
+        if not this[game.tick + t] then
+            this[game.tick + t] = {}
         end
 
-        traps[game.tick + t][#traps[game.tick + t] + 1] = {
+        this[game.tick + t][#this[game.tick + t] + 1] = {
             callback = 'create_particles',
             data = {surface = surface, position = {x = position.x, y = position.y}, amount = math.ceil(t * 0.05)}
         }
 
         if t == 60 then
-            traps[game.tick + t][#traps[game.tick + t] + 1] = {
+            this[game.tick + t][#this[game.tick + t] + 1] = {
                 callback = 'spawn_biters',
                 data = {surface = surface, position = {x = position.x, y = position.y}}
             }
@@ -204,17 +179,17 @@ function Public.buried_worm(surface, position)
     end
 
     for t = 1, 60, 1 do
-        if not traps[game.tick + t] then
-            traps[game.tick + t] = {}
+        if not this[game.tick + t] then
+            this[game.tick + t] = {}
         end
 
-        traps[game.tick + t][#traps[game.tick + t] + 1] = {
+        this[game.tick + t][#this[game.tick + t] + 1] = {
             callback = 'create_particles',
             data = {surface = surface, position = {x = position.x, y = position.y}, amount = math.ceil(t * 0.05)}
         }
 
         if t == 60 then
-            traps[game.tick + t][#traps[game.tick + t] + 1] = {
+            this[game.tick + t][#this[game.tick + t] + 1] = {
                 callback = 'spawn_worms',
                 data = {surface = surface, position = {x = position.x, y = position.y}}
             }
@@ -230,10 +205,10 @@ local callbacks = {
 
 local function on_tick()
     local t = game.tick
-    if not traps[t] then
+    if not this[t] then
         return
     end
-    for _, token in pairs(traps[t]) do
+    for _, token in pairs(this[t]) do
         local callback = token.callback
         local data = token.data
         local cbl = callbacks[callback]
@@ -241,12 +216,12 @@ local function on_tick()
             cbl(data)
         end
     end
-    traps[t] = nil
+    this[t] = nil
 end
 
 function Public.reset()
-    for k, _ in pairs(traps) do
-        traps[k] = nil
+    for k, _ in pairs(this) do
+        this[k] = nil
     end
 end
 

From 44af53da8cb2021e938ae88eb8120613d0b50865 Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Thu, 12 May 2022 22:21:49 +0200
Subject: [PATCH 04/13] fix that magic required level 51 to work

---
 maps/mountain_fortress_v3/entities.lua | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/maps/mountain_fortress_v3/entities.lua b/maps/mountain_fortress_v3/entities.lua
index 539453ef..642cc05d 100644
--- a/maps/mountain_fortress_v3/entities.lua
+++ b/maps/mountain_fortress_v3/entities.lua
@@ -351,9 +351,13 @@ end
 
 local function hidden_treasure(player, entity)
     local rpg = RPG.get_value_from_player(player.index)
+    if not rpg then
+        return
+    end
+
     local magic = rpg.magicka
 
-    if magic > 50 then
+    if magic >= 50 then
         local msg = rare_treasure_chest_messages[random(1, #rare_treasure_chest_messages)]
         Alert.alert_player(player, 5, msg)
         Loot.add_rare(entity.surface, entity.position, 'wooden-chest', magic)

From f0560c1d27a78fa854045c19160bcca6ebc0537d Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Thu, 12 May 2022 22:22:03 +0200
Subject: [PATCH 05/13] misc fixes

---
 maps/mountain_fortress_v3/terrain.lua | 17 +++++++++++++----
 modules/biter_health_booster_v2.lua   | 23 ++++++++++++-----------
 modules/rpg/main.lua                  | 25 ++++++++++++++-----------
 utils/commands/misc.lua               |  5 +----
 4 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/maps/mountain_fortress_v3/terrain.lua b/maps/mountain_fortress_v3/terrain.lua
index ad0cf790..3c319673 100644
--- a/maps/mountain_fortress_v3/terrain.lua
+++ b/maps/mountain_fortress_v3/terrain.lua
@@ -14,6 +14,15 @@ local ceil = math.ceil
 local zone_settings = WPT.zone_settings
 local worm_level_modifier = 0.19
 
+local start_ground_tiles = {
+    'sand-1',
+    'dirt-1',
+    'dirt-2',
+    'sand-2',
+    'dirt-3',
+    'sand-3'
+}
+
 local wagon_raffle = {
     'cargo-wagon',
     'cargo-wagon',
@@ -2624,7 +2633,7 @@ end
 local function border_chunk(p, data)
     local entities = data.entities
     local decoratives = data.decoratives
-    -- local tiles = data.tiles
+    local tiles = data.tiles
 
     local pos = p
 
@@ -2632,9 +2641,9 @@ local function border_chunk(p, data)
         entities[#entities + 1] = {name = trees[random(1, #trees)], position = pos}
     end
 
-    -- local noise = get_perlin('dungeons', pos, data.seed)
-    -- local index = floor(noise * 32) % 4 + 1
-    -- tiles[#tiles + 1] = {name = start_ground_tiles[index], position = pos}
+    local noise = get_perlin('dungeons', pos, data.seed)
+    local index = floor(noise * 32) % 4 + 1
+    tiles[#tiles + 1] = {name = start_ground_tiles[index], position = pos}
 
     local scrap_mineable_entities, scrap_mineable_entities_index = get_scrap_mineable_entities()
 
diff --git a/modules/biter_health_booster_v2.lua b/modules/biter_health_booster_v2.lua
index 488acfb6..bbc6fa67 100644
--- a/modules/biter_health_booster_v2.lua
+++ b/modules/biter_health_booster_v2.lua
@@ -157,7 +157,7 @@ local function create_entity_radius(surface, name, source, target)
 
     local position = {source.x, source.y}
 
-    for i = 1, distance * 1.5, 1 do
+    for _ = 1, distance * 1.5, 1 do
         if random(1, 2) ~= 1 then
             surface.create_entity(
                 {
@@ -401,7 +401,7 @@ local function on_entity_died(event)
 end
 
 --- Use this function to retrieve a key from the global table.
----@param key <string>
+---@param key string
 function Public.get(key)
     if key then
         return this[key]
@@ -411,8 +411,8 @@ function Public.get(key)
 end
 
 --- Using this function can set a new value to an exist key or create a new key with value
----@param key <string>
----@param value <string/boolean>
+---@param key string
+---@param value any
 function Public.set(key, value)
     if key and (value or value == false) then
         this[key] = value
@@ -442,8 +442,8 @@ function Public.reset_table()
 end
 
 --- Use this function to add a new unit that has extra health
----@param unit <LuaEntity>
----@param health_multiplier <number>
+---@param unit userdata
+---@param health_multiplier number
 function Public.add_unit(unit, health_multiplier)
     if not health_multiplier then
         health_multiplier = this.biter_health_boost
@@ -460,9 +460,9 @@ function Public.add_unit(unit, health_multiplier)
 end
 
 --- Use this function to add a new boss unit (with healthbar)
----@param unit <LuaEntity>
----@param health_multiplier <number>
----@param health_bar_size <number>
+---@param unit userdata
+---@param health_multiplier number
+---@param health_bar_size number
 function Public.add_boss_unit(unit, health_multiplier, health_bar_size)
     if not health_multiplier then
         health_multiplier = this.biter_health_boost
@@ -483,7 +483,7 @@ end
 
 --- This sets the active surface that we check and have the script active.
 --- This deletes the list of surfaces if we use multiple, so use it only before setting more of them.
----@param string
+---@param str string
 function Public.set_active_surface(str)
     if str and type(str) == 'string' then
         this.active_surfaces = {}
@@ -493,7 +493,8 @@ function Public.set_active_surface(str)
 end
 
 --- This sets if this surface is active, when we using multiple surfaces. The default active surface does not need to be added again
----@param string, boolean
+---@param name string
+---@param value boolean
 function Public.set_surface_activity(name, value)
     if name and type(name) == 'string' and type(value) == 'boolean' then
         this.active_surfaces[name] = value
diff --git a/modules/rpg/main.lua b/modules/rpg/main.lua
index 1ab4660c..1324a470 100644
--- a/modules/rpg/main.lua
+++ b/modules/rpg/main.lua
@@ -29,7 +29,7 @@ local function on_gui_click(event)
     if not event then
         return
     end
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
     if not (player and player.valid) then
         return
     end
@@ -369,6 +369,9 @@ local function regen_mana_player(players)
         local mana_per_tick = Public.get_mana_modifier(player)
         local rpg_extra = Public.get('rpg_extra')
         local rpg_t = Public.get_value_from_player(player.index)
+        if not rpg_t then
+            return
+        end
         if mana_per_tick <= 0.1 then
             mana_per_tick = rpg_extra.mana_per_tick
         end
@@ -568,7 +571,7 @@ local function on_player_repaired_entity(event)
         return
     end
 
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
 
     if not player or not player.valid or not player.character then
         return
@@ -585,7 +588,7 @@ local function on_player_repaired_entity(event)
 end
 
 local function on_player_rotated_entity(event)
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
 
     if not player or not player.valid then
         return
@@ -603,7 +606,7 @@ local function on_player_rotated_entity(event)
 end
 
 local function on_player_changed_position(event)
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
     if not player or not player.valid then
         return
     end
@@ -627,7 +630,7 @@ local building_and_mining_blacklist = {
 }
 
 local function on_player_died(event)
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
 
     if not player or not player.valid then
         return
@@ -637,7 +640,7 @@ local function on_player_died(event)
 end
 
 local function on_pre_player_left_game(event)
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
 
     if not player or not player.valid then
         return
@@ -657,7 +660,7 @@ local function on_pre_player_mined_item(event)
     if entity.force.index ~= 3 then
         return
     end
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
 
     if not player or not player.valid then
         return
@@ -702,7 +705,7 @@ local function on_player_crafted_item(event)
     if not event.recipe.energy then
         return
     end
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
     if not player or not player.valid then
         return
     end
@@ -735,7 +738,7 @@ local function on_player_crafted_item(event)
 end
 
 local function on_player_respawned(event)
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
     local rpg_t = Public.get_value_from_player(player.index)
     if not rpg_t then
         Public.rpg_reset_player(player)
@@ -748,7 +751,7 @@ local function on_player_respawned(event)
 end
 
 local function on_player_joined_game(event)
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
     local rpg_t = Public.get_value_from_player(player.index)
     local rpg_extra = Public.get('rpg_extra')
     if not rpg_t then
@@ -851,7 +854,7 @@ local function on_player_used_capsule(event)
     local conjure_items = Public.all_spells
     local projectile_types = Public.get_projectiles
 
-    local player = game.players[event.player_index]
+    local player = game.get_player(event.player_index)
     if not player or not player.valid then
         return
     end
diff --git a/utils/commands/misc.lua b/utils/commands/misc.lua
index c7fd5a40..f7397c87 100644
--- a/utils/commands/misc.lua
+++ b/utils/commands/misc.lua
@@ -239,10 +239,7 @@ commands.add_command(
         end
         if not this.creative_are_you_sure then
             this.creative_are_you_sure = true
-            player.print(
-                '[WARNING] This command will enable creative/cheat-mode for all connected players, run this command again if you really want to do this!',
-                Color.yellow
-            )
+            player.print('[WARNING] This command will enable creative/cheat-mode for all connected players, run this command again if you really want to do this!', Color.yellow)
             return
         end
         if this.creative_enabled then

From c2d272e8bbba58fc4ffb6d75f90fe1700dbd52c1 Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Sat, 14 May 2022 19:15:51 +0200
Subject: [PATCH 06/13] Collapse fix

---
 maps/mountain_fortress_v2/main.lua |   2 +-
 maps/mountain_fortress_v3/main.lua |   4 +-
 maps/mountain_race/main.lua        |   3 +-
 modules/collapse.lua               | 197 ++++++++++++++++++-----------
 4 files changed, 126 insertions(+), 80 deletions(-)

diff --git a/maps/mountain_fortress_v2/main.lua b/maps/mountain_fortress_v2/main.lua
index b89df14e..ba3610c2 100644
--- a/maps/mountain_fortress_v2/main.lua
+++ b/maps/mountain_fortress_v2/main.lua
@@ -192,7 +192,7 @@ function Public.reset_map()
     Collapse.set_speed(8)
     Collapse.set_amount(1)
     Collapse.set_max_line_size(level_depth)
-    Collapse.set_surface(surface)
+    Collapse.set_surface_index(surface.index)
     Collapse.set_position({0, 130})
     Collapse.set_direction('north')
 
diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua
index 29a5ddfb..36547bd0 100644
--- a/maps/mountain_fortress_v3/main.lua
+++ b/maps/mountain_fortress_v3/main.lua
@@ -82,7 +82,7 @@ local collapse_kill = {
         ['flamethrower-turret'] = true,
         ['gun-turret'] = true,
         ['artillery-turret'] = true,
-        ['landmine'] = true,
+        ['land-mine'] = true,
         ['locomotive'] = true,
         ['cargo-wagon'] = true,
         ['character'] = true,
@@ -253,7 +253,7 @@ function Public.reset_map()
     Collapse.set_amount(1)
     -- Collapse.set_max_line_size(zone_settings.zone_width)
     Collapse.set_max_line_size(540)
-    Collapse.set_surface(surface)
+    Collapse.set_surface_index(surface.index)
     Collapse.set_position({0, 130})
     Collapse.set_direction('north')
     Collapse.start_now(false)
diff --git a/maps/mountain_race/main.lua b/maps/mountain_race/main.lua
index 3bc128a9..228af0c9 100644
--- a/maps/mountain_race/main.lua
+++ b/maps/mountain_race/main.lua
@@ -136,9 +136,10 @@ local function init(mountain_race)
     Collapse.set_speed(8)
     Collapse.set_amount(0)
     Collapse.set_max_line_size(mountain_race.border_width + mountain_race.playfield_height * 2)
-    Collapse.set_surface(surface)
+    Collapse.set_surface_index(surface.index)
     Collapse.set_position({0, 0})
     Collapse.set_direction('east')
+    Collapse.start_now(true)
 
     game.reset_time_played()
 
diff --git a/modules/collapse.lua b/modules/collapse.lua
index 61150bf2..6b11b720 100644
--- a/modules/collapse.lua
+++ b/modules/collapse.lua
@@ -1,60 +1,97 @@
+local Event = require 'utils.event'
 local Global = require 'utils.global'
 local Public = {}
 
 local math_floor = math.floor
 local table_shuffle_table = table.shuffle_table
 
-local collapse = {
+local this = {
     debug = false
 }
 Global.register(
-    collapse,
+    this,
     function(tbl)
-        collapse = tbl
+        this = tbl
     end
 )
 
 local directions = {
     ['north'] = function(position)
-        local width = collapse.surface.map_gen_settings.width
-        if width > collapse.max_line_size then
-            width = collapse.max_line_size
+        local surface_index = this.surface_index
+        if not surface_index then
+            return
+        end
+
+        local surface = game.get_surface(surface_index)
+        if not surface.valid then
+            return
+        end
+        local width = surface.map_gen_settings.width
+        if width > this.max_line_size then
+            width = this.max_line_size
         end
         local a = width * 0.5 + 1
-        collapse.vector = {0, -1}
-        collapse.area = {{position.x - a, position.y - 1}, {position.x + a, position.y}}
+        this.vector = {0, -1}
+        this.area = {{position.x - a, position.y - 1}, {position.x + a, position.y}}
     end,
     ['south'] = function(position)
-        local width = collapse.surface.map_gen_settings.width
-        if width > collapse.max_line_size then
-            width = collapse.max_line_size
+        local surface_index = this.surface_index
+        if not surface_index then
+            return
+        end
+
+        local surface = game.get_surface(surface_index)
+        if not surface.valid then
+            return
+        end
+        local width = surface.map_gen_settings.width
+        if width > this.max_line_size then
+            width = this.max_line_size
         end
         local a = width * 0.5 + 1
-        collapse.vector = {0, 1}
-        collapse.area = {{position.x - a, position.y}, {position.x + a, position.y + 1}}
+        this.vector = {0, 1}
+        this.area = {{position.x - a, position.y}, {position.x + a, position.y + 1}}
     end,
     ['west'] = function(position)
-        local width = collapse.surface.map_gen_settings.height
-        if width > collapse.max_line_size then
-            width = collapse.max_line_size
+        local surface_index = this.surface_index
+        if not surface_index then
+            return
+        end
+
+        local surface = game.get_surface(surface_index)
+        if not surface.valid then
+            return
+        end
+        local width = surface.map_gen_settings.height
+        if width > this.max_line_size then
+            width = this.max_line_size
         end
         local a = width * 0.5 + 1
-        collapse.vector = {-1, 0}
-        collapse.area = {{position.x - 1, position.y - a}, {position.x, position.y + a}}
+        this.vector = {-1, 0}
+        this.area = {{position.x - 1, position.y - a}, {position.x, position.y + a}}
     end,
     ['east'] = function(position)
-        local width = collapse.surface.map_gen_settings.height
-        if width > collapse.max_line_size then
-            width = collapse.max_line_size
+        local surface_index = this.surface_index
+        if not surface_index then
+            return
+        end
+
+        local surface = game.get_surface(surface_index)
+        if not surface.valid then
+            return
+        end
+        local width = surface.map_gen_settings.height
+        if width > this.max_line_size then
+            width = this.max_line_size
         end
         local a = width * 0.5 + 1
-        collapse.vector = {1, 0}
-        collapse.area = {{position.x, position.y - a}, {position.x + 1, position.y + a}}
+        this.vector = {1, 0}
+        this.area = {{position.x, position.y - a}, {position.x + 1, position.y + a}}
     end
 }
 
 local function print_debug(a)
-    if not collapse.debug then
+    if not this.debug then
         return
     end
     print('Collapse error #' .. a)
@@ -64,52 +101,60 @@ local function set_collapse_tiles(surface)
     if not surface or surface.valid then
         print_debug(45)
     end
-    game.forces.player.chart(surface, collapse.area)
-    collapse.tiles = surface.find_tiles_filtered({area = collapse.area})
-    if not collapse.tiles then
+    game.forces.player.chart(surface, this.area)
+    this.tiles = surface.find_tiles_filtered({area = this.area})
+    if not this.tiles then
         return
     end
-    collapse.size_of_tiles = #collapse.tiles
-    if collapse.size_of_tiles > 0 then
-        table_shuffle_table(collapse.tiles)
+    this.size_of_tiles = #this.tiles
+    if this.size_of_tiles > 0 then
+        table_shuffle_table(this.tiles)
     end
-    collapse.position = {x = collapse.position.x + collapse.vector[1], y = collapse.position.y + collapse.vector[2]}
-    local v = collapse.vector
-    local area = collapse.area
-    collapse.area = {{area[1][1] + v[1], area[1][2] + v[2]}, {area[2][1] + v[1], area[2][2] + v[2]}}
-    game.forces.player.chart(surface, collapse.area)
+    this.position = {x = this.position.x + this.vector[1], y = this.position.y + this.vector[2]}
+    local v = this.vector
+    local area = this.area
+    this.area = {{area[1][1] + v[1], area[1][2] + v[2]}, {area[2][1] + v[1], area[2][2] + v[2]}}
+    game.forces.player.chart(surface, this.area)
 end
 
 local function progress()
-    local surface = collapse.surface
-
-    if not collapse.start_now then
-        collapse.tiles = nil
+    local surface_index = this.surface_index
+    if not surface_index then
         return
     end
 
-    local tiles = collapse.tiles
+    local surface = game.get_surface(surface_index)
+    if not surface.valid then
+        return
+    end
+
+    if not this.start_now then
+        this.tiles = nil
+        return
+    end
+
+    local tiles = this.tiles
     if not tiles then
         set_collapse_tiles(surface)
-        tiles = collapse.tiles
+        tiles = this.tiles
     end
     if not tiles then
         return
     end
 
-    for _ = 1, collapse.amount, 1 do
-        local tile = tiles[collapse.size_of_tiles]
+    for _ = 1, this.amount, 1 do
+        local tile = tiles[this.size_of_tiles]
         if not tile then
-            collapse.tiles = nil
+            this.tiles = nil
             return
         end
-        collapse.size_of_tiles = collapse.size_of_tiles - 1
+        this.size_of_tiles = this.size_of_tiles - 1
         if not tile.valid then
             return
         end
-        if collapse.specific_entities.enabled then
+        if this.specific_entities.enabled then
             local position = {tile.position.x + 0.5, tile.position.y + 0.5}
-            local entities = collapse.specific_entities.entities
+            local entities = this.specific_entities.entities
             for _, e in pairs(surface.find_entities_filtered({area = {{position[1] - 2, position[2] - 2}, {position[1] + 2, position[2] + 2}}})) do
                 if entities[e.name] and e.valid and e.health then
                     e.die()
@@ -118,7 +163,7 @@ local function progress()
                 end
             end
         end
-        if collapse.kill then
+        if this.kill then
             local position = {tile.position.x + 0.5, tile.position.y + 0.5}
             for _, e in pairs(surface.find_entities_filtered({area = {{position[1] - 2, position[2] - 2}, {position[1] + 2, position[2] + 2}}})) do
                 if e.valid and e.health then
@@ -130,20 +175,19 @@ local function progress()
     end
 end
 
-function Public.set_surface(surface)
-    if not surface then
+function Public.set_surface_index(surface_index)
+    if not surface_index then
         print_debug(1)
         return
     end
+
+    local surface = game.get_surface(surface_index)
     if not surface.valid then
         print_debug(2)
         return
     end
-    if not game.surfaces[surface.index] then
-        print_debug(3)
-        return
-    end
-    collapse.surface = surface
+
+    this.surface_index = surface_index
 end
 
 function Public.set_direction(direction)
@@ -151,7 +195,7 @@ function Public.set_direction(direction)
         print_debug(11)
         return
     end
-    directions[direction](collapse.position)
+    directions[direction](this.position)
 end
 
 function Public.set_speed(speed)
@@ -163,7 +207,7 @@ function Public.set_speed(speed)
     if speed < 1 then
         speed = 1
     end
-    collapse.speed = speed
+    this.speed = speed
 end
 
 function Public.set_amount(amount)
@@ -175,7 +219,7 @@ function Public.set_amount(amount)
     if amount < 0 then
         amount = 0
     end
-    collapse.amount = amount
+    this.amount = amount
 end
 
 function Public.set_position(position)
@@ -205,28 +249,28 @@ function Public.set_position(position)
     if position.y then
         y = position.y
     end
-    collapse.position = {x = x, y = y}
+    this.position = {x = x, y = y}
 end
 
 function Public.get_position()
-    return collapse.position
+    return this.position
 end
 
 function Public.get_amount()
-    return collapse.amount
+    return this.amount
 end
 
 function Public.get_speed()
-    return collapse.speed
+    return this.speed
 end
 
 function Public.start_now(status)
     if status == true then
-        collapse.start_now = true
+        this.start_now = true
     elseif status == false then
-        collapse.start_now = false
+        this.start_now = false
     end
-    return collapse.start_now
+    return this.start_now
 end
 
 function Public.set_max_line_size(size)
@@ -239,44 +283,45 @@ function Public.set_max_line_size(size)
         print_debug(21)
         return
     end
-    collapse.max_line_size = size
+    this.max_line_size = size
 end
 
 function Public.set_kill_entities(a)
-    collapse.kill = a
+    this.kill = a
 end
 
 function Public.set_kill_specific_entities(tbl)
     if tbl then
-        collapse.specific_entities = tbl
+        this.specific_entities = tbl
     else
-        collapse.specific_entities = {
+        this.specific_entities = {
             enabled = false
         }
     end
 end
 
 local function on_init()
-    Public.set_surface(game.surfaces.nauvis)
+    Public.set_surface_index(game.surfaces.nauvis.index)
     Public.set_position({0, 32})
     Public.set_max_line_size(256)
     Public.set_direction('north')
     Public.set_kill_entities(true)
     Public.set_kill_specific_entities()
-    collapse.tiles = nil
-    collapse.speed = 1
-    collapse.amount = 8
-    collapse.start_now = true
+    this.tiles = nil
+    this.speed = 1
+    this.amount = 8
+    this.start_now = false
 end
 
 local function on_tick()
-    if game.tick % collapse.speed ~= 0 then
+    local tick = game.tick
+    if tick % this.speed ~= 0 then
         return
     end
+
     progress()
 end
 
-local Event = require 'utils.event'
 Event.on_init(on_init)
 Event.add(defines.events.on_tick, on_tick)
 

From f121bbd8cabb144817e94812f9d089f37b32d309 Mon Sep 17 00:00:00 2001
From: hanakocz <hanakocz@users.noreply.github.com>
Date: Sun, 15 May 2022 00:55:36 +0200
Subject: [PATCH 07/13] module to set requests in logi chests to blueprint
 total costs

---
 modules/blueprint_requesting.lua | 34 ++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 modules/blueprint_requesting.lua

diff --git a/modules/blueprint_requesting.lua b/modules/blueprint_requesting.lua
new file mode 100644
index 00000000..de71ac3c
--- /dev/null
+++ b/modules/blueprint_requesting.lua
@@ -0,0 +1,34 @@
+--module by Hanakocz
+local Event = require 'utils.event'
+
+local function on_gui_closed(event)
+    local entity = event.entity
+    if not entity or not entity.valid then return end
+    if entity.name == 'logistic-chest-requester' or entity.name == 'logistic-chest-buffer' then
+        local inventory = entity.get_inventory(defines.inventory.chest)
+        if not inventory or not inventory.valid then return end
+        if inventory.get_item_count('blueprint') > 0 then
+            local items = {}
+            for i = 1, #inventory, 1 do
+                if inventory[i].valid_for_read and inventory[i].is_blueprint then
+                    local cost = inventory[i].cost_to_build
+                    for name, amount in pairs(cost) do
+                        items[name] = (items[name] or 0) + amount
+                    end
+                end
+            end
+            if entity.request_slot_count > 0 then
+                for slot = 1, entity.request_slot_count, 1 do
+                    entity.clear_request_slot(slot)
+                end
+            end
+            local slot_index = 1
+            for item, amount in pairs(items) do
+                entity.set_request_slot({name = item, count = amount}, slot_index)
+                slot_index = slot_index + 1
+            end
+        end
+    end
+end
+
+Event.add(defines.events.on_gui_closed, on_gui_closed)

From 8d5c00512e32c5f2cae34c225043757f7434f9a6 Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Sun, 15 May 2022 01:24:16 +0200
Subject: [PATCH 08/13] mtn v3 - fix cheesing

---
 maps/mountain_fortress_v3/locomotive.lua | 46 ++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/maps/mountain_fortress_v3/locomotive.lua b/maps/mountain_fortress_v3/locomotive.lua
index a147d7aa..ec10df46 100644
--- a/maps/mountain_fortress_v3/locomotive.lua
+++ b/maps/mountain_fortress_v3/locomotive.lua
@@ -27,6 +27,12 @@ local clear_items_upon_surface_entry = {
     ['substation'] = true
 }
 
+local valid_armors = {
+    ['modular-armor'] = true,
+    ['power-armor'] = true,
+    ['power-armor-mk2'] = true
+}
+
 local function add_random_loot_to_main_market(rarity)
     local main_market_items = WPT.get('main_market_items')
     local items = Market.get_random_item(rarity, true, false)
@@ -247,6 +253,45 @@ local function set_carriages()
     WPT.set('carriages', locomotive.train.carriages)
 end
 
+local function get_driver_action(entity)
+    if not entity or not entity.valid then
+        return
+    end
+
+    local driver = entity.get_driver()
+    if not driver or not driver.valid then
+        return
+    end
+
+    local player = driver.player
+    if not player or not player.valid then
+        return
+    end
+
+    if player.cursor_stack and player.cursor_stack.valid_for_read and player.cursor_stack.name == 'raw-fish' then
+        player.print('[color=blue][Locomotive][/color] Unequip your fishy if you want to drive.')
+        driver.driving = false
+        return
+    end
+
+    local weapon = driver.get_inventory(defines.inventory.character_guns)
+    if weapon then
+        for i = 1, 3 do
+            if weapon[i] and weapon[i].valid_for_read then
+                player.print('[color=blue][Locomotive][/color] Unequip your weapon if you want to drive.')
+                driver.driving = false
+                return
+            end
+        end
+    end
+
+    local armor = driver.get_inventory(defines.inventory.character_armor)
+    if armor and armor[1] and armor[1].valid_for_read and valid_armors[armor[1].name] then
+        player.print('[color=blue][Locomotive][/color] Unequip your armor if you want to drive.')
+        driver.driving = false
+    end
+end
+
 local function set_locomotive_health()
     local locomotive_health = WPT.get('locomotive_health')
     local locomotive_max_health = WPT.get('locomotive_max_health')
@@ -265,6 +310,7 @@ local function set_locomotive_health()
                 if not (entity and entity.valid) then
                     return
                 end
+                get_driver_action(entity)
                 local cargo_health = 600
                 if entity.type == 'locomotive' then
                     entity.health = 1000 * m

From 82f00a4a3e8d6af174b82627d2693882e193d836 Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Sun, 15 May 2022 02:20:06 +0200
Subject: [PATCH 09/13] mtn v3 - fix minor issue

---
 maps/mountain_fortress_v3/locomotive.lua | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/maps/mountain_fortress_v3/locomotive.lua b/maps/mountain_fortress_v3/locomotive.lua
index ec10df46..36e989aa 100644
--- a/maps/mountain_fortress_v3/locomotive.lua
+++ b/maps/mountain_fortress_v3/locomotive.lua
@@ -274,17 +274,6 @@ local function get_driver_action(entity)
         return
     end
 
-    local weapon = driver.get_inventory(defines.inventory.character_guns)
-    if weapon then
-        for i = 1, 3 do
-            if weapon[i] and weapon[i].valid_for_read then
-                player.print('[color=blue][Locomotive][/color] Unequip your weapon if you want to drive.')
-                driver.driving = false
-                return
-            end
-        end
-    end
-
     local armor = driver.get_inventory(defines.inventory.character_armor)
     if armor and armor[1] and armor[1].valid_for_read and valid_armors[armor[1].name] then
         player.print('[color=blue][Locomotive][/color] Unequip your armor if you want to drive.')

From 50469c804bcc1e26855c05f9c737bc436a7b455e Mon Sep 17 00:00:00 2001
From: hanakocz <hanakocz@users.noreply.github.com>
Date: Mon, 16 May 2022 01:02:25 +0200
Subject: [PATCH 10/13] bp requesting - player can disable the feature in
 config menu

---
 control.lua                      |  1 +
 locale/en/modules.cfg            |  4 ++++
 modules/blueprint_requesting.lua | 29 +++++++++++++++++++++++++++++
 utils/gui/config.lua             | 23 +++++++++++++++++++++++
 4 files changed, 57 insertions(+)

diff --git a/control.lua b/control.lua
index db3cb2c0..14b826b9 100644
--- a/control.lua
+++ b/control.lua
@@ -27,6 +27,7 @@ require 'modules.floaty_chat'
 require 'modules.show_inventory'
 require 'modules.inserter_drops_pickup'
 require 'modules.autostash'
+require 'modules.blueprint_requesting'
 
 require 'utils.gui'
 require 'utils.gui.player_list'
diff --git a/locale/en/modules.cfg b/locale/en/modules.cfg
index 176988ff..bf2c00a2 100644
--- a/locale/en/modules.cfg
+++ b/locale/en/modules.cfg
@@ -21,6 +21,10 @@ turret_filler_label_amount=Amount:
 turret_filler_ammo_type=Select Ammo:
 turret_filler_ammo_lower=Enable lower tiers?
 
+blueprint_requesting=Blueprint Requesting
+blueprint_requesting_desc=When placing blueprints into logistic requester or buffer chest, the chest requests will be overwritten to match the blueprint costs.
+blueprint_requesting_notify=This server has Blueprint Requesting feature enabled. Placing blueprints into logistic requester or buffer chests will match the requests to the blueprint costs. You can disable this feature for you in Comfy menu -> Config tab.
+
 [modules_towny]
 map_info=__1__\n\n__2__\n\n__3__\n\n__4__\n\n__5__
 map_info1=To ally or settle with another town, drop a fish on their market or character. (Default Hotkey Z)\nThey will have to do the same to you to complete the request.\nCoal yields the opposite result, as it will make foes or banish settlers.
diff --git a/modules/blueprint_requesting.lua b/modules/blueprint_requesting.lua
index de71ac3c..276b880b 100644
--- a/modules/blueprint_requesting.lua
+++ b/modules/blueprint_requesting.lua
@@ -1,10 +1,29 @@
 --module by Hanakocz
 local Event = require 'utils.event'
+local Global = require 'utils.global'
+local Public = {}
+
+local this = {}
+
+Global.register(
+    this,
+    function(tbl)
+        this = tbl
+    end
+)
 
 local function on_gui_closed(event)
+    local player_index = event.player_index
+    if this[player_index] and this[player_index].disabled then return end -- player disabled usage of this module in config tab for his actions
     local entity = event.entity
     if not entity or not entity.valid then return end
     if entity.name == 'logistic-chest-requester' or entity.name == 'logistic-chest-buffer' then
+        if not this[player_index] or not this[player_index].notified then
+            local player = game.get_player(player_index)
+            player.print({'modules.blueprint_requesting_notify'}, {r= 0.88, g = 0.66, b = 0.02})
+            this[player_index] = this[player_index] or {}
+            this[player_index].notified = true
+        end
         local inventory = entity.get_inventory(defines.inventory.chest)
         if not inventory or not inventory.valid then return end
         if inventory.get_item_count('blueprint') > 0 then
@@ -31,4 +50,14 @@ local function on_gui_closed(event)
     end
 end
 
+function Public.get(key)
+    if key then
+        return this[key]
+    else
+        return this
+    end
+end
+
 Event.add(defines.events.on_gui_closed, on_gui_closed)
+
+return Public
diff --git a/utils/gui/config.lua b/utils/gui/config.lua
index f261c157..1d8966aa 100644
--- a/utils/gui/config.lua
+++ b/utils/gui/config.lua
@@ -126,6 +126,18 @@ local functions = {
             game.get_player(event.player_index).spectator = false
         end
     end,
+    ['blueprint_requesting'] = function(event)
+        local BPRequests = is_loaded('modules.blueprint_requesting')
+        local Module = BPRequests.get()
+        if not Module[event.player_index] then
+            Module[event.player_index] = {}
+        end
+        if event.element.switch_state == 'left' then
+            Module[event.player_index].disabled = false
+        else
+            Module[event.player_index].disabled = true
+        end
+    end,
     ['bottom_location'] = function(event)
         local player = game.get_player(event.player_index)
         if event.element.switch_state == 'left' then
@@ -448,6 +460,17 @@ local function build_config_gui(data)
         scroll_pane.add({type = 'line'})
     end
 
+    local BPRequests = is_loaded('modules.blueprint_requesting')
+    if BPRequests then
+        local Module = BPRequests.get()
+        switch_state = 'left'
+        if Module[player.index] and Module[player.index].disabled then
+            switch_state = 'right'
+        end
+        add_switch(scroll_pane, switch_state, 'blueprint_requesting', {'modules.blueprint_requesting'}, {'modules.blueprint_requesting_desc'})
+        scroll_pane.add({type = 'line'})
+    end
+
     if BottomFrame.is_custom_buttons_enabled() then
         label = scroll_pane.add({type = 'label', caption = 'Bottom Buttons Settings'})
         label.style.font = 'default-bold'

From 7ebe7a706570ffd1b841b0a09e0f48753dd91522 Mon Sep 17 00:00:00 2001
From: hanakocz <hanakocz@users.noreply.github.com>
Date: Mon, 16 May 2022 02:22:05 +0200
Subject: [PATCH 11/13] minor change in lang

---
 locale/en/modules.cfg | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/locale/en/modules.cfg b/locale/en/modules.cfg
index bf2c00a2..fc47fb2a 100644
--- a/locale/en/modules.cfg
+++ b/locale/en/modules.cfg
@@ -22,8 +22,8 @@ turret_filler_ammo_type=Select Ammo:
 turret_filler_ammo_lower=Enable lower tiers?
 
 blueprint_requesting=Blueprint Requesting
-blueprint_requesting_desc=When placing blueprints into logistic requester or buffer chest, the chest requests will be overwritten to match the blueprint costs.
-blueprint_requesting_notify=This server has Blueprint Requesting feature enabled. Placing blueprints into logistic requester or buffer chests will match the requests to the blueprint costs. You can disable this feature for you in Comfy menu -> Config tab.
+blueprint_requesting_desc=Placing blueprints into [entity=logistic-chest-requester] or [entity=logistic-chest-buffer], the chest requests will be overwritten to match the blueprint costs.
+blueprint_requesting_notify=This server has Blueprint Requesting feature enabled. Placing blueprints into [entity=logistic-chest-requester] or [entity=logistic-chest-buffer] will match the requests to the blueprint costs. You can disable this feature for yourself in Comfy menu -> Config.
 
 [modules_towny]
 map_info=__1__\n\n__2__\n\n__3__\n\n__4__\n\n__5__

From ee2627d16b1abf960766bc59faf1ea7e0ebc56f2 Mon Sep 17 00:00:00 2001
From: hanakocz <hanakocz@users.noreply.github.com>
Date: Mon, 16 May 2022 02:23:59 +0200
Subject: [PATCH 12/13] more lang fixes

---
 locale/en/modules.cfg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/locale/en/modules.cfg b/locale/en/modules.cfg
index fc47fb2a..c92df419 100644
--- a/locale/en/modules.cfg
+++ b/locale/en/modules.cfg
@@ -22,7 +22,7 @@ turret_filler_ammo_type=Select Ammo:
 turret_filler_ammo_lower=Enable lower tiers?
 
 blueprint_requesting=Blueprint Requesting
-blueprint_requesting_desc=Placing blueprints into [entity=logistic-chest-requester] or [entity=logistic-chest-buffer], the chest requests will be overwritten to match the blueprint costs.
+blueprint_requesting_desc=Placing blueprints into [entity=logistic-chest-requester] or [entity=logistic-chest-buffer] will set the chest requests to match the blueprint costs. Happens when chest is closed.
 blueprint_requesting_notify=This server has Blueprint Requesting feature enabled. Placing blueprints into [entity=logistic-chest-requester] or [entity=logistic-chest-buffer] will match the requests to the blueprint costs. You can disable this feature for yourself in Comfy menu -> Config.
 
 [modules_towny]

From 30a6264041942f2d6cdce2a8e0e4be3ccb080b49 Mon Sep 17 00:00:00 2001
From: Gerkiz <fs@nvfs.se>
Date: Fri, 20 May 2022 10:33:11 +0200
Subject: [PATCH 13/13] rpg - minor fix

---
 modules/rpg/spells.lua | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/modules/rpg/spells.lua b/modules/rpg/spells.lua
index a5cadb67..b1173fbe 100644
--- a/modules/rpg/spells.lua
+++ b/modules/rpg/spells.lua
@@ -98,6 +98,10 @@ local restore_movement_speed_token =
             return
         end
 
+        if not player.character or not player.character.valid then
+            return
+        end
+
         player.character.character_running_speed_modifier = old_speed
     end
 )