1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-05-13 21:56:29 +02:00

Merge branch 'develop' into journey1.9

This commit is contained in:
hanakocz 2023-06-19 01:05:42 +02:00 committed by GitHub
commit e957442425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 641 additions and 410 deletions

View File

@ -33,9 +33,9 @@
-------------------------------------------------------------------------------
--[Set Defaults]--
-------------------------------------------------------------------------------
local LINE_LENGTH = false -- It is 2017 limits on length are a waste
local IGNORE = {'21./%w+_$', '21./^_%w+$', '213/[ijk]', '213/index', '213/key'}
local NOT_GLOBALS = {'coroutine', 'io', 'socket', 'dofile', 'loadfile'} -- These globals are not available to the factorio API
local LINE_LENGTH = false -- It is 2017 limits on length are a waste
local IGNORE = { '21./%w+_$', '21./^_%w+$', '213/[ijk]', '213/index', '213/key' }
local NOT_GLOBALS = { 'coroutine', 'io', 'socket', 'dofile', 'loadfile' } -- These globals are not available to the factorio API
local STD_CONTROL = 'lua52c+factorio+factorio_control+stdlib+factorio_defines'
local STD_DATA = 'lua52c+factorio+factorio_data+stdlib+stdlib_data+factorio_defines'
@ -51,6 +51,8 @@ std = STD_CONTROL
globals = {
'print',
'_DEBUG',
'_PROFILE',
'_PROFILE_ON_INIT',
'_CHEATS',
'_DUMP_ENV',
'ServerCommands',
@ -59,6 +61,7 @@ globals = {
'_STAGE',
'get_game_version',
'is_loaded',
'is_loaded_bool',
'is_game_modded',
'is_mod_loaded',
'require'
@ -104,32 +107,35 @@ files['**/settings/'].std = STD_DATA
local base_scenarios = {
std = STD_BASE_CONTROL .. '+factorio_base_scenarios+factorio_base_story',
--ignore = {'212/event', '111', '112', '113', '211', '212', '213', '311', '411', '412', '421', '422', '423', '431', '432', '512'}
ignore = {'...'}
ignore = { '...' }
}
files['**/base/scenarios/'] = base_scenarios
files['**/base/tutorials/'] = base_scenarios
files['**/base/campaigns/'] = base_scenarios
files['**/wip-scenario/'] = base_scenarios
files['**/base/migrations/'] = {std = STD_BASE_CONTROL}
files['**/base/migrations/'] = { std = STD_BASE_CONTROL }
files['**/core/lualib/'] = {std = STD_BASE_CONTROL}
files['**/core/lualib/util.lua'] = {globals = {'util', 'table'}, ignore = {'432/object'}}
files['**/core/lualib/silo-script.lua'] = {globals = {'silo_script'}, ignore = {'4../player'}}
files['**/core/lualib/production-score.lua'] = {globals = {'production_score', 'get_price_recursive'}, ignore = {'4../player'}}
files['**/core/lualib/story*'] = {std = '+factorio_base_story', ignore = {'42./k', '42./filter'}}
files['**/core/lualib/mod-gui.lua'] = {globals = {'mod_gui'}}
files['**/core/lualib/camera.lua'] = {globals = {'camera'}}
files['**/core/lualib/builder.lua'] = {globals = {'Builder', 'builder', 'action', 'down', 'right'}}
files['**/core/lualib/'] = { std = STD_BASE_CONTROL }
files['**/core/lualib/util.lua'] = { globals = { 'util', 'table' }, ignore = { '432/object' } }
files['**/core/lualib/silo-script.lua'] = { globals = { 'silo_script' }, ignore = { '4../player' } }
files['**/core/lualib/production-score.lua'] = {
globals = { 'production_score', 'get_price_recursive' },
ignore = { '4../player' }
}
files['**/core/lualib/story*'] = { std = '+factorio_base_story', ignore = { '42./k', '42./filter' } }
files['**/core/lualib/mod-gui.lua'] = { globals = { 'mod_gui' } }
files['**/core/lualib/camera.lua'] = { globals = { 'camera' } }
files['**/core/lualib/builder.lua'] = { globals = { 'Builder', 'builder', 'action', 'down', 'right' } }
files['**/core/lualib/bonus-gui-ordering/'] = {std = STD_BASE_DATA}
files['**/core/lualib/dataloader.lua'] = {globals = {'data'}}
files['**/core/lualib/circuit-connector-*'] = {std = STD_BASE_DATA .. '+factorio_circuit_connector_generated'}
files['**/core/lualib/bonus-gui-ordering.lua'] = {globals = {'bonus_gui_ordering'}}
files['**/core/lualib/bonus-gui-ordering/'] = { std = STD_BASE_DATA }
files['**/core/lualib/dataloader.lua'] = { globals = { 'data' } }
files['**/core/lualib/circuit-connector-*'] = { std = STD_BASE_DATA .. '+factorio_circuit_connector_generated' }
files['**/core/lualib/bonus-gui-ordering.lua'] = { globals = { 'bonus_gui_ordering' } }
files['**/base/prototypes/'] = {std = STD_BASE_DATA}
files['**/core/prototypes/'] = {std = STD_BASE_DATA}
files['**/core/prototypes/noise-programs.lua'] = {ignore = {'212/x', '212/y', '212/tile', '212/map'}}
files['**/base/prototypes/'] = { std = STD_BASE_DATA }
files['**/core/prototypes/'] = { std = STD_BASE_DATA }
files['**/core/prototypes/noise-programs.lua'] = { ignore = { '212/x', '212/y', '212/tile', '212/map' } }
--(( stdlib ))--
local stdlib_control = {
@ -153,7 +159,7 @@ files['**/stdlib/data/'] = stdlib_data
-- STDLIB Busted Spec
files['**/spec/**'] = {
globals = {'serpent', 'log', 'SLOG', 'RESET'},
globals = { 'serpent', 'log', 'SLOG', 'RESET' },
std = 'lua52c+busted+factorio_defines+factorio_control+stdlib'
} --))
@ -220,9 +226,9 @@ stds.factorio_control = {
settings = {
fields = {
'get_player_settings',
startup = {read_only = false, other_fields = true},
global = {read_only = false, other_fields = true},
player = {read_only = false, other_fields = true}
startup = { read_only = false, other_fields = true },
global = { read_only = false, other_fields = true },
player = { read_only = false, other_fields = true }
}
},
-- @script@: Provides an interface for registering event handlers.
@ -247,7 +253,7 @@ stds.factorio_control = {
-- (http://lua-api.factorio.com/latest/LuaRemote.html)
remote = {
fields = {
interfaces = {read_only = false, other_fields = true},
interfaces = { read_only = false, other_fields = true },
'add_interface',
'remove_interface',
'call'
@ -256,7 +262,7 @@ stds.factorio_control = {
other_fields = false
},
rcon = {
fields = {'print'}
fields = { 'print' }
},
commands = {
fields = {
@ -413,42 +419,42 @@ stds.factorio_control = {
'unban_player',
'unmute_player',
'write_file',
active_mods = {read_only = true, other_fields = true},
ammo_category_prototypes = {read_only = true, other_fields = true},
autoplace_control_prototypes = {read_only = true, other_fields = true},
backer_names = {read_only = true, other_fields = true},
connected_players = {read_only = true, other_fields = true},
custom_input_prototypes = {read_only = true, other_fields = true},
damage_prototypes = {read_only = true, other_fields = true},
decorative_prototypes = {read_only = true, other_fields = true},
default_map_gen_settings = {read_only = true, other_fields = true},
difficulty = {read_only = true, other_fields = true},
difficulty_settings = {read_only = true, other_fields = true},
enemy_has_vision_on_land_mines = {read_only = false, other_fields = false},
entity_prototypes = {read_only = true, other_fields = true},
equipment_grid_prototypes = {read_only = true, other_fields = true},
equipment_prototypes = {read_only = true, other_fields = true},
finished = {read_only = true, other_fields = true},
fluid_prototypes = {read_only = true, other_fields = true},
forces = {read_only = true, other_fields = true},
item_prototypes = {read_only = true, other_fields = true},
map_settings = {read_only = true, other_fields = true},
mod_setting_prototypes = {read_only = true, other_fields = true},
noise_layer_prototypes = {read_only = true, other_fields = true},
permissions = {read_only = true, other_fields = true},
player = {read_only = true, other_fields = true},
players = {read_only = true, other_fields = true},
recipe_prototypes = {read_only = true, other_fields = true},
speed = {read_only = false, other_fields = false},
styles = {read_only = true, other_fields = true},
surfaces = {read_only = true, other_fields = true},
technology_prototypes = {read_only = true, other_fields = true},
tick = {read_only = true, other_fields = true},
tick_paused = {read_only = false, other_fields = false},
ticks_played = {read_only = true, other_fields = true},
ticks_to_run = {read_only = false, other_fields = false},
tile_prototypes = {read_only = true, other_fields = true},
virtual_signal_prototypes = {read_only = true, other_fields = true}
active_mods = { read_only = true, other_fields = true },
ammo_category_prototypes = { read_only = true, other_fields = true },
autoplace_control_prototypes = { read_only = true, other_fields = true },
backer_names = { read_only = true, other_fields = true },
connected_players = { read_only = true, other_fields = true },
custom_input_prototypes = { read_only = true, other_fields = true },
damage_prototypes = { read_only = true, other_fields = true },
decorative_prototypes = { read_only = true, other_fields = true },
default_map_gen_settings = { read_only = true, other_fields = true },
difficulty = { read_only = true, other_fields = true },
difficulty_settings = { read_only = true, other_fields = true },
enemy_has_vision_on_land_mines = { read_only = false, other_fields = false },
entity_prototypes = { read_only = true, other_fields = true },
equipment_grid_prototypes = { read_only = true, other_fields = true },
equipment_prototypes = { read_only = true, other_fields = true },
finished = { read_only = true, other_fields = true },
fluid_prototypes = { read_only = true, other_fields = true },
forces = { read_only = true, other_fields = true },
item_prototypes = { read_only = true, other_fields = true },
map_settings = { read_only = true, other_fields = true },
mod_setting_prototypes = { read_only = true, other_fields = true },
noise_layer_prototypes = { read_only = true, other_fields = true },
permissions = { read_only = true, other_fields = true },
player = { read_only = true, other_fields = true },
players = { read_only = true, other_fields = true },
recipe_prototypes = { read_only = true, other_fields = true },
speed = { read_only = false, other_fields = false },
styles = { read_only = true, other_fields = true },
surfaces = { read_only = true, other_fields = true },
technology_prototypes = { read_only = true, other_fields = true },
tick = { read_only = true, other_fields = true },
tick_paused = { read_only = false, other_fields = false },
ticks_played = { read_only = true, other_fields = true },
ticks_to_run = { read_only = false, other_fields = false },
tile_prototypes = { read_only = true, other_fields = true },
virtual_signal_prototypes = { read_only = true, other_fields = true }
}
}
},
@ -496,7 +502,7 @@ stds.factorio_data = {
--(( Factorio Globals are bad mkay ))--
stds.factorio_base_control = {
read_globals = {'silo_script', 'mod_gui', 'camera'}
read_globals = { 'silo_script', 'mod_gui', 'camera' }
}
stds.factorio_base_scenarios = {
@ -1221,12 +1227,12 @@ stds.factorio_defines = {
'not_enough_repair_packs'
}
},
anticolor = {other_fields = true},
behavior_result = {fields = {'success', 'in_progress', 'deleted', 'fail'}},
build_check_type = {fields = {'script', 'manual', 'ghost_revive', 'ghost_place'}},
chain_signal_state = {fields = {'partially_open', 'none_open', 'none', 'all_open'}},
anticolor = { other_fields = true },
behavior_result = { fields = { 'success', 'in_progress', 'deleted', 'fail' } },
build_check_type = { fields = { 'script', 'manual', 'ghost_revive', 'ghost_place' } },
chain_signal_state = { fields = { 'partially_open', 'none_open', 'none', 'all_open' } },
chunk_generated_status = {
fields = {'basic_tiles', 'corrected_tiles', 'entities', 'nothing', 'tiles', 'custom_tiles'}
fields = { 'basic_tiles', 'corrected_tiles', 'entities', 'nothing', 'tiles', 'custom_tiles' }
},
circuit_condition_index = {
fields = {
@ -1260,7 +1266,7 @@ stds.factorio_defines = {
'container'
}
},
color = {other_fields = true},
color = { other_fields = true },
command = {
fields = {
'attack',
@ -1274,7 +1280,7 @@ stds.factorio_defines = {
'flee'
}
},
compound_command = {fields = {'return_last', 'logical_and', 'logical_or'}},
compound_command = { fields = { 'return_last', 'logical_and', 'logical_or' } },
control_behavior = {
fields = {
inserter = {
@ -1288,15 +1294,15 @@ stds.factorio_defines = {
'enable_disable'
}
},
hand_read_mode = {fields = {'hold', 'pulse'}}
hand_read_mode = { fields = { 'hold', 'pulse' } }
}
},
lamp = {fields = {circuit_mode_of_operation = {fields = {'use_colors'}}}},
lamp = { fields = { circuit_mode_of_operation = { fields = { 'use_colors' } } } },
logistic_container = {
fields = {circuit_mode_of_operation = {fields = {'set_requests', 'send_contents'}}}
fields = { circuit_mode_of_operation = { fields = { 'set_requests', 'send_contents' } } }
},
mining_drill = {fields = {resource_read_mode = {fields = {'this_miner', 'entire_patch'}}}},
transport_belt = {fields = {content_read_mode = {fields = {'hold', 'pulse'}}}},
mining_drill = { fields = { resource_read_mode = { fields = { 'this_miner', 'entire_patch' } } } },
transport_belt = { fields = { content_read_mode = { fields = { 'hold', 'pulse' } } } },
type = {
fields = {
'rail_chain_signal',
@ -1321,23 +1327,23 @@ stds.factorio_defines = {
}
}
},
controllers = {fields = {'spectator', 'character', 'god', 'cutscene', 'editor', 'ghost'}},
controllers = { fields = { 'spectator', 'character', 'god', 'cutscene', 'editor', 'ghost' } },
deconstruction_item = {
fields = {
entity_filter_mode = {fields = {'whitelist', 'blacklist'}},
tile_filter_mode = {fields = {'whitelist', 'blacklist'}},
tile_selection_mode = {fields = {'only', 'never', 'always', 'normal'}}
entity_filter_mode = { fields = { 'whitelist', 'blacklist' } },
tile_filter_mode = { fields = { 'whitelist', 'blacklist' } },
tile_selection_mode = { fields = { 'only', 'never', 'always', 'normal' } }
}
},
difficulty = {fields = {'hard', 'easy', 'normal'}},
difficulty = { fields = { 'hard', 'easy', 'normal' } },
difficulty_settings = {
fields = {
recipe_difficulty = {fields = {'normal', 'expensive'}},
technology_difficulty = {fields = {'normal', 'expensive'}}
recipe_difficulty = { fields = { 'normal', 'expensive' } },
technology_difficulty = { fields = { 'normal', 'expensive' } }
}
},
direction = {
fields = {'southwest', 'north', 'northeast', 'west', 'east', 'northwest', 'south', 'southeast'}
fields = { 'southwest', 'north', 'northeast', 'west', 'east', 'northwest', 'south', 'southeast' }
},
disconnect_reason = {
fields = {
@ -1354,7 +1360,7 @@ stds.factorio_defines = {
'reconnect'
}
},
distraction = {fields = {'by_damage', 'by_anything', 'by_enemy', 'none'}},
distraction = { fields = { 'by_damage', 'by_anything', 'by_enemy', 'none' } },
entity_status = {
fields = {
'no_power',
@ -1881,7 +1887,7 @@ stds.factorio_defines = {
'cargo_wagon'
}
},
lightcolor = {other_fields = true},
lightcolor = { other_fields = true },
logistic_member_index = {
fields = {
'character_provider',
@ -1893,12 +1899,12 @@ stds.factorio_defines = {
}
},
logistic_mode = {
fields = {'passive_provider', 'active_provider', 'requester', 'storage', 'buffer', 'none'}
fields = { 'passive_provider', 'active_provider', 'requester', 'storage', 'buffer', 'none' }
},
mouse_button_type = {fields = {'left', 'middle', 'right', 'none'}},
rail_connection_direction = {fields = {'left', 'straight', 'right', 'none'}},
rail_direction = {fields = {'back', 'front'}},
relative_gui_position = {fields = {'bottom', 'top', 'left', 'right'}},
mouse_button_type = { fields = { 'left', 'middle', 'right', 'none' } },
rail_connection_direction = { fields = { 'left', 'straight', 'right', 'none' } },
rail_direction = { fields = { 'back', 'front' } },
relative_gui_position = { fields = { 'bottom', 'top', 'left', 'right' } },
relative_gui_type = {
fields = {
'blueprint_library_gui',
@ -1966,17 +1972,17 @@ stds.factorio_defines = {
'entity_variations_gui'
}
},
render_mode = {fields = {'chart_zoomed_in', 'game', 'chart'}},
rich_text_setting = {fields = {'disabled', 'enabled', 'highlight'}},
render_mode = { fields = { 'chart_zoomed_in', 'game', 'chart' } },
rich_text_setting = { fields = { 'disabled', 'enabled', 'highlight' } },
riding = {
fields = {
acceleration = {fields = {'reversing', 'accelerating', 'nothing', 'braking'}},
direction = {fields = {'left', 'straight', 'right'}}
acceleration = { fields = { 'reversing', 'accelerating', 'nothing', 'braking' } },
direction = { fields = { 'left', 'straight', 'right' } }
}
},
shooting = {fields = {'shooting_selected', 'not_shooting', 'shooting_enemies'}},
signal_state = {fields = {'reserved_by_circuit_network', 'reserved', 'closed', 'open'}},
time = {fields = {'hour', 'week', 'year', 'month', 'minute', 'second', 'day'}},
shooting = { fields = { 'shooting_selected', 'not_shooting', 'shooting_enemies' } },
signal_state = { fields = { 'reserved_by_circuit_network', 'reserved', 'closed', 'open' } },
time = { fields = { 'hour', 'week', 'year', 'month', 'minute', 'second', 'day' } },
train_state = {
fields = {
'no_path',
@ -2005,8 +2011,8 @@ stds.factorio_defines = {
'right_split_line'
}
},
wire_connection_id = {fields = {'power_switch_right', 'power_switch_left', 'electric_pole'}},
wire_type = {fields = {'copper', 'green', 'red'}}
wire_connection_id = { fields = { 'power_switch_right', 'power_switch_left', 'electric_pole' } },
wire_type = { fields = { 'copper', 'green', 'red' } }
}
}
}

View File

@ -2,6 +2,8 @@ require 'utils.data_stages'
_LIFECYCLE = _STAGE.control -- Control stage
_DEBUG = false
_DUMP_ENV = false
_PROFILE = false
_PROFILE_ON_INIT = false
require 'utils.server'
require 'utils.server_commands'
@ -264,6 +266,9 @@ require 'map_loader'
if _DUMP_ENV then
require 'utils.dump_env'
end
if _PROFILE then
require 'utils.profiler'
end

View File

@ -1202,7 +1202,7 @@ local function show_mvps(player)
RPG_Progression.save_all_players()
end
local date = Server.get_start_time()
game.server_save('Final_Mtn_Fortress_v3_' .. tostring(date))
game.server_save('Final_Mtn_v3_' .. tostring(date) .. '_wave' .. tostring(wave))
local text = {
title = 'Game over!',
description = 'Game statistics from the game is below',

View File

@ -20,6 +20,7 @@ local BottomFrame = require 'utils.gui.bottom_frame'
local Modifiers = require 'utils.player_modifiers'
local zone_settings = Public.zone_settings
local de = defines.events
local this = {
power_sources = {index = 1},
@ -1716,11 +1717,11 @@ local on_research_finished = Public.on_research_finished
local on_player_changed_position = Public.on_player_changed_position
local on_player_respawned = Public.on_player_respawned
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_player_left_game, on_player_left_game)
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.add(de.on_player_joined_game, on_player_joined_game)
Event.add(de.on_player_left_game, on_player_left_game)
Event.add(de.on_research_finished, on_research_finished)
Event.add(de.on_player_changed_position, on_player_changed_position)
Event.add(de.on_player_respawned, on_player_respawned)
Event.on_nth_tick(10, tick)
Event.add(WD.events.on_wave_created, on_wave_created)

View File

@ -25,9 +25,6 @@ local wintery_type = {
['cargo-wagon'] = true
}
-- Set to false by modules that want to control the on_chunk_generated event themselves.
Public.enable_register_events = true
-- Simple "loop" that is UPS friendly.
local function get_position(data)
data.yv = data.yv + 1
@ -518,7 +515,7 @@ local map_gen_action_token = Token.register(map_gen_action)
--- Adds generation of a Chunk of the map to the queue
-- @param event <table> the event table from on_chunk_generated
function Public.schedule_chunk(event)
local function schedule_chunk(event)
local surface = event.surface
local shape = generate_map
@ -563,7 +560,7 @@ end
--- Generates a Chunk of map when called
-- @param event <table> the event table from on_chunk_generated
function Public.do_chunk(event)
local function do_chunk(event)
local surface = event.surface
local shape = generate_map
@ -610,9 +607,6 @@ function Public.do_chunk(event)
do_place_treasure(data)
end
local do_chunk = Public.do_chunk
local schedule_chunk = Public.schedule_chunk
local function on_chunk(event)
local force_chunk = Public.get('force_chunk')
local stop_chunk = Public.get('stop_chunk')

View File

@ -196,99 +196,7 @@ local function on_player_joined_game(event)
end
end
local function on_gui_click(event)
local element = event.element
if not element.valid then
return
end
local name = element.name
if name == main_button_name then
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
local is_spamming = SpamProtection.is_spamming(player, nil, 'Mtn Gui Click')
if is_spamming then
return
end
local locomotive = Public.get('locomotive')
if not validate_entity(locomotive) then
return
end
if not player or not player.valid then
return
end
if not player.surface or not player.surface.valid then
return
end
if player.surface ~= locomotive.surface then
local minimap = player.gui.left.icw_main_frame
if minimap and minimap.visible then
minimap.visible = false
return
elseif minimap and not minimap.visible then
minimap.visible = true
return
end
return
end
if player.gui.top[main_frame_name] then
local info = player.gui.top[main_frame_name]
local wd = player.gui.top['wave_defense']
local diff = player.gui.top[Difficulty.top_button_name]
if info and info.visible then
if wd then
wd.visible = false
end
if diff then
diff.visible = false
end
info.visible = false
return
elseif wd and not wd.visible then
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
if wd then
wd.visible = true
end
if diff then
diff.visible = true
end
return
elseif info and not info.visible then
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
if wd then
wd.visible = true
end
if diff then
diff.visible = true
end
info.visible = true
return
end
else
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
create_main_frame(player)
end
end
end
local function on_player_changed_surface(event)
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
local function changed_surface(player)
local rpg_button = RPG.draw_main_frame_name
local rpg_frame = RPG.main_frame_name
local rpg_settings = RPG.settings_frame_name
@ -404,6 +312,101 @@ local function on_player_changed_surface(event)
end
end
local function on_gui_click(event)
local element = event.element
if not element.valid then
return
end
local name = element.name
if name == main_button_name then
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
local is_spamming = SpamProtection.is_spamming(player, nil, 'Mtn Gui Click')
if is_spamming then
return
end
local locomotive = Public.get('locomotive')
if not validate_entity(locomotive) then
return
end
if not player or not player.valid then
return
end
if not player.surface or not player.surface.valid then
return
end
if player.surface ~= locomotive.surface then
local minimap = player.gui.left.icw_main_frame
if minimap and minimap.visible then
minimap.visible = false
return
elseif minimap and not minimap.visible then
minimap.visible = true
return
end
return
end
if player.gui.top[main_frame_name] then
local info = player.gui.top[main_frame_name]
local wd = player.gui.top['wave_defense']
local diff = player.gui.top[Difficulty.top_button_name]
if info and info.visible then
if wd then
wd.visible = false
end
if diff then
diff.visible = false
end
info.visible = false
return
elseif wd and not wd.visible then
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
if wd then
wd.visible = true
end
if diff then
diff.visible = true
end
return
elseif info and not info.visible then
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
if wd then
wd.visible = true
end
if diff then
diff.visible = true
end
info.visible = true
return
end
else
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
create_main_frame(player)
end
end
end
local function on_player_changed_surface(event)
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
changed_surface(player)
end
local function enable_guis(event)
local player = game.players[event.player_index]
if not validate_player(player) then
@ -552,4 +555,6 @@ Gui.on_click(
end
)
Public.changed_surface = changed_surface
return Public

View File

@ -177,6 +177,8 @@ function Public.reset_map()
game.forces.player.set_spawn_position({-27, 25}, surface)
game.forces.player.manual_mining_speed_modifier = 0
game.forces.player.set_ammo_damage_modifier('artillery-shell', -0.95)
game.forces.player.worker_robots_battery_modifier = 4
game.forces.player.worker_robots_storage_bonus = 15
BiterHealthBooster.set_active_surface(tostring(surface.name))
BiterHealthBooster.acid_nova(true)
@ -394,7 +396,7 @@ local lock_locomotive_positions = function()
local total_pos = #locomotive_positions.tbl
if total_pos > 50 then
remove(locomotive_positions.tbl, total_pos - total_pos + 1)
remove(locomotive_positions.tbl, 1)
end
end

View File

@ -278,7 +278,7 @@ function Public.entity_died_randomness(data)
surface.spill_item_stack(position, {name = harvest, count = random(1, 5)}, true)
local particle = particles[harvest]
create_particles(surface, particle, position, 64, {x = entity.position.x, y = entity.position.y})
create_particles(surface, particle, position, 16, {x = entity.position.x, y = entity.position.y})
end
local function randomness(data)
@ -340,9 +340,9 @@ local function randomness(data)
local particle = particles[harvest]
if data.script_character then
create_particles(player.surface, particle, position, 64, {x = data.script_character.position.x, y = data.script_character.position.y})
create_particles(player.surface, particle, position, 16, {x = data.script_character.position.x, y = data.script_character.position.y})
else
create_particles(player.surface, particle, position, 64, {x = player.position.x, y = player.position.y})
create_particles(player.surface, particle, position, 16, {x = player.position.x, y = player.position.y})
end
end

View File

@ -49,6 +49,38 @@ local ammo_loot = {
},
weight = 1
},
{
stack = {
recipe = 'rocket',
tech = 'military-2',
output = {item = 'rocket', min_rate = 1 / 800, distance_factor = 1 / 8 / 60 / 20480}
},
weight = 0.95
},
{
stack = {
recipe = 'explosive-rocket',
tech = 'military-2',
output = {item = 'explosive-rocket', min_rate = 2 / 1800, distance_factor = 1 / 8 / 60 / 20480}
},
weight = 0.4
},
{
stack = {
recipe = 'defender-capsule',
tech = 'military-2',
output = {item = 'defender-capsule', min_rate = 2 / 1800, distance_factor = 1 / 8 / 60 / 20480}
},
weight = 0.95
},
{
stack = {
recipe = 'distractor-capsule',
tech = 'military-2',
output = {item = 'distractor-capsule', min_rate = 2 / 1800, distance_factor = 1 / 8 / 60 / 20480}
},
weight = 0.55
},
{
stack = {
recipe = 'firearm-magazine',
@ -194,11 +226,19 @@ local resource_loot = {
{
stack = {
recipe = 'stone-wall',
tech = 'stone-walls',
tech = 'stone-wall',
output = {item = 'stone-wall', min_rate = 0.6 / 60, distance_factor = 1 / 8 / 60 / 20480}
},
weight = 10
},
{
stack = {
recipe = 'rail',
tech = 'automated-rail-transportation',
output = {item = 'rail', min_rate = 1 / 4 / 60, distance_factor = 1 / 8 / 60 / 20480}
},
weight = 7
},
{
stack = {
recipe = 'concrete',

View File

@ -101,13 +101,11 @@ function Public.reset_main_table()
this.restart = false
this.shutdown = false
this.announced_message = false
this.game_saved = false
-- @end
this.breach_wall_warning = false
this.icw_locomotive = nil
this.game_lost = false
this.death_mode = false
this.fullness_enabled = true
this.locomotive_health = 10000
this.locomotive_max_health = 10000
this.gap_between_zones = {

View File

@ -322,7 +322,9 @@ local function on_tick()
progress()
end
Event.on_init(on_init)
Event.add(defines.events.on_tick, on_tick)
if not Public.read_tables_only then
Event.on_init(on_init)
Event.add(defines.events.on_tick, on_tick)
end
return Public

View File

@ -442,12 +442,7 @@ function Public.draw_level_text(player)
rpg_t.text = nil
end
local players = {}
for _, p in pairs(game.players) do
if p.index ~= player.index then -- todo maybe remove this so the player also sees their level?
players[#players + 1] = p.index
end
end
local players = game.connected_players
if #players == 0 then
return
end

View File

@ -4,28 +4,15 @@ local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Difficulty = require 'modules.difficulty_vote_by_amount'
local Alert = require 'utils.alert'
local Server = require 'utils.server'
local Collapse = require 'modules.collapse'
Collapse.read_tables_only = true
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')
if not debug then
return
end
print('WaveDefense: ' .. msg)
end
local function debug_print_health(msg)
local debug = Public.get('debug_health')
if not debug then
return
end
print('[HEALTHBOOSTER]: ' .. msg)
end
local check_if_near_target
local function valid(userdata)
if not (userdata and userdata.valid) then
@ -43,6 +30,13 @@ local function shuffle(tbl)
return tbl
end
local function normalize_spawn_position()
local collapse_spawn_position = Collapse.get_position()
local new_pos = {x = 0, y = collapse_spawn_position.y - 40}
Public.set_spawn_position(new_pos)
return new_pos
end
local function find_initial_spot(surface, position)
local spot = Public.get('spot')
if not spot then
@ -168,14 +162,14 @@ local function fill_tiles(entity, size)
surface.set_tiles({{name = 'sand-1', position = tile.position}}, true)
end
end
debug_print('fill_tiles - filled tiles cause we found non-placable tiles.')
Public.debug_print('fill_tiles - filled tiles cause we found non-placable tiles.')
end
local function get_spawn_pos()
local surface_index = Public.get('surface_index')
local surface = game.surfaces[surface_index]
if not surface then
return debug_print('get_spawn_pos - surface was not valid?')
return Public.debug_print('get_spawn_pos - surface was not valid?')
end
local c = 0
@ -183,11 +177,14 @@ local function get_spawn_pos()
::retry::
local initial_position = Public.get('spawn_position')
local target = Public.get('target')
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}
if initial_position.y - target.position.y > 10 then
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
end
local located_position = find_initial_spot(surface, initial_position)
@ -206,21 +203,21 @@ local function get_spawn_pos()
if remove_entities then
c = c + 1
valid_position = Public.get('spawn_position')
debug_print(serpent.block('valid_position - x:' .. valid_position.x .. ' y:' .. valid_position.y))
Public.debug_print(serpent.block('valid_position - x:' .. valid_position.x .. ' y:' .. valid_position.y))
remove_trees({surface = surface, position = valid_position, valid = true})
remove_rocks({surface = surface, position = valid_position, valid = true})
fill_tiles({surface = surface, position = valid_position, valid = true})
Public.set('spot', 'nil')
if c == 5 then
return debug_print('get_spawn_pos - we could not find a spawning pos?')
return Public.debug_print('get_spawn_pos - we could not find a spawning pos?')
end
goto retry
else
return debug_print('get_spawn_pos - we could not find a spawning pos?')
return Public.debug_print('get_spawn_pos - we could not find a spawning pos?')
end
end
debug_print(serpent.block('valid_position - x:' .. valid_position.x .. ' y:' .. valid_position.y))
Public.debug_print(serpent.block('valid_position - x:' .. valid_position.x .. ' y:' .. valid_position.y))
return valid_position
end
@ -228,15 +225,15 @@ end
local function is_unit_valid(biter)
local max_biter_age = Public.get('max_biter_age')
if not biter.entity then
debug_print('is_unit_valid - unit destroyed - does no longer exist')
Public.debug_print('is_unit_valid - unit destroyed - does no longer exist')
return false
end
if not biter.entity.valid then
debug_print('is_unit_valid - unit destroyed - invalid')
Public.debug_print('is_unit_valid - unit destroyed - invalid')
return false
end
if biter.spawn_tick + max_biter_age < game.tick then
debug_print('is_unit_valid - unit destroyed - timed out')
Public.debug_print('is_unit_valid - unit destroyed - timed out')
return false
end
return true
@ -245,7 +242,7 @@ end
local function refresh_active_unit_threat()
local active_biter_threat = Public.get('active_biter_threat')
local generated_units = Public.get('generated_units')
debug_print('refresh_active_unit_threat - current value ' .. active_biter_threat)
Public.debug_print('refresh_active_unit_threat - current value ' .. active_biter_threat)
local biter_threat = 0
for k, biter in pairs(generated_units.active_biters) do
if valid(biter.entity) then
@ -256,7 +253,7 @@ local function refresh_active_unit_threat()
end
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
Public.set('active_biter_threat', round(biter_threat * biter_health_boost, 2))
debug_print('refresh_active_unit_threat - new value ' .. active_biter_threat)
Public.debug_print('refresh_active_unit_threat - new value ' .. active_biter_threat)
if generated_units.unit_group_pos.index > 500 then
generated_units.unit_group_pos.positions = {}
generated_units.unit_group_pos.index = 0
@ -285,7 +282,7 @@ local function time_out_biters()
entity.destroy()
end
end
debug_print('time_out_biters: ' .. k .. ' got deleted.')
Public.debug_print('time_out_biters: ' .. k .. ' got deleted.')
generated_units.active_biters[k] = nil
end
end
@ -316,7 +313,7 @@ local function get_random_close_spawner()
if not spawner or (center.x - spawner_2.position.x) ^ 2 + (center.y - spawner_2.position.y) ^ 2 < (center.x - spawner.position.x) ^ 2 + (center.y - spawner.position.y) ^ 2 then
spawner = spawner_2
if spawner and spawner.position then
debug_print('get_random_close_spawner - Found at x' .. spawner.position.x .. ' y' .. spawner.position.y)
Public.debug_print('get_random_close_spawner - Found at x' .. spawner.position.x .. ' y' .. spawner.position.y)
end
end
end
@ -368,7 +365,7 @@ local function set_main_target()
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.')
Public.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
local function set_group_spawn_position(surface)
@ -383,7 +380,7 @@ local function set_group_spawn_position(surface)
Public.set('spawn_position', {x = position.x, y = position.y})
local spawn_position = get_spawn_pos()
if spawn_position then
debug_print('set_group_spawn_position -- Changed position to x' .. spawn_position.x .. ' y' .. spawn_position.y .. '.')
Public.debug_print('set_group_spawn_position -- Changed position to x' .. spawn_position.x .. ' y' .. spawn_position.y .. '.')
end
end
@ -423,7 +420,7 @@ local function can_units_spawn()
local threat = Public.get('threat')
if threat <= 0 then
debug_print('can_units_spawn - threat too low')
Public.debug_print('can_units_spawn - threat too low')
time_out_biters()
return false
end
@ -431,14 +428,14 @@ local function can_units_spawn()
local active_biter_count = Public.get('active_biter_count')
local max_active_biters = Public.get('max_active_biters')
if active_biter_count >= max_active_biters then
debug_print('can_units_spawn - active biter count too high')
Public.debug_print('can_units_spawn - active biter count too high')
time_out_biters()
return false
end
local active_biter_threat = Public.get('active_biter_threat')
if active_biter_threat >= threat then
debug_print('can_units_spawn - active biter threat too high (' .. active_biter_threat .. ')')
Public.debug_print('can_units_spawn - active biter threat too high (' .. active_biter_threat .. ')')
time_out_biters()
return false
end
@ -469,7 +466,7 @@ local function get_active_unit_groups_count()
end
end
end
debug_print('Active unit group count: ' .. count)
Public.debug_print('Active unit group count: ' .. count)
return count
end
@ -531,7 +528,7 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_se
if final_health < 1 then
final_health = 1
end
debug_print_health('final_health - unit: ' .. biter.name .. ' with h-m: ' .. final_health)
Public.debug_print_health('final_health - unit: ' .. biter.name .. ' with h-m: ' .. final_health)
BiterHealthBooster.add_unit(biter, final_health)
end
@ -574,8 +571,8 @@ local function increase_biter_damage()
local e_old_melee = e.get_ammo_damage_modifier('melee')
local e_old_biological = e.get_ammo_damage_modifier('biological')
debug_print('Melee: ' .. melee + e_old_melee)
debug_print('Biological: ' .. bio + e_old_biological)
Public.debug_print('Melee: ' .. melee + e_old_melee)
Public.debug_print('Biological: ' .. bio + e_old_biological)
e.set_ammo_damage_modifier('melee', melee + e_old_melee)
e.set_ammo_damage_modifier('biological', bio + e_old_biological)
@ -592,7 +589,7 @@ local function increase_biters_health()
if modified_unit_health.current_value > modified_unit_health.limit_value then
modified_unit_health.current_value = modified_unit_health.limit_value
end
debug_print_health('modified_unit_health.current_value: ' .. modified_unit_health.current_value)
Public.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
@ -600,7 +597,7 @@ local function increase_biters_health()
if modified_boss_unit_health.current_value > modified_boss_unit_health.limit_value then
modified_boss_unit_health.current_value = modified_boss_unit_health.limit_value
end
debug_print_health('modified_boss_unit_health.current_value: ' .. modified_boss_unit_health.current_value)
Public.debug_print_health('modified_boss_unit_health.current_value: ' .. modified_boss_unit_health.current_value)
Public.set('modified_boss_unit_health').current_value = modified_boss_unit_health.current_value + modified_boss_unit_health.health_increase_per_boss_wave
end
@ -622,7 +619,7 @@ local function increase_unit_group_size()
end
Public.set('average_unit_group_size', new_average_unit_group_size)
debug_print_health('average_unit_group_size - ' .. new_average_unit_group_size)
Public.debug_print_health('average_unit_group_size - ' .. new_average_unit_group_size)
end
end
@ -644,7 +641,7 @@ local function increase_max_active_unit_groups()
end
Public.set('max_active_unit_groups', new_max_active_unit_groups)
debug_print_health('max_active_unit_groups - ' .. new_max_active_unit_groups)
Public.debug_print_health('max_active_unit_groups - ' .. new_max_active_unit_groups)
end
end
@ -727,14 +724,14 @@ local function reform_group(group)
for _, biter in pairs(group.members) do
new_group.add_member(biter)
end
debug_print('Creating new unit group, because old one was stuck.')
Public.debug_print('Creating new unit group, because old one was stuck.')
generated_units.unit_groups[new_group.group_number] = new_group
local unit_groups_size = Public.get('unit_groups_size')
Public.set('unit_groups_size', unit_groups_size + 1)
return new_group
else
debug_print('Destroying stuck group.')
Public.debug_print('Destroying stuck group.')
if generated_units.unit_groups[group.group_number] then
if generated_units.unit_group_last_command[group.group_number] then
generated_units.unit_group_last_command[group.group_number] = nil
@ -810,7 +807,7 @@ local function get_main_command(group)
return
end
debug_print('get_main_command - starting')
Public.debug_print('get_main_command - starting')
local target_position = target.position
local distance_to_target = floor(sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2))
@ -820,9 +817,9 @@ local function get_main_command(group)
round((target_position.y - group_position.y) / steps, 3)
}
debug_print('get_commmands - to main target x' .. target_position.x .. ' y' .. target_position.y)
debug_print('get_commmands - distance_to_target:' .. distance_to_target .. ' steps:' .. steps)
debug_print('get_commmands - vector ' .. vector[1] .. '_' .. vector[2])
Public.debug_print('get_commmands - to main target x' .. target_position.x .. ' y' .. target_position.y)
Public.debug_print('get_commmands - distance_to_target:' .. distance_to_target .. ' steps:' .. steps)
Public.debug_print('get_commmands - vector ' .. vector[1] .. '_' .. vector[2])
for _ = 1, steps, 1 do
local old_position = group_position
@ -907,7 +904,7 @@ local function command_to_main_target(group, bypass)
local commands = get_main_command(group)
debug_print('get_main_command - got commands')
Public.debug_print('get_main_command - got commands')
local surface_index = Public.get('surface_index')
@ -922,7 +919,7 @@ local function command_to_main_target(group, bypass)
commands = commands
}
)
debug_print('get_main_command - sent commands')
Public.debug_print('get_main_command - sent commands')
if valid(group) then
generated_units.unit_group_last_command[group.group_number] = game.tick
end
@ -1007,25 +1004,25 @@ end
local function spawn_unit_group(fs, only_bosses)
if fs then
debug_print('spawn_unit_group - forcing new biters')
Public.debug_print('spawn_unit_group - forcing new biters')
else
if not can_units_spawn() then
debug_print('spawn_unit_group - Cant spawn units?')
Public.debug_print('spawn_unit_group - Cant spawn units?')
return
end
end
local target = Public.get('target')
if not valid(target) then
debug_print('spawn_unit_group - Target was not valid?')
Public.debug_print('spawn_unit_group - Target was not valid?')
return
end
local max_active_unit_groups = Public.get('max_active_unit_groups')
if fs then
debug_print('spawn_unit_group - forcing new biters')
Public.debug_print('spawn_unit_group - forcing new biters')
else
if get_active_unit_groups_count() >= max_active_unit_groups then
debug_print('spawn_unit_group - unit_groups at max')
Public.debug_print('spawn_unit_group - unit_groups at max')
return
end
end
@ -1040,6 +1037,15 @@ local function spawn_unit_group(fs, only_bosses)
return
end
if check_if_near_target(spawn_position) then
spawn_position = normalize_spawn_position()
Public.debug_print('spawn_unit_group - cannot spawn unit group near target')
if not spawn_position then
Public.debug_print('spawn_unit_group - spawn_position was invalid')
return
end
end
local radius = 10
local area = {
left_top = {spawn_position.x - radius, spawn_position.y - radius},
@ -1047,7 +1053,7 @@ local function spawn_unit_group(fs, only_bosses)
}
for _, v in pairs(surface.find_entities_filtered {area = area, name = 'land-mine'}) do
if v and v.valid then
debug_print('spawn_unit_group - found land-mines')
Public.debug_print('spawn_unit_group - found land-mines')
v.die()
end
end
@ -1061,7 +1067,7 @@ local function spawn_unit_group(fs, only_bosses)
local wave_number = Public.get('wave_number')
Public.wave_defense_set_unit_raffle(wave_number)
debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y)
Public.debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y)
local event_data = {}
@ -1093,7 +1099,7 @@ local function spawn_unit_group(fs, only_bosses)
for _ = 1, group_size, 1 do
local biter = spawn_biter(surface, spawn_position, fs, false, unit_settings)
if not biter then
debug_print('spawn_unit_group - No biters were found?')
Public.debug_print('spawn_unit_group - No biters were found?')
break
end
unit_group.add_member(biter)
@ -1116,7 +1122,7 @@ local function spawn_unit_group(fs, only_bosses)
for _ = 1, count, 1 do
local biter = spawn_biter(surface, spawn_position, fs, true, unit_settings)
if not biter then
debug_print('spawn_unit_group - No biter was found?')
Public.debug_print('spawn_unit_group - No biter was found?')
break
end
unit_group.add_member(biter)
@ -1191,14 +1197,37 @@ local function log_threat()
end
end
if is_loaded_bool('maps.mountain_fortress_v3.table') then
local Core = require 'maps.mountain_fortress_v3.core'
check_if_near_target = function(position)
local entity = {
valid = true,
position = position
}
local disable_spawn_near_target = Public.get('disable_spawn_near_target')
if Core.is_around_train(entity) and disable_spawn_near_target then
Public.debug_print('check_if_near_target - cannot spawn inside locomotive aura')
return true
end
return false
end
else
check_if_near_target = function()
return false
end
end
local tick_tasks = {
[30] = set_main_target,
[60] = set_enemy_evolution,
[90] = check_group_positions,
[120] = give_main_command_to_group,
[150] = log_threat,
[180] = Public.build_nest,
[210] = Public.build_worm
[180] = Public.build_worm,
[210] = Public.build_nest
}
local tick_tasks_t2 = {
@ -1283,5 +1312,7 @@ Event.on_nth_tick(
)
Public.set_next_wave = set_next_wave
Public.normalize_spawn_position = normalize_spawn_position
Public.check_if_near_target = check_if_near_target
return Public

View File

@ -128,6 +128,7 @@ local function pause_waves_state(state)
else
local message = ({'wave_defense.start_waves'})
Alert.alert_all_players(30, message, nil, 'achievement/tech-maniac', 0.75)
Public.normalize_spawn_position()
Public.set('paused', false)
Public.set('paused_waves_for', nil)
Public.set('last_pause', nil)

View File

@ -59,6 +59,7 @@ function Public.reset_wave_defense()
this.biter_raffle = {}
this.debug = false
this.debug_health = false
this.disable_spawn_near_target = true
this.log_wave_to_discord = true
this.paused = false
this.pause_without_votes = true
@ -168,6 +169,20 @@ function Public.reset_wave_defense()
}
end
function Public.debug_print(msg)
if not this.debug then
return
end
log('WaveDefense: ' .. msg)
end
function Public.debug_print_health(msg)
if not this.debug then
return
end
log('[HEALTHBOOSTER]: ' .. msg)
end
--- This gets values from our table
-- @param key <string>
function Public.get(key)

View File

@ -1,10 +1,13 @@
local Public = require 'modules.wave_defense.table'
local Event = require 'utils.event'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local math_random = math.random
local round = math.round
local Token = require 'utils.token'
local Task = require 'utils.task'
local Alert = require 'utils.alert'
local round = math.round
local random = math.random
local place_nest_near_unit_group
local immunity_spawner =
Token.register(
@ -61,73 +64,156 @@ local function remove_unit(entity)
end
end
local function place_nest_near_unit_group()
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
if is_loaded_bool('maps.mountain_fortress_v3.table') then
local Core = require 'maps.mountain_fortress_v3.core'
local generated_units = Public.get('generated_units')
local group = generated_units.unit_groups[random_group.group_number]
if not group then
return
end
if not group.valid then
return
end
if not group.members then
return
end
if not group.members[1] then
return
end
local unit = group.members[math_random(1, #group.members)]
if not unit.valid then
return
end
local name = 'biter-spawner'
if math_random(1, 3) == 1 then
name = 'spitter-spawner'
end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
type = 'unit-spawner',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
}
) > 0
then
return
end
place_nest_near_unit_group = function()
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
local boss = is_boss(unit)
local disable_spawn_near_target = Public.get('disable_spawn_near_target')
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local generated_units = Public.get('generated_units')
local group = generated_units.unit_groups[random_group.group_number]
if not group then
return
end
if not group.valid then
return
end
if not group.members then
return
end
if not group.members[1] then
return
end
local unit = group.members[random(1, #group.members)]
if not unit.valid then
return
end
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
spawner.destructible = false
Task.set_timeout_in_ticks(200, immunity_spawner, {entity = spawner})
if Core.is_around_train(unit) and disable_spawn_near_target then
Public.debug_print('place_nest_near_unit_group - cannot spawn inside locomotive aura')
return
end
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
local name = 'biter-spawner'
if random(1, 3) == 1 then
name = 'spitter-spawner'
end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
type = 'unit-spawner',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
}
) > 0
then
return
end
local boss = is_boss(unit)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
spawner.destructible = false
local immunity_delay = random(100, 200)
Task.set_timeout_in_ticks(immunity_delay, immunity_spawner, {entity = spawner})
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
end
generated_units.nests[#generated_units.nests + 1] = spawner
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
remove_unit(unit)
unit.destroy()
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
end
else
place_nest_near_unit_group = function()
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
local generated_units = Public.get('generated_units')
local group = generated_units.unit_groups[random_group.group_number]
if not group then
return
end
if not group.valid then
return
end
if not group.members then
return
end
if not group.members[1] then
return
end
local unit = group.members[random(1, #group.members)]
if not unit.valid then
return
end
local name = 'biter-spawner'
if random(1, 3) == 1 then
name = 'spitter-spawner'
end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
type = 'unit-spawner',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
}
) > 0
then
return
end
local boss = is_boss(unit)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
spawner.destructible = false
Task.set_timeout_in_ticks(100, immunity_spawner, {entity = spawner})
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
end
generated_units.nests[#generated_units.nests + 1] = spawner
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
remove_unit(unit)
unit.destroy()
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
end
generated_units.nests[#generated_units.nests + 1] = spawner
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
remove_unit(unit)
unit.destroy()
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
end
function Public.build_nest()
@ -153,7 +239,7 @@ function Public.build_worm()
end
local worm_building_chance = Public.get('worm_building_chance') --[[@as integer]]
if math_random(1, worm_building_chance) ~= 1 then
if random(1, worm_building_chance) ~= 1 then
return
end
@ -180,7 +266,7 @@ function Public.build_worm()
if not group.members[1] then
return
end
local unit = group.members[math_random(1, #group.members)]
local unit = group.members[random(1, #group.members)]
if not unit.valid then
return
end
@ -232,14 +318,17 @@ end
local function shred_simple_entities(entity)
local threat = Public.get('threat')
if threat < 25000 then
if threat < 5000 then
return
end
local simple_entities =
entity.surface.find_entities_filtered(
{
type = 'simple-entity',
area = {{entity.position.x - 3, entity.position.y - 3}, {entity.position.x + 3, entity.position.y + 3}}
area = {
{entity.position.x - 3, entity.position.y - 3},
{entity.position.x + 3, entity.position.y + 3}
}
}
)
if #simple_entities == 0 then
@ -290,9 +379,21 @@ local function spawn_unit_spawner_inhabitants(entity)
for _ = 1, count, 1 do
local position = {entity.position.x + (-4 + math.random(0, 8)), entity.position.y + (-4 + math.random(0, 8))}
if math.random(1, 4) == 1 then
entity.surface.create_entity({name = Public.wave_defense_roll_spitter_name(), position = position, force = 'enemy'})
entity.surface.create_entity(
{
name = Public.wave_defense_roll_spitter_name(),
position = position,
force = 'enemy'
}
)
else
entity.surface.create_entity({name = Public.wave_defense_roll_biter_name(), position = position, force = 'enemy'})
entity.surface.create_entity(
{
name = Public.wave_defense_roll_biter_name(),
position = position,
force = 'enemy'
}
)
end
end
end
@ -306,14 +407,14 @@ local function on_entity_died(event)
local disable_threat_below_zero = Public.get('disable_threat_below_zero')
local valid_enemy_forces = Public.get('valid_enemy_forces')
if not valid_enemy_forces then
return
goto continue
end
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
if entity.type == 'unit' then
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
if not Public.threat_values[entity.name] then
return
goto continue
end
if disable_threat_below_zero then
local threat = Public.get('threat')
@ -322,7 +423,7 @@ local function on_entity_died(event)
if sub <= 0 or threat <= 0 then
Public.set('threat', 0)
remove_unit(entity)
return
goto continue
end
Public.set('threat', math.round(threat - Public.threat_values[entity.name] * biter_health_boost, 2))
remove_unit(entity)
@ -332,6 +433,8 @@ local function on_entity_died(event)
remove_unit(entity)
end
else
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
if valid_enemy_forces[entity.force.name] then
if entity.health then
if Public.threat_values[entity.name] then
@ -343,6 +446,8 @@ local function on_entity_died(event)
end
end
::continue::
if entity.force.index == 3 then
if event.cause then
if event.cause.valid then

View File

@ -24,7 +24,7 @@ local settings = {
playtime_for_instant_jail = 207360000, -- 40 days
-- playtime_for_instant_jail = 103680000, -- 20 days
clear_voted_player = 36000, -- remove player from vote-tbl after 10 minutes
clear_terms_tbl = 300,
clear_terms_tbl = 2000,
votejail_count = 5,
valid_surface = 'nauvis',
normies_can_jail = true -- states that normal players with enough playtime can jail
@ -429,7 +429,7 @@ local function validate_args(data)
return false
end
if player.name == offender and not player.admin then
if player.name == offender then
Utils.print_to(player, module_name .. 'You can´t jail yourself.')
return false
end

View File

@ -3,13 +3,24 @@ local string_rep = string.rep
local string_format = string.format
local debug_getinfo = debug.getinfo
local Color = require 'utils.color_presets'
local Task = require 'utils.task'
local Token = require 'utils.token'
local Event = require 'utils.event'
local Profiler = {
-- Call
CallTree = nil,
IsRunning = false
local Public = {
call_tree = nil,
is_running = false
}
local stop_profiler_token =
Token.register(
function()
Public.stop()
game.print('[PROFILER] Stopped!')
log('[PROFILER] Stopped!')
end
)
-- we can have this on runtime,
-- but never ever can a player run this without notifying us.
local allowed = {
@ -17,15 +28,15 @@ local allowed = {
['mewmew'] = true
}
local ignoredFunctions = {
local ignored_functions = {
[debug.sethook] = true
}
local namedSources = {
local named_sources = {
['[string "local n, v = "serpent", "0.30" -- (C) 2012-17..."]'] = 'serpent'
}
local function startCommand(command)
local function start_command(command)
local player = game.player
if player then
if player ~= nil then
@ -35,15 +46,15 @@ local function startCommand(command)
return
else
if allowed[player.name] then
Profiler.Start(command.parameter ~= nil)
Public.start(command.parameter ~= nil)
elseif _DEBUG then
Profiler.Start(command.parameter ~= nil)
Public.start(command.parameter ~= nil)
end
end
end
end
end
local function stopCommand(command)
local function stop_command(command)
local player = game.player
if player then
if player ~= nil then
@ -53,44 +64,44 @@ local function stopCommand(command)
return
else
if allowed[player.name] then
Profiler.Stop(command.parameter ~= nil, nil)
Public.stop(command.parameter ~= nil, nil)
elseif _DEBUG then
Profiler.Stop(command.parameter ~= nil, nil)
Public.stop(command.parameter ~= nil, nil)
end
end
end
end
end
ignoredFunctions[startCommand] = true
ignoredFunctions[stopCommand] = true
ignored_functions[start_command] = true
ignored_functions[stop_command] = true
commands.add_command('startProfiler', 'Starts profiling', startCommand)
commands.add_command('stopProfiler', 'Stops profiling', stopCommand)
commands.add_command('start_profiler', 'Starts profiling', start_command)
commands.add_command('stop_profiler', 'Stops profiling', stop_command)
--local assert_raw = assert
--function assert(expr, ...)
-- if not expr then
-- Profiler.Stop(false, "Assertion failed")
-- Public.stop(false, "Assertion failed")
-- end
-- assert_raw(expr, ...)
--end
local error_raw = error
--luacheck: ignore error
function error(...)
Profiler.Stop(false, 'Error raised')
Public.stop(false, 'Error raised')
error_raw(...)
end
function Profiler.Start(excludeCalledMs)
if Profiler.IsRunning then
function Public.start(exclude_called_ms)
if Public.is_running then
return
end
local create_profiler = game.create_profiler
Profiler.IsRunning = true
Public.is_running = true
Profiler.CallTree = {
Public.call_tree = {
name = 'root',
calls = 0,
profiler = create_profiler(),
@ -98,21 +109,21 @@ function Profiler.Start(excludeCalledMs)
}
-- Array of Call
local stack = {[0] = Profiler.CallTree}
local stack = {[0] = Public.call_tree}
local stack_count = 0
debug.sethook(
function(event)
local info = debug_getinfo(2, 'nSf')
if ignoredFunctions[info.func] then
if ignored_functions[info.func] then
return
end
if event == 'call' or event == 'tail call' then
local prevCall = stack[stack_count]
if excludeCalledMs then
prevCall.profiler.stop()
local prev_call = stack[stack_count]
if exclude_called_ms and prev_call then
prev_call.profiler.stop()
end
local what = info.what
@ -121,7 +132,7 @@ function Profiler.Start(excludeCalledMs)
name = string_format('C function %q', info.name or 'anonymous')
else
local source = info.short_src
local namedSource = namedSources[source]
local namedSource = named_sources[source]
if namedSource ~= nil then
source = namedSource
elseif string.sub(source, 1, 1) == '@' then
@ -130,13 +141,13 @@ function Profiler.Start(excludeCalledMs)
name = string_format('%q in %q, line %d', info.name or 'anonymous', source, info.linedefined)
end
local prevCall_next = prevCall.next
if prevCall_next == nil then
prevCall_next = {}
prevCall.next = prevCall_next
local prev_call_next = prev_call.next
if prev_call_next == nil then
prev_call_next = {}
prev_call.next = prev_call_next
end
local currCall = prevCall_next[name]
local currCall = prev_call_next[name]
local profilerStartFunc
if currCall == nil then
local prof = create_profiler()
@ -145,7 +156,7 @@ function Profiler.Start(excludeCalledMs)
calls = 1,
profiler = prof
}
prevCall_next[name] = currCall
prev_call_next[name] = currCall
profilerStartFunc = prof.reset
else
currCall.calls = currCall.calls + 1
@ -164,7 +175,7 @@ function Profiler.Start(excludeCalledMs)
stack[stack_count] = nil
stack_count = stack_count - 1
if excludeCalledMs then
if exclude_called_ms then
stack[stack_count].profiler.restart()
end
end
@ -173,9 +184,9 @@ function Profiler.Start(excludeCalledMs)
'cr'
)
end
ignoredFunctions[Profiler.Start] = true
ignored_functions[Public.start] = true
local function DumpTree(averageMs)
local function dump_tree(averageMs)
local function sort_Call(a, b)
return a.calls > b.calls
end
@ -216,28 +227,39 @@ local function DumpTree(averageMs)
end
end
end
if Profiler.CallTree.next ~= nil then
recurse(Profiler.CallTree.next, 0)
if Public.call_tree.next ~= nil then
recurse(Public.call_tree.next, 0)
return fullStr
end
return 'No calls'
end
function Profiler.Stop(averageMs, message)
if not Profiler.IsRunning then
function Public.stop(averageMs, message)
if not Public.is_running then
return
end
debug.sethook()
local text = {'', '\n\n----------PROFILER DUMP----------\n', DumpTree(averageMs), '\n\n----------PROFILER STOPPED----------\n'}
local text = {'', '\n\n----------PROFILER DUMP----------\n', dump_tree(averageMs), '\n\n----------PROFILER STOPPED----------\n'}
if message ~= nil then
text[#text + 1] = string.format('Reason: %s\n', message)
end
log(text)
Profiler.CallTree = nil
Profiler.IsRunning = false
Public.call_tree = nil
Public.is_running = false
end
ignoredFunctions[Profiler.Stop] = true
ignored_functions[Public.stop] = true
return Profiler
Event.on_init(
function()
if _PROFILE and _PROFILE_ON_INIT then
game.print('[PROFILER] Started!')
log('[PROFILER] Started!')
Public.start()
Task.set_timeout_in_ticks(3600, stop_profiler_token)
end
end
)
return Public

View File

@ -70,9 +70,18 @@ function is_loaded(module)
local res = _G.package.loaded[module]
if res then
return res
else
return false
end
return false
end
function is_loaded_bool(module)
local res = _G.package.loaded[module]
if res then
return true
end
return false
end
function is_game_modded()