mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-28 23:06:38 +02:00
Mtn v3 - changes for new season
This commit is contained in:
parent
b3b939b902
commit
b39ed27725
21
control.lua
21
control.lua
@ -13,17 +13,7 @@ require 'utils.utils'
|
||||
require 'utils.pause_game'
|
||||
require 'utils.table'
|
||||
require 'utils.whisper_notice'
|
||||
require 'utils.datastore.server_ups_data'
|
||||
require 'utils.datastore.current_time_data'
|
||||
require 'utils.datastore.color_data'
|
||||
require 'utils.datastore.session_data'
|
||||
require 'utils.datastore.jail_data'
|
||||
require 'utils.datastore.quickbar_data'
|
||||
require 'utils.datastore.warning_on_join_data'
|
||||
require 'utils.datastore.message_on_join_data'
|
||||
require 'utils.datastore.player_tag_data'
|
||||
require 'utils.datastore.supporters'
|
||||
require 'utils.datastore.banhandler'
|
||||
require 'utils.datastore.init'
|
||||
require 'utils.chatbot'
|
||||
require 'utils.commands'
|
||||
require 'utils.antigrief'
|
||||
@ -35,14 +25,7 @@ require 'modules.inserter_drops_pickup'
|
||||
require 'modules.autostash'
|
||||
require 'modules.blueprint_requesting'
|
||||
|
||||
require 'utils.gui'
|
||||
require 'utils.gui.player_list'
|
||||
require 'utils.gui.admin'
|
||||
require 'utils.gui.group'
|
||||
require 'utils.gui.score'
|
||||
require 'utils.gui.config'
|
||||
require 'utils.gui.poll'
|
||||
require 'utils.gui.server_select'
|
||||
require 'utils.gui.init'
|
||||
require 'utils.freeplay'
|
||||
require 'utils.remote_chunks'
|
||||
|
||||
|
@ -148,9 +148,12 @@ linked=[font=default-bold]Convert chests to linked: [/font]
|
||||
linked_static=[font=default-bold]Purchase linked chests: [/font]
|
||||
mystical_chest=[font=default-bold]Feeding the hungry chest: [/font]
|
||||
enemies_killed=[font=default-bold]Enemies killed: [/font]
|
||||
enemies_killed_type=[font=default-bold]Enemies killed (__1__): [/font]
|
||||
crafted_items=[font=default-bold]Handcraft item (__1__): [/font]
|
||||
cast_spell=[font=default-bold]Cast spell (__1__): [/font]
|
||||
launch_item=[font=default-bold]Launch item __1__ to orbit: [/font]
|
||||
launch_rockets=[font=default-bold]Rockets launched: [/font]
|
||||
rocks_mined=[font=default-bold]Rocks mined: [/font]
|
||||
trees_mined=[font=default-bold]Trees mined: [/font]
|
||||
minerals_mined=[font=default-bold]Minerals mined: [/font]
|
||||
production=[font=default-bold]Produce the following items: [/font]
|
||||
production_single=[font=default-bold]Produce the following item: [/font]
|
||||
market_spent=[font=default-bold]Spend coins in market: [/font]
|
||||
@ -158,14 +161,15 @@ research=[font=default-bold]Research __1__: [/font]
|
||||
|
||||
season_tooltip=Whenever a new season starts, all buffs are reset.\nGerkiz tries to add new content for each season that starts.\nSeason resets in __1__ days.
|
||||
rounds_survived_tooltip=Winning the game increases this number by 1.\nThis number resets as of now every 2 months.
|
||||
buff_tooltip=Each buff that is given to the players is listed here.\nHover over the icon to the right to view the buffs.
|
||||
buff_tooltip=Each buff that is given to the players is listed here.\nClick the icon to the right to view the buffs.
|
||||
buff_tooltip_click=Click the icon view the buffs.
|
||||
zone_tooltip=Complete this objective by breaching/moving forward until you've reached the given zone.
|
||||
wave_tooltip=Complete this objective by surviving until the given wave.
|
||||
linked_tooltip=Complete this objective by converting the given amount of chests to linked chests.
|
||||
linked_static_tooltip=Complete this objective by purchasing the given amount of linked chests.
|
||||
production_tooltip=Complete this objective by producing the given item(s).
|
||||
time_until_attack_tooltip=Time in either minutes or seconds until the biters attack.
|
||||
generic_tooltip=Complete this and this objective will be marked as complete.
|
||||
generic_tooltip=Complete this to mark the objective as complete.
|
||||
win_conditions_tooltip=In order to win the game, you must complete all these objectives that are listed below! [img=utility/force_editor_icon]
|
||||
tooltip_failed=You've failed to complete this objective. [img=utility/not_available]
|
||||
tooltip_not_completed=This objective has not been completed. [img=utility/not_available]
|
||||
|
@ -147,6 +147,8 @@ distractor=Distractor Capsule
|
||||
defender=Defender Capsule
|
||||
destroyer=Destroyer Capsule
|
||||
warp=Warp Gate
|
||||
mark_spot=X Marks The Spot
|
||||
tidal_wave=Tidal Wave
|
||||
pointy_explosives=Detonate Chest
|
||||
repair_aoe=Repair AOE
|
||||
charge=Charge
|
||||
|
@ -2,6 +2,7 @@ local Event = require 'utils.event'
|
||||
local Public = require 'maps.mountain_fortress_v3.table'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local StatData = require 'utils.datastore.statistics'
|
||||
local insert = table.insert
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
@ -120,9 +121,15 @@ local function on_entity_died(event)
|
||||
if forest_zone then
|
||||
if random(1, 12) == 1 then
|
||||
player.insert({name = 'coin', count = coin_count})
|
||||
if p then
|
||||
StatData.get_data(p.index):increase('coins', coin_count)
|
||||
end
|
||||
end
|
||||
else
|
||||
player.insert({name = 'coin', count = coin_count})
|
||||
if p then
|
||||
StatData.get_data(p.index):increase('coins', coin_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -9,14 +9,15 @@ local Color = require 'utils.color_presets'
|
||||
|
||||
local Public = {}
|
||||
local module_name = '[color=blue][Charging station][/color] '
|
||||
local charging_station_name = Gui.uid_name()
|
||||
|
||||
local function draw_charging_gui(player, activate_custom_buttons)
|
||||
local button =
|
||||
player.gui.top['charging_station'] or
|
||||
player.gui.top[charging_station_name] or
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = 'charging_station',
|
||||
name = charging_station_name,
|
||||
sprite = 'item/battery-mk2-equipment',
|
||||
tooltip = {
|
||||
'modules.charging_station_tooltip'
|
||||
@ -73,6 +74,12 @@ local function charge(player)
|
||||
if not grid or not grid.valid then
|
||||
return player.print(module_name .. 'No valid armor to charge was found.', Color.warning)
|
||||
end
|
||||
|
||||
local ents = player.surface.find_entities_filtered {name = 'accumulator', force = player.force, position = player.position, radius = 13}
|
||||
if not ents or not next(ents) then
|
||||
return player.print(module_name .. 'No accumulators nearby.', Color.warning)
|
||||
end
|
||||
|
||||
local equip = grid.equipment
|
||||
for _, piece in pairs(equip) do
|
||||
if piece.valid and piece.generator_power == 0 then
|
||||
@ -104,7 +111,7 @@ local function on_player_joined_game(event)
|
||||
BottomFrame.add_inner_frame(
|
||||
{
|
||||
player = player,
|
||||
element_name = 'charging_station',
|
||||
element_name = charging_station_name,
|
||||
tooltip = {
|
||||
'modules.charging_station_tooltip'
|
||||
},
|
||||
@ -114,29 +121,24 @@ local function on_player_joined_game(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
if not event then
|
||||
return
|
||||
end
|
||||
if not event.element then
|
||||
return
|
||||
end
|
||||
if not event.element.valid then
|
||||
return
|
||||
end
|
||||
if event.element.name == 'charging_station' then
|
||||
local player = game.players[event.player_index]
|
||||
Gui.on_click(
|
||||
charging_station_name,
|
||||
function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local is_spamming = SpamProtection.is_spamming(player, nil, 'Charging Station Gui Click')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
|
||||
charge(player)
|
||||
return
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
|
||||
Event.add(
|
||||
BottomFrame.events.bottom_quickbar_location_changed,
|
||||
|
@ -6,7 +6,7 @@ local Collapse = require 'modules.collapse'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Discord = require 'utils.discord_handler'
|
||||
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
|
||||
local scenario_name = 'Mtn Fortress'
|
||||
local scenario_name = Public.scenario_name
|
||||
|
||||
commands.add_command(
|
||||
'scenario',
|
||||
|
@ -14,6 +14,9 @@ local Diff = require 'modules.difficulty_vote_by_amount'
|
||||
local format_number = require 'util'.format_number
|
||||
local RPG_Progression = require 'utils.datastore.rpg_data'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local scenario_name = Public.scenario_name
|
||||
local StatData = require 'utils.datastore.statistics'
|
||||
StatData.add_normalize('coins', 'Coins collected'):set_tooltip('The amount of coins the player has collected through mining/killed enemies.')
|
||||
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
@ -470,8 +473,12 @@ local function give_coin(player)
|
||||
if coin_amount >= 1 then
|
||||
if coin_override then
|
||||
player.insert({name = 'coin', count = coin_override})
|
||||
StatData.get_data(player):increase('coins', coin_override)
|
||||
else
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
player.insert({name = 'coin', count = random(1, coin_amount)})
|
||||
|
||||
StatData.get_data(player):increase('coins', coin_amount)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1230,7 +1237,7 @@ local function show_mvps(player)
|
||||
miners_label_text.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
|
||||
|
||||
local sent_to_discord = Public.get('sent_to_discord')
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
|
||||
if not sent_to_discord and server_name_matches then
|
||||
local message = {
|
||||
@ -1704,7 +1711,7 @@ local on_player_or_robot_built_tile = function(event)
|
||||
if not tiles then
|
||||
return
|
||||
end
|
||||
for k, v in pairs(tiles) do
|
||||
for _, v in pairs(tiles) do
|
||||
local old_tile = v.old_tile
|
||||
if old_tile.name == 'black-refined-concrete' then
|
||||
surface.set_tiles({{name = 'black-refined-concrete', position = v.position}}, true)
|
||||
|
@ -30,6 +30,8 @@ local this = {
|
||||
magic_fluid_crafters = {index = 1},
|
||||
art_table = {index = 1},
|
||||
editor_mode = {},
|
||||
techs = {},
|
||||
limit_types = {},
|
||||
starting_items = {
|
||||
['pistol'] = {
|
||||
count = 1
|
||||
@ -1342,6 +1344,7 @@ function Public.on_player_joined_game(event)
|
||||
local death_message = ({'main.death_mode_warning'})
|
||||
Alert.alert_player(player, 15, death_message)
|
||||
end
|
||||
player.clear_items_inside()
|
||||
for item, data in pairs(this.starting_items) do
|
||||
player.insert({name = item, count = data.count})
|
||||
end
|
||||
@ -1793,12 +1796,12 @@ function Public.equip_players(starting_items, recreate)
|
||||
if player.character and player.character.valid then
|
||||
player.character.destroy()
|
||||
end
|
||||
player.clear_items_inside()
|
||||
if player.connected then
|
||||
if not player.character then
|
||||
player.set_controller({type = defines.controllers.god})
|
||||
player.create_character()
|
||||
end
|
||||
player.clear_items_inside()
|
||||
Modifiers.update_player_modifiers(player)
|
||||
if not recreate then
|
||||
starting_items = starting_items or this.starting_items
|
||||
@ -1821,6 +1824,8 @@ function Public.reset_func_table()
|
||||
this.refill_turrets = {index = 1}
|
||||
this.magic_crafters = {index = 1}
|
||||
this.magic_fluid_crafters = {index = 1}
|
||||
this.techs = {}
|
||||
this.limit_types = {}
|
||||
this.starting_items = {
|
||||
['pistol'] = {
|
||||
count = 1
|
||||
|
@ -25,6 +25,22 @@ local function validate_entity(entity)
|
||||
return true
|
||||
end
|
||||
|
||||
local function get_top_frame(player)
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
return Gui.get_button_flow(player)[main_frame_name]
|
||||
else
|
||||
return player.gui.top[main_frame_name]
|
||||
end
|
||||
end
|
||||
|
||||
local function get_top_frame_custom(player, name)
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
return Gui.get_button_flow(player)[name]
|
||||
else
|
||||
return player.gui.top[name]
|
||||
end
|
||||
end
|
||||
|
||||
local function validate_player(player)
|
||||
if not player then
|
||||
return false
|
||||
@ -45,22 +61,44 @@ local function validate_player(player)
|
||||
end
|
||||
|
||||
local function create_button(player)
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'item/dummy-steel-axe',
|
||||
tooltip = 'Shows statistics!',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'item/dummy-steel-axe',
|
||||
tooltip = 'Shows statistics!',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'item/dummy-steel-axe',
|
||||
tooltip = 'Shows statistics!',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
end
|
||||
end
|
||||
|
||||
local function spectate_button(player)
|
||||
if player.gui.top[spectate_button_name] then
|
||||
if get_top_frame_custom(player, spectate_button_name) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -68,29 +106,68 @@ local function spectate_button(player)
|
||||
return
|
||||
end
|
||||
|
||||
local b =
|
||||
player.gui.top.add {
|
||||
type = 'sprite-button',
|
||||
name = spectate_button_name,
|
||||
sprite = 'utility/ghost_time_to_live_modifier_icon',
|
||||
tooltip = 'Spectate!\nThis will kill your character.',
|
||||
style = Gui.button_style
|
||||
}
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = spectate_button_name,
|
||||
sprite = 'utility/ghost_time_to_live_modifier_icon',
|
||||
tooltip = 'Spectate!\nThis will kill your character.',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local b =
|
||||
player.gui.top.add {
|
||||
type = 'sprite-button',
|
||||
name = spectate_button_name,
|
||||
sprite = 'utility/ghost_time_to_live_modifier_icon',
|
||||
tooltip = 'Spectate!\nThis will kill your character.',
|
||||
style = Gui.button_style
|
||||
}
|
||||
|
||||
b.style.maximal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
end
|
||||
end
|
||||
|
||||
local function create_main_frame(player)
|
||||
local label
|
||||
local line
|
||||
if player.gui.top['wave_defense'] then
|
||||
player.gui.top['wave_defense'].visible = true
|
||||
if get_top_frame_custom(player, 'wave_defense') then
|
||||
get_top_frame_custom(player, 'wave_defense').visible = true
|
||||
end
|
||||
|
||||
local frame = player.gui.top.add({type = 'frame', name = main_frame_name, style = 'finished_game_subheader_frame'})
|
||||
frame.location = {x = 1, y = 40}
|
||||
frame.style.minimal_height = 38
|
||||
frame.style.maximal_height = 38
|
||||
local frame
|
||||
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
frame =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'frame',
|
||||
name = main_frame_name,
|
||||
style = 'finished_game_subheader_frame'
|
||||
}
|
||||
)
|
||||
frame.location = {x = 1, y = 38}
|
||||
frame.style.minimal_height = 36
|
||||
frame.style.maximal_height = 36
|
||||
else
|
||||
frame = player.gui.top.add({type = 'frame', name = main_frame_name, style = 'finished_game_subheader_frame'})
|
||||
frame.location = {x = 1, y = 40}
|
||||
frame.style.minimal_height = 38
|
||||
frame.style.maximal_height = 38
|
||||
end
|
||||
|
||||
label = frame.add({type = 'label', caption = ' ', name = 'label'})
|
||||
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
|
||||
@ -166,17 +243,33 @@ local function create_main_frame(player)
|
||||
end
|
||||
|
||||
local function hide_all_gui(player)
|
||||
for _, child in pairs(player.gui.top.children) do
|
||||
if child.name ~= spectate_button_name and child.name ~= 'minimap_button' and child.name ~= 'wave_defense' then
|
||||
child.visible = false
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
for _, child in pairs(player.gui.top.mod_gui_top_frame.mod_gui_inner_frame.children) do
|
||||
if child.name ~= spectate_button_name and child.name ~= 'minimap_button' and child.name ~= 'wave_defense' then
|
||||
child.visible = false
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, child in pairs(player.gui.top.children) do
|
||||
if child.name ~= spectate_button_name and child.name ~= 'minimap_button' and child.name ~= 'wave_defense' then
|
||||
child.visible = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function show_all_gui(player)
|
||||
for _, child in pairs(player.gui.top.children) do
|
||||
if child.name ~= spectate_button_name and child.name ~= 'minimap_button' then
|
||||
child.visible = true
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
for _, child in pairs(player.gui.top.mod_gui_top_frame.mod_gui_inner_frame.children) do
|
||||
if child.name ~= spectate_button_name and child.name ~= 'minimap_button' then
|
||||
child.visible = true
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, child in pairs(player.gui.top.children) do
|
||||
if child.name ~= spectate_button_name and child.name ~= 'minimap_button' then
|
||||
child.visible = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -187,11 +280,11 @@ local function on_player_joined_game(event)
|
||||
return
|
||||
end
|
||||
|
||||
if not player.gui.top[spectate_button_name] then
|
||||
if not get_top_frame_custom(player, spectate_button_name) then
|
||||
spectate_button(player)
|
||||
end
|
||||
|
||||
if not player.gui.top[main_button_name] then
|
||||
if not get_top_frame_custom(player, main_button_name) then
|
||||
create_button(player)
|
||||
end
|
||||
end
|
||||
@ -209,19 +302,19 @@ local function changed_surface(player)
|
||||
end
|
||||
|
||||
local wagon_surface = icw_locomotive.surface
|
||||
local main_toggle_button = player.gui.top[main_toggle_button_name]
|
||||
local info = player.gui.top[main_button_name]
|
||||
local wd = player.gui.top['wave_defense']
|
||||
local spectate = player.gui.top[spectate_button_name]
|
||||
local minimap_button = player.gui.top['minimap_button']
|
||||
local rpg_b = player.gui.top[rpg_button]
|
||||
local poll_b = player.gui.top[poll_button]
|
||||
local main_toggle_button = get_top_frame_custom(player, main_toggle_button_name)
|
||||
local info = get_top_frame_custom(player, main_button_name)
|
||||
local wd = get_top_frame_custom(player, 'wave_defense')
|
||||
local spectate = get_top_frame_custom(player, spectate_button_name)
|
||||
local minimap_button = get_top_frame_custom(player, 'minimap_button')
|
||||
local rpg_b = get_top_frame_custom(player, rpg_button)
|
||||
local poll_b = get_top_frame_custom(player, poll_button)
|
||||
local rpg_f = player.gui.screen[rpg_frame]
|
||||
local rpg_s = player.gui.screen[rpg_settings]
|
||||
local diff = player.gui.top[Difficulty.top_button_name]
|
||||
local charging = player.gui.top['charging_station']
|
||||
local diff = get_top_frame_custom(player, Difficulty.top_button_name)
|
||||
local charging = get_top_frame_custom(player, 'charging_station')
|
||||
local charging_frame = BottomFrame.get_section(player, 'charging_station')
|
||||
local frame = player.gui.top[main_frame_name]
|
||||
local frame = get_top_frame(player)
|
||||
local spell_gui_frame_name = RPG.spell_gui_frame_name
|
||||
local spell_cast_buttons = player.gui.screen[spell_gui_frame_name]
|
||||
|
||||
@ -326,7 +419,7 @@ local function changed_surface(player)
|
||||
info.sprite = 'utility/map'
|
||||
info.visible = true
|
||||
end
|
||||
if player.gui.top[main_frame_name] then
|
||||
if get_top_frame(player) then
|
||||
if frame then
|
||||
frame.visible = false
|
||||
return
|
||||
@ -391,10 +484,10 @@ local function on_gui_click(event)
|
||||
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 get_top_frame(player) then
|
||||
local info = get_top_frame(player)
|
||||
local wd = get_top_frame_custom(player, 'wave_defense')
|
||||
local diff = get_top_frame_custom(player, Difficulty.top_button_name)
|
||||
|
||||
if info and info.visible then
|
||||
if wd then
|
||||
@ -453,14 +546,14 @@ local function enable_guis(event)
|
||||
end
|
||||
|
||||
local main_toggle_button_name = Gui.main_toggle_button_name
|
||||
local main_toggle_button = player.gui.top[main_toggle_button_name]
|
||||
local main_toggle_button = get_top_frame_custom(player, main_toggle_button_name)
|
||||
local rpg_button = RPG.draw_main_frame_name
|
||||
local info = player.gui.top[main_button_name]
|
||||
local wd = player.gui.top['wave_defense']
|
||||
local spectate = player.gui.top[spectate_button_name]
|
||||
local rpg_b = player.gui.top[rpg_button]
|
||||
local diff = player.gui.top[Difficulty.top_button_name]
|
||||
local charging = player.gui.top['charging_station']
|
||||
local info = get_top_frame_custom(player, main_button_name)
|
||||
local wd = get_top_frame_custom(player, 'wave_defense')
|
||||
local spectate = get_top_frame_custom(player, spectate_button_name)
|
||||
local rpg_b = get_top_frame_custom(player, rpg_button)
|
||||
local diff = get_top_frame_custom(player, Difficulty.top_button_name)
|
||||
local charging = get_top_frame_custom(player, 'charging_station')
|
||||
local charging_frame = BottomFrame.get_section(player, 'charging_station')
|
||||
|
||||
IC_Gui.remove_toolbar(player)
|
||||
@ -511,14 +604,14 @@ function Public.update_gui(player)
|
||||
return
|
||||
end
|
||||
|
||||
if not player.gui.top[main_frame_name] then
|
||||
if not get_top_frame(player) then
|
||||
return
|
||||
end
|
||||
|
||||
if not player.gui.top[main_frame_name].visible then
|
||||
if not get_top_frame(player).visible then
|
||||
return
|
||||
end
|
||||
local gui = player.gui.top[main_frame_name]
|
||||
local gui = get_top_frame(player)
|
||||
|
||||
local rpg_extra = RPG.get('rpg_extra')
|
||||
local mined_scrap = Public.get('mined_scrap')
|
||||
|
@ -957,22 +957,42 @@ end
|
||||
|
||||
function Public.kill_car_but_save_surface(entity)
|
||||
if not validate_entity(entity) then
|
||||
return
|
||||
return nil
|
||||
end
|
||||
|
||||
local entity_type = IC.get('entity_type')
|
||||
|
||||
if not entity_type[entity.type] then
|
||||
return
|
||||
return nil
|
||||
end
|
||||
|
||||
local cars = IC.get('cars')
|
||||
local car = cars[entity.unit_number]
|
||||
if not car then
|
||||
return nil
|
||||
end
|
||||
|
||||
local surface_index = car.surface
|
||||
local surface = game.get_surface(surface_index)
|
||||
if not surface then
|
||||
return nil
|
||||
end
|
||||
|
||||
local c = 0
|
||||
local entities = surface.find_entities_filtered({area = car.area, force = 'player'})
|
||||
if entities and #entities > 0 then
|
||||
for _, e in pairs(entities) do
|
||||
if e and e.valid and e.name ~= 'character' then
|
||||
c = c + 1
|
||||
end
|
||||
end
|
||||
if c > 0 then
|
||||
return false, c
|
||||
end
|
||||
end
|
||||
|
||||
local surfaces = IC.get('surfaces')
|
||||
local surfaces_deleted_by_button = IC.get('surfaces_deleted_by_button')
|
||||
local cars = IC.get('cars')
|
||||
local car = cars[entity.unit_number]
|
||||
if not car then
|
||||
return
|
||||
end
|
||||
|
||||
kick_players_out_of_vehicles(car)
|
||||
kick_players_from_surface(car)
|
||||
@ -992,7 +1012,7 @@ function Public.kill_car_but_save_surface(entity)
|
||||
end
|
||||
|
||||
if not owner then
|
||||
return
|
||||
return nil
|
||||
end
|
||||
|
||||
local renders = IC.get('renders')
|
||||
@ -1017,9 +1037,6 @@ function Public.kill_car_but_save_surface(entity)
|
||||
misc_settings[owner.index] = nil
|
||||
end
|
||||
|
||||
local surface_index = car.surface
|
||||
local surface = game.surfaces[surface_index]
|
||||
|
||||
if not surfaces_deleted_by_button[owner.name] then
|
||||
surfaces_deleted_by_button[owner.name] = {}
|
||||
end
|
||||
@ -1030,6 +1047,7 @@ function Public.kill_car_but_save_surface(entity)
|
||||
car.entity.force.chart(surface, car.area)
|
||||
surfaces[entity.unit_number] = nil
|
||||
cars[entity.unit_number] = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.validate_owner(player, entity)
|
||||
|
@ -6,6 +6,7 @@ local Tabs = require 'utils.gui'
|
||||
local Event = require 'utils.event'
|
||||
local Task = require 'utils.task_token'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local Discord = require 'utils.discord_handler'
|
||||
|
||||
local Public = {}
|
||||
local insert = table.insert
|
||||
@ -29,10 +30,19 @@ local allow_anyone_to_enter_name = Gui.uid_name()
|
||||
local auto_upgrade_name = Gui.uid_name()
|
||||
local kick_player_name = Gui.uid_name()
|
||||
local destroy_surface_name = Gui.uid_name()
|
||||
local scenario_name = 'Mtn Fortress'
|
||||
|
||||
local add_toolbar
|
||||
local remove_toolbar
|
||||
|
||||
local function get_top_frame(player)
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
return Gui.get_button_flow(player)[main_toolbar_name]
|
||||
else
|
||||
return player.gui.top[main_toolbar_name]
|
||||
end
|
||||
end
|
||||
|
||||
local function increment(t, k)
|
||||
t[k] = true
|
||||
end
|
||||
@ -448,28 +458,50 @@ end
|
||||
|
||||
add_toolbar = function(player, remove)
|
||||
if remove then
|
||||
if player.gui.top[main_toolbar_name] then
|
||||
player.gui.top[main_toolbar_name].destroy()
|
||||
if get_top_frame(player) then
|
||||
get_top_frame(player).destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
if player.gui.top[main_toolbar_name] then
|
||||
if get_top_frame(player) then
|
||||
return
|
||||
end
|
||||
|
||||
local tooltip = ({'ic.control'})
|
||||
local button =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/spidertron',
|
||||
name = main_toolbar_name,
|
||||
tooltip = tooltip,
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
button.style.minimal_height = 38
|
||||
button.style.maximal_height = 38
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_toolbar_name,
|
||||
sprite = 'item/spidertron',
|
||||
tooltip = tooltip,
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local button =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/spidertron',
|
||||
name = main_toolbar_name,
|
||||
tooltip = tooltip,
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
button.style.minimal_height = 38
|
||||
button.style.maximal_height = 38
|
||||
end
|
||||
end
|
||||
|
||||
remove_toolbar = function(player)
|
||||
@ -480,8 +512,8 @@ remove_toolbar = function(player)
|
||||
remove_main_frame(main_frame)
|
||||
end
|
||||
|
||||
if player.gui.top[main_toolbar_name] then
|
||||
player.gui.top[main_toolbar_name].destroy()
|
||||
if get_top_frame(player) then
|
||||
get_top_frame(player).destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -811,8 +843,14 @@ Gui.on_click(
|
||||
|
||||
local entity = car.entity
|
||||
if entity and entity.valid then
|
||||
Functions.kill_car_but_save_surface(entity)
|
||||
game.print('[IC] ' .. player.name .. ' has destroyed their surface!', Color.warning)
|
||||
local position = entity.position
|
||||
local suc, count = Functions.kill_car_but_save_surface(entity)
|
||||
if suc then
|
||||
game.print('[IC] ' .. player.name .. ' has destroyed their surface!', Color.warning)
|
||||
Discord.send_notification_raw(scenario_name, player.name .. ' deleted their vehicle surface at x = ' .. position.x .. ' y = ' .. position.y .. '.')
|
||||
else
|
||||
player.print('[IC] Entities are still on the surface. Please remove any entities and retry this operation. Found ' .. count .. ' entities!', Color.warning)
|
||||
end
|
||||
end
|
||||
|
||||
remove_main_frame(event.element)
|
||||
|
@ -24,28 +24,58 @@ local function validate_player(player)
|
||||
return true
|
||||
end
|
||||
|
||||
local function get_top_frame(player)
|
||||
if CoreGui.get_mod_gui_top_frame() then
|
||||
return CoreGui.get_button_flow(player)['minimap_button']
|
||||
else
|
||||
return player.gui.top['minimap_button']
|
||||
end
|
||||
end
|
||||
|
||||
local function create_button(player)
|
||||
local button =
|
||||
player.gui.top['minimap_button'] or
|
||||
player.gui.top.add(
|
||||
if CoreGui.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
CoreGui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = 'minimap_button',
|
||||
sprite = 'utility/map',
|
||||
tooltip = 'Open or close minimap.',
|
||||
style = CoreGui.button_style
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
button.style.minimal_height = 38
|
||||
button.style.maximal_height = 38
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local button =
|
||||
player.gui.top['minimap_button'] or
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = 'minimap_button',
|
||||
sprite = 'utility/map',
|
||||
tooltip = 'Open or close minimap.',
|
||||
style = CoreGui.button_style
|
||||
}
|
||||
)
|
||||
button.style.minimal_height = 38
|
||||
button.style.maximal_height = 38
|
||||
end
|
||||
end
|
||||
|
||||
function Public.toggle_button(player)
|
||||
if not player.gui.top['minimap_button'] then
|
||||
if not get_top_frame(player) then
|
||||
create_button(player)
|
||||
end
|
||||
|
||||
local button = player.gui.top['minimap_button']
|
||||
local button = get_top_frame(player)
|
||||
if Functions.get_player_surface(player) then
|
||||
create_button(player)
|
||||
else
|
||||
@ -175,7 +205,7 @@ function Public.minimap(player, surface, position)
|
||||
end
|
||||
|
||||
function Public.update_minimap()
|
||||
for k, player in pairs(game.connected_players) do
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local player_data = get_player_data(player)
|
||||
if Functions.get_player_surface(player) and player.gui.left.minimap_toggle_frame and player_data.auto then
|
||||
kill_frame(player)
|
||||
|
@ -429,6 +429,27 @@ local function get_items()
|
||||
upgrade = false,
|
||||
static = false
|
||||
}
|
||||
if upgrades.burner_generator.bought >= upgrades.burner_generator.limit then
|
||||
main_market_items['burner-generator'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = 300,
|
||||
tooltip = ({'main_market.sold_out'}),
|
||||
enabled = false,
|
||||
upgrade = false,
|
||||
static = true
|
||||
}
|
||||
else
|
||||
main_market_items['burner-generator'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = 300,
|
||||
tooltip = {'', {'item-name.burner-generator'}, ' bought: ', upgrades.burner_generator.bought, '/', upgrades.burner_generator.limit},
|
||||
upgrade = false,
|
||||
static = true
|
||||
}
|
||||
end
|
||||
|
||||
main_market_items['car'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
@ -974,6 +995,31 @@ local function gui_click(event)
|
||||
LinkedChests.set('converted_chests', converted_chests + 1)
|
||||
end
|
||||
|
||||
if name == 'burner-generator' then
|
||||
if this.upgrades.burner_generator.bought >= this.upgrades.burner_generator.limit then
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
player.print(({'locomotive.limit_reached'}), {r = 0.98, g = 0.66, b = 0.22})
|
||||
return
|
||||
end
|
||||
player.remove_item({name = item.value, count = item.price})
|
||||
|
||||
player.insert({name = name, count = item.stack})
|
||||
|
||||
Event.raise(Public.events.on_market_item_purchased, {cost = item.price})
|
||||
|
||||
if item.stack > this.upgrades.burner_generator.limit then
|
||||
item.stack = this.upgrades.burner_generator.limit
|
||||
end
|
||||
|
||||
this.upgrades.burner_generator.bought = this.upgrades.burner_generator.bought + item.stack
|
||||
|
||||
this.upgrades.train_upgrade_contribution = this.upgrades.train_upgrade_contribution + item.price
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
redraw_coins_left(data.coins_left, player)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if name == 'upgrade_pickaxe' then
|
||||
player.remove_item({name = item.value, count = item.price})
|
||||
|
||||
|
@ -195,11 +195,17 @@ function Public.locomotive_spawn(surface, position, reversed)
|
||||
)
|
||||
end
|
||||
|
||||
local s = 'entity/compilatron'
|
||||
|
||||
if random(1, 10) == 1 then
|
||||
s = 'entity/character-corpse'
|
||||
end
|
||||
|
||||
for y = -1, 0, 0.05 do
|
||||
local scale = random(50, 100) * 0.01
|
||||
rendering.draw_sprite(
|
||||
{
|
||||
sprite = 'entity/small-biter',
|
||||
sprite = s,
|
||||
orientation = random(0, 100) * 0.01,
|
||||
x_scale = scale,
|
||||
y_scale = scale,
|
||||
@ -229,6 +235,8 @@ function Public.locomotive_spawn(surface, position, reversed)
|
||||
surface = locomotive.surface
|
||||
}
|
||||
|
||||
log(serpent.block(extra_wagons))
|
||||
|
||||
if extra_wagons and extra_wagons > 0 then
|
||||
local inc = 7
|
||||
|
||||
|
@ -46,6 +46,7 @@ local Beam = require 'modules.render_beam'
|
||||
-- Use these settings for live
|
||||
local send_ping_to_channel = Discord.channel_names.mtn_channel
|
||||
local role_to_mention = Discord.role_mentions.mtn_fortress
|
||||
local scenario_name = Public.scenario_name
|
||||
-- Use these settings for testing
|
||||
-- bot-lounge
|
||||
-- local send_ping_to_channel = Discord.channel_names.bot_quarters
|
||||
@ -107,7 +108,7 @@ end
|
||||
local announce_new_map =
|
||||
Task.register(
|
||||
function()
|
||||
local server_name = Server.check_server_name('Mtn Fortress')
|
||||
local server_name = Server.check_server_name(scenario_name)
|
||||
if server_name then
|
||||
Server.to_discord_named_raw(send_ping_to_channel, role_to_mention .. ' ** Mtn Fortress was just reset! **')
|
||||
end
|
||||
@ -115,9 +116,12 @@ local announce_new_map =
|
||||
)
|
||||
|
||||
function Public.reset_map()
|
||||
log(serpent.block('resetting map'))
|
||||
game.forces.player.reset()
|
||||
Public.reset_main_table()
|
||||
|
||||
Difficulty.show_gui(false)
|
||||
|
||||
local this = Public.get()
|
||||
local wave_defense_table = WD.get_table()
|
||||
Misc.reset()
|
||||
@ -199,6 +203,7 @@ function Public.reset_map()
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
Difficulty.clear_top_frame(player)
|
||||
Score.init_player_table(player, true)
|
||||
Misc.insert_all_items(player)
|
||||
Modifiers.reset_player_modifiers(player)
|
||||
@ -211,7 +216,6 @@ function Public.reset_map()
|
||||
|
||||
Difficulty.reset_difficulty_poll({closing_timeout = game.tick + 36000})
|
||||
Difficulty.set_gui_width(20)
|
||||
Difficulty.show_gui(false)
|
||||
|
||||
Collapse.set_kill_entities(false)
|
||||
Collapse.set_kill_specific_entities(collapse_kill)
|
||||
@ -224,6 +228,12 @@ function Public.reset_map()
|
||||
Collapse.start_now(false)
|
||||
Collapse.disable_collapse(false)
|
||||
|
||||
Public.stateful.enable(true)
|
||||
Public.stateful.create()
|
||||
Public.stateful.reset_stateful(true, true)
|
||||
Public.stateful.increase_enemy_damage_and_health()
|
||||
Public.stateful.apply_startup_settings()
|
||||
|
||||
this.locomotive_health = 10000
|
||||
this.locomotive_max_health = 10000
|
||||
|
||||
@ -298,11 +308,6 @@ function Public.reset_map()
|
||||
this.game_lost = false
|
||||
|
||||
RPG.reset_table()
|
||||
Public.stateful.enable(true)
|
||||
Public.stateful.create()
|
||||
Public.stateful.reset_stateful(true, true)
|
||||
Public.stateful.increase_enemy_damage_and_health()
|
||||
Public.stateful.apply_startup_settings()
|
||||
|
||||
RPG.rpg_reset_all_players()
|
||||
RPG.set_surface_name({game.surfaces[this.active_surface_index].name, 'boss_room'})
|
||||
|
@ -4,6 +4,7 @@ local Public = require 'maps.mountain_fortress_v3.table'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
local Alert = require 'utils.alert'
|
||||
local Task = require 'utils.task_token'
|
||||
local StatData = require 'utils.datastore.statistics'
|
||||
|
||||
local shuffle = table.shuffle_table
|
||||
local random = math.random
|
||||
@ -330,6 +331,7 @@ local mc_random_rewards = {
|
||||
if player and player.valid then
|
||||
if player.can_insert({name = 'coin', count = rng}) then
|
||||
player.insert({name = 'coin', count = rng})
|
||||
StatData.get_data(player):increase('coins', rng)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -12,6 +12,7 @@ local score_key = 'mtn_v3'
|
||||
local score_key_dev = 'mtn_v3_dev'
|
||||
local set_data = Server.set_data
|
||||
local try_get_data = Server.try_get_data
|
||||
local scenario_name = Public.scenario_name
|
||||
|
||||
local insert = table.insert
|
||||
|
||||
@ -87,7 +88,7 @@ function Public.get_season_scores()
|
||||
if not secs then
|
||||
return
|
||||
else
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
if server_name_matches then
|
||||
try_get_data(score_dataset, score_key, get_scores)
|
||||
else
|
||||
@ -102,7 +103,7 @@ function Public.set_season_scores()
|
||||
if not secs then
|
||||
return
|
||||
else
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
if server_name_matches then
|
||||
write_additional_stats(score_key)
|
||||
else
|
||||
|
@ -19,8 +19,12 @@ local main_button_name = Gui.uid_name()
|
||||
local main_frame_name = Gui.uid_name()
|
||||
local boss_frame_name = Gui.uid_name()
|
||||
local close_button = Gui.uid_name()
|
||||
local close_buffs_window_name = Gui.uid_name()
|
||||
local buffs_window_name = Gui.uid_name()
|
||||
local on_click_buff_name = Gui.uid_name()
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local scenario_name = Public.scenario_name
|
||||
local main_frame
|
||||
|
||||
local function create_particles(surface, name, position, amount, cause_position)
|
||||
@ -68,11 +72,17 @@ local spread_particles_token =
|
||||
end
|
||||
)
|
||||
|
||||
local function pretty_format(input)
|
||||
local action = string.gsub(input, '-', ' ')
|
||||
local result = string.upper(string.sub(action, 1, 1)) .. string.sub(action, 2)
|
||||
return result
|
||||
end
|
||||
|
||||
local function notify_won_to_discord(buff)
|
||||
if not buff then
|
||||
return error('Buff is required when sending message to discord.', 2)
|
||||
end
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
|
||||
local stateful = Public.get_stateful()
|
||||
|
||||
@ -182,18 +192,62 @@ local warn_player_sound_token =
|
||||
)
|
||||
|
||||
local function create_button(player)
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'utility/custom_tag_icon',
|
||||
tooltip = 'Has information about all objectives that needs to be completed',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'utility/custom_tag_icon',
|
||||
tooltip = 'Has information about all objectives that needs to be completed',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'utility/custom_tag_icon',
|
||||
tooltip = 'Has information about all objectives that needs to be completed',
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
end
|
||||
end
|
||||
|
||||
local function create_input_element(frame, type, value, items, index, tooltip, custom_space)
|
||||
if type == 'slider' then
|
||||
return frame.add({type = 'slider', value = value, minimum_value = 0, maximum_value = 1})
|
||||
end
|
||||
if type == 'boolean' then
|
||||
return frame.add({type = 'checkbox', state = value})
|
||||
end
|
||||
if type == 'label' then
|
||||
local label = frame.add({type = 'label', caption = value})
|
||||
label.style.font = 'default-listbox'
|
||||
label.tooltip = tooltip or ''
|
||||
if custom_space then
|
||||
label.style.minimal_height = custom_space
|
||||
end
|
||||
return label
|
||||
end
|
||||
if type == 'dropdown' then
|
||||
return frame.add({type = 'drop-down', items = items, selected_index = index})
|
||||
end
|
||||
return frame.add({type = 'text-box', text = value})
|
||||
end
|
||||
|
||||
local function play_game_won()
|
||||
@ -321,6 +375,111 @@ local function objective_frames(stateful, player_frame, objective, data)
|
||||
return
|
||||
end
|
||||
|
||||
local function buff_window(player)
|
||||
local buff_frame_name, inside_table = Gui.add_main_frame_with_toolbar(player, 'center', buffs_window_name, nil, close_buffs_window_name, 'Buffs gathered')
|
||||
if not buff_frame_name then
|
||||
return
|
||||
end
|
||||
if not inside_table then
|
||||
return
|
||||
end
|
||||
|
||||
local stateful = Public.get_stateful()
|
||||
|
||||
local inside_table_style = inside_table.style
|
||||
inside_table_style.width = 530
|
||||
|
||||
local info_text = inside_table.add({type = 'label', caption = 'All the buffs that have been gathered throughout the runs!'})
|
||||
local info_text_style = info_text.style
|
||||
info_text_style.font = 'heading-2'
|
||||
info_text_style.padding = 0
|
||||
info_text_style.left_padding = 10
|
||||
info_text_style.horizontal_align = 'left'
|
||||
info_text_style.vertical_align = 'bottom'
|
||||
info_text_style.font_color = {0.55, 0.55, 0.99}
|
||||
|
||||
local buff_pane = inside_table.add({type = 'scroll-pane'})
|
||||
local ns = buff_pane.style
|
||||
ns.vertically_squashable = true
|
||||
ns.bottom_padding = 5
|
||||
ns.left_padding = 5
|
||||
ns.right_padding = 5
|
||||
ns.top_padding = 5
|
||||
|
||||
buff_pane.add({type = 'line'})
|
||||
|
||||
local starting_items_label = buff_pane.add({type = 'label', caption = 'Starting items'})
|
||||
local starting_items_label_style = starting_items_label.style
|
||||
starting_items_label_style.font = 'heading-3'
|
||||
starting_items_label_style.padding = 0
|
||||
starting_items_label_style.horizontal_align = 'left'
|
||||
starting_items_label_style.font_color = {0.55, 0.55, 0.99}
|
||||
|
||||
local starting_grid = buff_pane.add({type = 'table', column_count = 8})
|
||||
|
||||
buff_pane.add({type = 'line'})
|
||||
|
||||
local force_label = buff_pane.add({type = 'label', caption = 'Force Buffs'})
|
||||
local force_label_style = force_label.style
|
||||
force_label_style.font = 'heading-3'
|
||||
force_label_style.padding = 0
|
||||
force_label_style.horizontal_align = 'left'
|
||||
force_label_style.font_color = {0.55, 0.55, 0.99}
|
||||
local force_grid = buff_pane.add({type = 'table', column_count = 2})
|
||||
|
||||
buff_pane.add({type = 'line'})
|
||||
|
||||
local custom_label = buff_pane.add({type = 'label', caption = 'Custom Buffs'})
|
||||
local custom_label_style = custom_label.style
|
||||
custom_label_style.font = 'heading-3'
|
||||
custom_label_style.padding = 0
|
||||
custom_label_style.horizontal_align = 'left'
|
||||
custom_label_style.font_color = {0.55, 0.55, 0.99}
|
||||
local custom_grid = buff_pane.add({type = 'table', column_count = 2})
|
||||
|
||||
if stateful.buffs and next(stateful.buffs) then
|
||||
if stateful.buffs_collected and next(stateful.buffs_collected) then
|
||||
if stateful.buffs_collected.starting_items then
|
||||
for item_name, item_data in pairs(stateful.buffs_collected.starting_items) do
|
||||
-- local text = pretty_format(item_name) .. ': [font=font-bold]' .. item_data.count
|
||||
local text = '[font=default-large] [item=' .. item_name .. '][/font]' .. ': [font=default-bold]' .. item_data.count .. '[/font]'
|
||||
create_input_element(starting_grid, 'label', text, nil, nil, item_data.discord, 30)
|
||||
end
|
||||
end
|
||||
|
||||
for name, buff_data in pairs(stateful.buffs_collected) do
|
||||
if type(buff_data.amount) ~= 'table' and buff_data.force then
|
||||
local c = buff_data.count
|
||||
local text
|
||||
if name == 'xp_level' or name == 'xp_bonus' or name == 'character_health_bonus' then
|
||||
text = '[font=default-bold]' .. Stateful.buff_to_string[name] .. ': ' .. c .. '[/font]'
|
||||
else
|
||||
text = '[font=default-bold]' .. Stateful.buff_to_string[name] .. ': ' .. (c * 100) .. '%[/font]'
|
||||
end
|
||||
|
||||
create_input_element(force_grid, 'label', text, nil, nil, buff_data.discord)
|
||||
end
|
||||
|
||||
if name ~= 'starting_items' and not buff_data.force then
|
||||
if buff_data.name then
|
||||
local text_to_place = buff_data.count or 'Unlocked'
|
||||
local text = '[font=default-bold]' .. buff_data.name .. ': ' .. text_to_place .. ' [/font]'
|
||||
create_input_element(custom_grid, 'label', text, nil, nil, buff_data.discord)
|
||||
else
|
||||
for _, buff in pairs(buff_data) do
|
||||
local text_to_place = buff.count or 'Unlocked'
|
||||
local text = '[font=default-bold]' .. pretty_format(buff.name) .. ': ' .. text_to_place .. ' [/font]'
|
||||
create_input_element(custom_grid, 'label', text, nil, nil, buff.discord)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
player.opened = buff_frame_name
|
||||
end
|
||||
|
||||
local function boss_frame(player, alert)
|
||||
local main_winning_frame = player.gui.screen[main_frame_name]
|
||||
if main_winning_frame then
|
||||
@ -480,7 +639,11 @@ main_frame = function(player)
|
||||
local wave_number = WD.get('wave_number')
|
||||
|
||||
local frame = player.gui.screen.add {type = 'frame', name = main_frame_name, caption = {'stateful.win_conditions'}, direction = 'vertical', tooltip = {'stateful.win_conditions_tooltip'}}
|
||||
frame.location = {x = 1, y = 45}
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
frame.location = {x = 0, y = 67}
|
||||
else
|
||||
frame.location = {x = 1, y = 45}
|
||||
end
|
||||
frame.style.maximal_height = 700
|
||||
frame.style.minimal_width = 200
|
||||
frame.style.maximal_width = 400
|
||||
@ -533,31 +696,7 @@ main_frame = function(player)
|
||||
buff_right_flow.style.horizontal_align = 'right'
|
||||
buff_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
local buffs = ''
|
||||
if stateful.buffs_collected and next(stateful.buffs_collected) then
|
||||
if stateful.buffs_collected.starting_items then
|
||||
buffs = buffs .. 'Starting items:\n'
|
||||
for item_name, item_data in pairs(stateful.buffs_collected.starting_items) do
|
||||
buffs = buffs .. item_name .. ': ' .. item_data.count
|
||||
buffs = buffs .. '\n'
|
||||
end
|
||||
buffs = buffs .. '\n'
|
||||
end
|
||||
|
||||
buffs = buffs .. 'Force buffs:\n'
|
||||
for name, buff_data in pairs(stateful.buffs_collected) do
|
||||
if type(buff_data.amount) ~= 'table' and name ~= 'starting_items' then
|
||||
if name == 'xp_level' or name == 'xp_bonus' or name == 'character_health_bonus' then
|
||||
buffs = buffs .. Stateful.buff_to_string[name] .. ': ' .. buff_data.count
|
||||
else
|
||||
buffs = buffs .. Stateful.buff_to_string[name] .. ': ' .. (buff_data.count * 100) .. '%'
|
||||
end
|
||||
buffs = buffs .. '\n'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
buff_right_flow.add({type = 'label', caption = '[img=utility/center]', tooltip = buffs})
|
||||
buff_right_flow.add({name = on_click_buff_name, type = 'label', caption = '[img=utility/center]', tooltip = {'stateful.buff_tooltip_click'}})
|
||||
|
||||
local buff_label = buff_left_flow.add({type = 'label', caption = {'stateful.buffs'}, tooltip = {'stateful.buff_tooltip'}})
|
||||
buff_label.style.single_line = false
|
||||
@ -874,6 +1013,7 @@ local function update_raw()
|
||||
if breached_wall >= stateful.objectives.randomized_zone then
|
||||
if not stateful.objectives_completed.randomized_zone then
|
||||
stateful.objectives_completed.randomized_zone = true
|
||||
stateful.objectives_time_spent.randomized_zone = tick
|
||||
play_achievement_unlocked()
|
||||
Alert.alert_all_players(10, 'Objective: **breach zone** has been complete!')
|
||||
Server.to_discord_embed('Objective: **breach zone** has been complete!')
|
||||
@ -886,6 +1026,8 @@ local function update_raw()
|
||||
if wave_number >= stateful.objectives.randomized_wave then
|
||||
if not stateful.objectives_completed.randomized_wave then
|
||||
stateful.objectives_completed.randomized_wave = true
|
||||
stateful.objectives_time_spent.randomized_wave = tick
|
||||
|
||||
play_achievement_unlocked()
|
||||
Alert.alert_all_players(10, 'Objective: **survive until wave** has been complete!')
|
||||
Server.to_discord_embed('Objective: **survive until wave** has been complete!')
|
||||
@ -911,6 +1053,7 @@ local function update_raw()
|
||||
if items_done == 3 then
|
||||
if not stateful.objectives_completed.supplies then
|
||||
stateful.objectives_completed.supplies = true
|
||||
stateful.objectives_time_spent.supplies = tick
|
||||
Alert.alert_all_players(10, 'Objective: **produce 3 items multiple times** has been complete!')
|
||||
Server.to_discord_embed('Objective: **produce 3 items multiple times** has been complete!')
|
||||
play_achievement_unlocked()
|
||||
@ -937,6 +1080,7 @@ local function update_raw()
|
||||
stateful.objectives.single_item.count = 0
|
||||
if not stateful.objectives_completed.single_item then
|
||||
stateful.objectives_completed.single_item = true
|
||||
stateful.objectives_time_spent.single_item = tick
|
||||
play_achievement_unlocked()
|
||||
Alert.alert_all_players(10, 'Objective: **produce an item multiple times** has been completed!')
|
||||
Server.to_discord_embed('Objective: **produce an item multiple times** has been completed!')
|
||||
@ -1042,6 +1186,7 @@ local function update_raw()
|
||||
local completed, _, _ = callback()
|
||||
if completed and completed == true and not stateful.objectives_completed[objective_name] then
|
||||
stateful.objectives_completed[objective_name] = true
|
||||
stateful.objectives_time_spent[objective_name] = tick
|
||||
Alert.alert_all_players(10, 'Objective: **' .. objective_name .. '** has been completed!')
|
||||
Server.to_discord_embed('Objective: **' .. objective_name .. '** has been completed!')
|
||||
play_achievement_unlocked()
|
||||
@ -1189,6 +1334,71 @@ Gui.on_click(
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
close_buffs_window_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Buff Close Button')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
local player = event.player
|
||||
local center = player.gui.center
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local frame_buff = center[buffs_window_name]
|
||||
if frame_buff and frame_buff.valid then
|
||||
Gui.remove_data_recursively(frame_buff)
|
||||
frame_buff.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_custom_close(
|
||||
buffs_window_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Buff Custom Close')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
local player = event.player
|
||||
local center = player.gui.center
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local frame_buff = center[buffs_window_name]
|
||||
if frame_buff and frame_buff.valid then
|
||||
Gui.remove_data_recursively(frame_buff)
|
||||
frame_buff.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
on_click_buff_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Buff Open Button')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
local player = event.player
|
||||
local center = player.gui.center
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local frame_buff = center[buffs_window_name]
|
||||
if frame_buff and frame_buff.valid then
|
||||
Gui.remove_data_recursively(frame_buff)
|
||||
frame_buff.destroy()
|
||||
else
|
||||
buff_window(player)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.on_nth_tick(30, update_data)
|
||||
Event.on_nth_tick(30, update_raw)
|
||||
|
@ -2,6 +2,7 @@ local Public = require 'maps.mountain_fortress_v3.stateful.table'
|
||||
local Event = require 'utils.event'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Beam = require 'modules.render_beam'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
|
||||
Public.stateful_gui = require 'maps.mountain_fortress_v3.stateful.gui'
|
||||
Public.stateful_terrain = require 'maps.mountain_fortress_v3.stateful.terrain'
|
||||
@ -82,6 +83,123 @@ Event.on_nth_tick(
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_crafted_item,
|
||||
function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local item = event.item_stack
|
||||
if not item or not item.valid_for_read then
|
||||
return
|
||||
end
|
||||
|
||||
local objectives = Public.get_stateful('objectives')
|
||||
|
||||
local handcrafted_items_any = objectives.handcrafted_items_any
|
||||
if handcrafted_items_any then
|
||||
handcrafted_items_any.actual = handcrafted_items_any.actual + item.count
|
||||
end
|
||||
|
||||
local handcrafted_items = objectives.handcrafted_items
|
||||
if handcrafted_items then
|
||||
if item.name ~= handcrafted_items.name then
|
||||
return
|
||||
end
|
||||
|
||||
handcrafted_items.actual = handcrafted_items.actual + item.count
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_entity_died,
|
||||
function(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not Public.valid_enemy_forces[entity.force.name] then
|
||||
return
|
||||
end
|
||||
|
||||
local objectives = Public.get_stateful('objectives')
|
||||
|
||||
local damage_type = event.damage_type
|
||||
if not damage_type then
|
||||
return
|
||||
end
|
||||
local killed_enemies = objectives.killed_enemies_type
|
||||
if not killed_enemies then
|
||||
return
|
||||
end
|
||||
|
||||
if killed_enemies.damage_type ~= damage_type.name then
|
||||
return
|
||||
end
|
||||
|
||||
if entity.type == 'unit' then
|
||||
killed_enemies.actual = killed_enemies.actual + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_rocket_launched,
|
||||
function(event)
|
||||
local rocket_inventory = event.rocket.get_inventory(defines.inventory.rocket)
|
||||
local slot = rocket_inventory[1]
|
||||
if slot and slot.valid and slot.valid_for_read then
|
||||
local objectives = Public.get_stateful('objectives')
|
||||
|
||||
local launch_item = objectives.launch_item
|
||||
if launch_item then
|
||||
if slot.name ~= launch_item.name then
|
||||
return
|
||||
end
|
||||
|
||||
launch_item.actual = launch_item.actual + slot.count
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
RPG.events.on_spell_cast_success,
|
||||
function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local spell_name = event.spell_name
|
||||
local amount = event.amount
|
||||
|
||||
if not player.character or not player.character.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local objectives = Public.get_stateful('objectives')
|
||||
|
||||
local cast_spell_any = objectives.cast_spell_any
|
||||
if cast_spell_any then
|
||||
cast_spell_any.actual = cast_spell_any.actual + amount
|
||||
end
|
||||
|
||||
local cast_spell = objectives.cast_spell
|
||||
if cast_spell then
|
||||
if spell_name ~= cast_spell.name then
|
||||
return
|
||||
end
|
||||
|
||||
cast_spell.actual = cast_spell.actual + amount
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.on_nth_tick(
|
||||
14400,
|
||||
function()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,9 @@ Public.events = {
|
||||
on_market_item_purchased = Event.generate_event_name('on_market_item_purchased')
|
||||
}
|
||||
|
||||
local scenario_name = 'Mtn Fortress'
|
||||
Public.scenario_name = scenario_name
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
@ -134,6 +137,7 @@ function Public.reset_main_table()
|
||||
this.locomotive_health = 10000
|
||||
this.locomotive_max_health = 10000
|
||||
this.extra_wagons = 0
|
||||
this.all_the_fish = false
|
||||
this.gap_between_zones = {
|
||||
set = false,
|
||||
gap = 900,
|
||||
@ -177,6 +181,10 @@ function Public.reset_main_table()
|
||||
this.robotics_deployed = false
|
||||
this.upgrades = {
|
||||
showed_text = false,
|
||||
burner_generator = {
|
||||
limit = 50,
|
||||
bought = 0
|
||||
},
|
||||
landmine = {
|
||||
limit = 25,
|
||||
bought = 0,
|
||||
@ -375,7 +383,7 @@ function Public.remove(key, sub_key)
|
||||
end
|
||||
|
||||
function Public.save_stateful_settings()
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
|
||||
if server_name_matches then
|
||||
Server.set_data(dataset, dataset_key, stateful_settings)
|
||||
@ -387,7 +395,7 @@ end
|
||||
local apply_settings_token =
|
||||
Task.register(
|
||||
function(data)
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
local settings = data and data.value or nil
|
||||
|
||||
if not settings then
|
||||
@ -412,7 +420,7 @@ Event.add(
|
||||
local start_data = Server.get_start_data()
|
||||
|
||||
if not start_data.initialized then
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
local server_name_matches = Server.check_server_name(scenario_name)
|
||||
|
||||
if server_name_matches then
|
||||
Server.try_get_data(dataset, dataset_key, apply_settings_token)
|
||||
|
@ -79,6 +79,13 @@ local function clear_main_frame(player)
|
||||
end
|
||||
end
|
||||
|
||||
local function clear_top_frame(player)
|
||||
local top = player.gui.top
|
||||
if top[top_button_name] and top[top_button_name].valid then
|
||||
top[top_button_name].destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.difficulty_gui()
|
||||
if not this.show_gui then
|
||||
return
|
||||
@ -459,5 +466,7 @@ Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_left_game, on_player_left_game)
|
||||
|
||||
Public.top_button_name = top_button_name
|
||||
Public.clear_main_frame = clear_main_frame
|
||||
Public.clear_top_frame = clear_top_frame
|
||||
|
||||
return Public
|
||||
|
@ -739,6 +739,114 @@ function Public.aoe_punch(cause, entity, damage, final_damage_amount)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_tidal_wave(cause, ent_position, shape, length, max_spread)
|
||||
local rpg_extra = Public.get('rpg_extra')
|
||||
|
||||
if not cause or not cause.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local wave = {
|
||||
cause = cause,
|
||||
start_position = cause.position,
|
||||
direction = {ent_position.x - cause.position.x, ent_position.y - cause.position.y},
|
||||
length = length or 24,
|
||||
base_spread = 0.5,
|
||||
max_spread = max_spread or 5,
|
||||
shape = shape or false,
|
||||
tick = 0
|
||||
}
|
||||
local vector_length = math.sqrt(wave.direction[1] ^ 2 + wave.direction[2] ^ 2)
|
||||
wave.direction = {wave.direction[1] / vector_length, wave.direction[2] / vector_length}
|
||||
|
||||
rpg_extra.tidal_waves = rpg_extra.tidal_waves or {}
|
||||
rpg_extra.tidal_waves[#rpg_extra.tidal_waves + 1] = wave
|
||||
end
|
||||
|
||||
--Melee damage modifier
|
||||
function Public.update_tidal_wave()
|
||||
local rpg_extra = Public.get('rpg_extra')
|
||||
|
||||
if not rpg_extra.tidal_waves or not next(rpg_extra.tidal_waves) then
|
||||
return
|
||||
end
|
||||
|
||||
for id, wave in pairs(rpg_extra.tidal_waves) do
|
||||
if not wave then
|
||||
break
|
||||
end
|
||||
|
||||
local cone = wave.shape and wave.shape == 'cone' or false
|
||||
|
||||
local wave_player = wave.cause
|
||||
if not wave_player or not wave_player.valid then
|
||||
rpg_extra.tidal_waves[id] = nil
|
||||
return
|
||||
end
|
||||
|
||||
if wave.tick < wave.length then
|
||||
local surface = wave.cause.surface
|
||||
local cause_position = wave.start_position
|
||||
local i = wave.tick + 1
|
||||
|
||||
local current_spread = wave.base_spread + (wave.max_spread - wave.base_spread) * (i / wave.length)
|
||||
|
||||
if not cone then
|
||||
for j = -wave.max_spread, wave.max_spread do
|
||||
local offset_x = cause_position.x + wave.direction[1] * i + j * wave.direction[2]
|
||||
local offset_y = cause_position.y + wave.direction[2] * i - j * wave.direction[1]
|
||||
local position = {offset_x, offset_y}
|
||||
|
||||
local next_offset_x = cause_position.x + wave.direction[1] * (i + 1) + j * wave.direction[2]
|
||||
local next_offset_y = cause_position.y + wave.direction[2] * (i + 1) - j * wave.direction[1]
|
||||
local next_position = {next_offset_x, next_offset_y}
|
||||
|
||||
surface.create_entity({name = 'water-splash', position = position})
|
||||
-- surface.create_trivial_smoke({name = 'poison-capsule-smoke', position = position})
|
||||
local sound = 'utility/build_small'
|
||||
wave_player.play_sound {path = sound, volume_modifier = 1}
|
||||
|
||||
for _, entity in pairs(surface.find_entities({{position[1] - 1, position[2] - 1}, {position[1] + 1, position[2] + 1}})) do
|
||||
if entity.valid and entity.name ~= 'character' and entity.destructible and entity.type == 'unit' and entity.force.index ~= 3 then
|
||||
local new_pos = surface.find_non_colliding_position('character', next_position, 3, 0.5)
|
||||
if new_pos then
|
||||
entity.teleport(new_pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for j = -current_spread, current_spread, wave.base_spread do
|
||||
local offset_x = cause_position.x + wave.direction[1] * i + j * wave.direction[2]
|
||||
local offset_y = cause_position.y + wave.direction[2] * i - j * wave.direction[1]
|
||||
local position = {offset_x, offset_y}
|
||||
|
||||
local next_offset_x = cause_position.x + wave.direction[1] * (i + 1) + j * wave.direction[2]
|
||||
local next_offset_y = cause_position.y + wave.direction[2] * (i + 1) - j * wave.direction[1]
|
||||
local next_position = {next_offset_x, next_offset_y}
|
||||
-- surface.create_trivial_smoke({name = 'poison-capsule-smoke', position = position})
|
||||
surface.create_entity({name = 'water-splash', position = position})
|
||||
local sound = 'utility/build_small'
|
||||
wave_player.play_sound {path = sound, volume_modifier = 1}
|
||||
|
||||
for _, entity in pairs(surface.find_entities({{position[1] - 1, position[2] - 1}, {position[1] + 1, position[2] + 1}})) do
|
||||
if entity.valid and entity.name ~= 'character' and entity.destructible and entity.type == 'unit' and entity.force.index ~= 3 then
|
||||
local new_pos = surface.find_non_colliding_position('character', next_position, 3, 0.5)
|
||||
if new_pos then
|
||||
entity.teleport(new_pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wave.tick = wave.tick + 1
|
||||
else
|
||||
rpg_extra.tidal_waves[id] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.level_limit_exceeded(player, value)
|
||||
local rpg_extra = Public.get('rpg_extra')
|
||||
local rpg_t = Public.get_value_from_player(player.index)
|
||||
@ -1219,6 +1327,7 @@ function Public.rpg_reset_player(player, one_time_reset)
|
||||
dropdown_select_index_3 = 1,
|
||||
dropdown_select_name_3 = Public.all_spells[1].name[1],
|
||||
allocate_index = 1,
|
||||
amount = 0,
|
||||
explosive_bullets = false,
|
||||
enable_entity_spawn = false,
|
||||
health_bar = rpg_t.health_bar,
|
||||
@ -1268,6 +1377,7 @@ function Public.rpg_reset_player(player, one_time_reset)
|
||||
dropdown_select_index_3 = 1,
|
||||
dropdown_select_name_3 = Public.all_spells[1].name[1],
|
||||
allocate_index = 1,
|
||||
amount = 0,
|
||||
explosive_bullets = false,
|
||||
enable_entity_spawn = false,
|
||||
points_left = 0,
|
||||
|
@ -49,11 +49,10 @@ function Public.draw_gui_char_button(player)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
b.style.minimal_width = 50
|
||||
b.style.padding = 0
|
||||
b.style.margin = 0
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
if player.gui.top[draw_main_frame_name] then
|
||||
@ -218,7 +217,7 @@ local function draw_main_frame(player, location)
|
||||
main_frame.location = location
|
||||
else
|
||||
if ComfyGui.get_mod_gui_top_frame() then
|
||||
main_frame.location = {x = 1, y = 55}
|
||||
main_frame.location = {x = 0, y = 67}
|
||||
else
|
||||
main_frame.location = {x = 1, y = 45}
|
||||
end
|
||||
@ -543,6 +542,7 @@ Gui.on_click(
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
|
@ -6,10 +6,12 @@ local AntiGrief = require 'utils.antigrief'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local Explosives = require 'modules.explosives'
|
||||
|
||||
local StatData = require 'utils.datastore.statistics'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Math2D = require 'math2d'
|
||||
|
||||
StatData.add_normalize('spells', 'Spells casted')
|
||||
|
||||
--RPG Settings
|
||||
local enemy_types = Public.enemy_types
|
||||
local die_cause = Public.die_cause
|
||||
@ -1009,11 +1011,21 @@ local function on_player_used_capsule(event)
|
||||
cast_spell = Public.cast_spell
|
||||
}
|
||||
|
||||
rpg_t.amount = 0
|
||||
|
||||
local cast_spell = spell.callback(data, funcs)
|
||||
if not cast_spell then
|
||||
return
|
||||
end
|
||||
|
||||
if rpg_t.amount == 0 then
|
||||
rpg_t.amount = 1
|
||||
end
|
||||
|
||||
Event.raise(Public.events.on_spell_cast_success, {player_index = player.index, spell_name = spell.entityName, amount = rpg_t.amount})
|
||||
|
||||
StatData.get_data(player):increase('spells')
|
||||
|
||||
if spell.enforce_cooldown then
|
||||
Public.register_cooldown_for_player(player, spell)
|
||||
end
|
||||
@ -1078,6 +1090,7 @@ Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
|
||||
Event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
|
||||
Event.add(defines.events.on_player_removed, on_player_removed)
|
||||
Event.on_nth_tick(10, tick)
|
||||
Event.on_nth_tick(2, Public.update_tidal_wave)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_gui_closed,
|
||||
|
@ -1,6 +1,5 @@
|
||||
local Public = require 'modules.rpg.table'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Task = require 'utils.task_token'
|
||||
local Ai = require 'modules.ai'
|
||||
local Modifiers = require 'utils.player_modifiers'
|
||||
|
||||
@ -14,9 +13,10 @@ local states = {
|
||||
}
|
||||
|
||||
local restore_movement_speed_token
|
||||
local repeat_sound_token
|
||||
|
||||
local repair_buildings =
|
||||
Token.register(
|
||||
Task.register(
|
||||
function(data)
|
||||
local entity = data.entity
|
||||
if entity and entity.valid then
|
||||
@ -34,6 +34,52 @@ local repair_buildings =
|
||||
end
|
||||
)
|
||||
|
||||
repeat_sound_token =
|
||||
Task.register(
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local sound = event.sound or 'utility/armor_insert'
|
||||
|
||||
local spell_active = Public.get_value_from_player(player_index, 'has_custom_spell_active')
|
||||
|
||||
if spell_active then
|
||||
player.play_sound {path = sound, volume_modifier = 1}
|
||||
if player.character ~= nil then
|
||||
player.character.surface.create_entity({name = 'water-splash', position = player.position})
|
||||
end
|
||||
Task.set_timeout_in_ticks(30, repeat_sound_token, event)
|
||||
else
|
||||
player.play_sound {path = sound, volume_modifier = 1}
|
||||
return
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local x_marks_the_spot_token =
|
||||
Task.register(
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
local old_surface_index = event.old_surface_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
local old_position = event.old_position
|
||||
if not old_position then
|
||||
return
|
||||
end
|
||||
|
||||
player.teleport(old_position, old_surface_index)
|
||||
Public.set_active_spell_disabled(player_index)
|
||||
Task.set_timeout_in_ticks(5, repeat_sound_token, {player_index = player.index, sound = 'utility/new_objective'})
|
||||
end
|
||||
)
|
||||
|
||||
local function get_area(pos, dist)
|
||||
local area = {
|
||||
left_top = {
|
||||
@ -48,6 +94,33 @@ local function get_area(pos, dist)
|
||||
return area
|
||||
end
|
||||
|
||||
local levels = {
|
||||
[150] = {length = 26, max_spread = 6},
|
||||
[200] = {length = 27, max_spread = 6},
|
||||
[250] = {length = 28, max_spread = 7},
|
||||
[300] = {length = 29, max_spread = 7},
|
||||
[350] = {length = 30, max_spread = 8},
|
||||
[400] = {length = 31, max_spread = 8}
|
||||
}
|
||||
|
||||
local function get_level_data(player_level)
|
||||
local closest_level = nil
|
||||
|
||||
for level, _ in pairs(levels) do
|
||||
if player_level >= level then
|
||||
closest_level = level
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if closest_level then
|
||||
return levels[closest_level]
|
||||
else
|
||||
return {length = 26, max_spread = 6}
|
||||
end
|
||||
end
|
||||
|
||||
local function area_of_effect(player, position, state, radius, callback, find_entities)
|
||||
if not radius then
|
||||
return
|
||||
@ -87,7 +160,7 @@ local function area_of_effect(player, position, state, radius, callback, find_en
|
||||
end
|
||||
|
||||
restore_movement_speed_token =
|
||||
Token.register(
|
||||
Task.register(
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
local rpg_t = event.rpg_t
|
||||
@ -152,6 +225,7 @@ local function create_projectiles(data)
|
||||
}
|
||||
do_projectile(surface, projectile_types[self.entityName].name, position, force, target_pos, range)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
rpg_t.amount = rpg_t.amount + 1
|
||||
if self.damage then
|
||||
for _, e in pairs(surface.find_entities_filtered({area = damage_area})) do
|
||||
damage_entity(e)
|
||||
@ -222,6 +296,7 @@ local function create_entity(data)
|
||||
has_cast = true
|
||||
e.direction = player.character.direction
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
rpg_t.amount = rpg_t.amount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -259,6 +334,7 @@ local function insert_onto(data)
|
||||
|
||||
player.insert({name = self.entityName, count = self.amount})
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
rpg_t.amount = rpg_t.amount + 1
|
||||
end
|
||||
else
|
||||
player.insert({name = self.entityName, count = self.amount})
|
||||
@ -1064,6 +1140,82 @@ spells[#spells + 1] = {
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
spells[#spells + 1] = {
|
||||
name = {'spells.mark_spot'},
|
||||
entityName = 'mark-spot',
|
||||
target = true,
|
||||
force = 'player',
|
||||
level = 60,
|
||||
type = 'special',
|
||||
mana_cost = 340,
|
||||
cooldown = 2000,
|
||||
enforce_cooldown = true,
|
||||
check_if_active = true,
|
||||
enabled = true,
|
||||
log_spell = true,
|
||||
sprite = 'virtual-signal/signal-X',
|
||||
special_sprite = 'virtual-signal=signal-X',
|
||||
tooltip = 'Warps you back to the locomotive and after a couple of seconds you return to your previous location.',
|
||||
callback = function(data)
|
||||
local player = data.player
|
||||
local surface = data.surface
|
||||
local old_position = player.position
|
||||
local rpg_t = data.rpg_t
|
||||
rpg_t.has_custom_spell_active = true
|
||||
|
||||
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
else
|
||||
pos = game.forces.player.get_spawn_position(surface)
|
||||
player.teleport(pos, surface)
|
||||
end
|
||||
|
||||
Task.set_timeout_in_ticks(5, repeat_sound_token, {player_index = player.index})
|
||||
Task.set_timeout_in_ticks(300, x_marks_the_spot_token, {player_index = player.index, old_position = old_position, old_surface_index = surface.index})
|
||||
Public.remove_mana(player, 340)
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
spells[#spells + 1] = {
|
||||
name = {'spells.tidal_wave'},
|
||||
entityName = 'tidal-wave',
|
||||
target = true,
|
||||
force = 'player',
|
||||
level = 100,
|
||||
type = 'special',
|
||||
mana_cost = 340,
|
||||
cooldown = 1000,
|
||||
enforce_cooldown = true,
|
||||
check_if_active = false,
|
||||
enabled = true,
|
||||
log_spell = false,
|
||||
sprite = 'virtual-signal/signal-T',
|
||||
special_sprite = 'virtual-signal=signal-T',
|
||||
tooltip = 'Spawns a tidal wave that pushes the enemies back.',
|
||||
callback = function(data)
|
||||
local player = data.player
|
||||
local rpg_t = data.rpg_t
|
||||
local cursor_position = data.position
|
||||
|
||||
local shape = 'cone'
|
||||
|
||||
if random(1, 2) == 1 then
|
||||
shape = 'square'
|
||||
end
|
||||
|
||||
local level_data = get_level_data(rpg_t.level)
|
||||
|
||||
Public.add_tidal_wave(player, cursor_position, shape, level_data.length, level_data.max_spread)
|
||||
|
||||
Public.remove_mana(player, 340)
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
name = {'spells.charge'},
|
||||
entityName = 'haste',
|
||||
|
@ -34,6 +34,10 @@ Global.register(
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
Public.events = {
|
||||
on_spell_cast_success = Event.generate_event_name('on_spell_cast_success'),
|
||||
on_spell_cast_failure = Event.generate_event_name('on_spell_cast_failure')
|
||||
}
|
||||
|
||||
Public.points_per_level = 5
|
||||
|
||||
@ -195,6 +199,22 @@ function Public.set_value_to_player(key, value, setter)
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets set_active_spell_enabled as enabled.
|
||||
---@param player_index string
|
||||
function Public.set_active_spell_enabled(player_index)
|
||||
if (this.rpg_t[player_index]) then
|
||||
this.rpg_t[player_index].has_custom_spell_active = true
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets set_active_spell_disabled as nil.
|
||||
---@param player_index string
|
||||
function Public.set_active_spell_disabled(player_index)
|
||||
if this.rpg_t[player_index] then
|
||||
this.rpg_t[player_index].has_custom_spell_active = false
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets a new table to rpg_t table
|
||||
---@param key string
|
||||
---@param tbl table
|
||||
|
@ -1,11 +1,35 @@
|
||||
local Public = require 'modules.wave_defense.table'
|
||||
local Gui = require 'utils.gui'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
|
||||
local floor = math.floor
|
||||
|
||||
local function get_top_frame_custom(player, name)
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
return Gui.get_button_flow(player)[name]
|
||||
else
|
||||
return player.gui.top[name]
|
||||
end
|
||||
end
|
||||
|
||||
local function create_gui(player)
|
||||
local frame = player.gui.top.add({type = 'frame', name = 'wave_defense', style = 'finished_game_subheader_frame'})
|
||||
frame.style.maximal_height = 38
|
||||
local frame
|
||||
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
frame =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'frame',
|
||||
name = 'wave_defense',
|
||||
style = 'finished_game_subheader_frame'
|
||||
}
|
||||
)
|
||||
frame.style.maximal_height = 36
|
||||
else
|
||||
frame = player.gui.top.add({type = 'frame', name = 'wave_defense', style = 'finished_game_subheader_frame'})
|
||||
frame.style.maximal_height = 38
|
||||
end
|
||||
|
||||
local label = frame.add({type = 'label', caption = ' ', name = 'label'})
|
||||
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
|
||||
@ -19,7 +43,7 @@ local function create_gui(player)
|
||||
wave_number_label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
|
||||
|
||||
local progressbar = frame.add({type = 'progressbar', name = 'progressbar', value = 0})
|
||||
progressbar.style = 'achievement_progressbar'
|
||||
progressbar.style = 'achievement_progressbar' ---@class LuaGuiElementStyle
|
||||
progressbar.style.minimal_width = 96
|
||||
progressbar.style.maximal_width = 96
|
||||
progressbar.style.padding = -1
|
||||
@ -61,16 +85,16 @@ end
|
||||
function Public.update_gui(player)
|
||||
local final_battle = Public.get('final_battle')
|
||||
if final_battle then
|
||||
if player.gui.top.wave_defense and player.gui.top.wave_defense.valid then
|
||||
player.gui.top.wave_defense.destroy()
|
||||
if get_top_frame_custom(player, 'wave_defense') and get_top_frame_custom(player, 'wave_defense').valid then
|
||||
get_top_frame_custom(player, 'wave_defense').destroy()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not player.gui.top.wave_defense then
|
||||
if not get_top_frame_custom(player, 'wave_defense') then
|
||||
create_gui(player)
|
||||
end
|
||||
local gui = player.gui.top.wave_defense
|
||||
local gui = get_top_frame_custom(player, 'wave_defense')
|
||||
|
||||
local biter_health_boost = 1
|
||||
local biter_health_boosts = BiterHealthBooster.get('biter_health_boost')
|
||||
@ -93,6 +117,7 @@ function Public.update_gui(player)
|
||||
gui.wave_number.caption = wave_number
|
||||
if wave_number == 0 then
|
||||
gui.label.caption = {'wave_defense.gui_1'}
|
||||
gui.label.tooltip = 'Next pause will occur in: ' .. floor((Public.get('next_pause_interval') - game.tick) / 60 / 60) + 1 .. ' minute(s)'
|
||||
gui.wave_number.caption = floor((next_wave - game.tick) / 60) + 1 .. 's'
|
||||
end
|
||||
local interval = next_wave - last_wave
|
||||
@ -105,11 +130,13 @@ function Public.update_gui(player)
|
||||
gui.progressbar.value = value
|
||||
else
|
||||
gui.label.caption = {'wave_defense.gui_4'}
|
||||
gui.label.tooltip = 'Wave: ' .. wave_number
|
||||
local pause_for = floor((paused_waves_for - game.tick) / 60) + 1
|
||||
if pause_for < 0 then
|
||||
pause_for = 0
|
||||
end
|
||||
gui.wave_number.caption = pause_for .. 's'
|
||||
gui.wave_number.tooltip = 'Wave: ' .. wave_number
|
||||
|
||||
local interval = paused_waves_for - last_pause
|
||||
local value = 1 - (paused_waves_for - game.tick) / interval
|
||||
@ -124,6 +151,7 @@ function Public.update_gui(player)
|
||||
|
||||
gui.threat.caption = {'wave_defense.gui_3'}
|
||||
gui.threat.tooltip = {'wave_defense.tooltip_1', biter_health_boost * 100, max_active_biters}
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
gui.threat_value.caption = floor(threat)
|
||||
gui.threat_value.tooltip = {
|
||||
'wave_defense.tooltip_1',
|
||||
|
@ -259,6 +259,8 @@ Event.on_nth_tick(
|
||||
return
|
||||
end
|
||||
|
||||
Public.set('next_pause_interval', game.tick + 216000)
|
||||
|
||||
local pause_without_votes = Public.get('pause_without_votes')
|
||||
if pause_without_votes then
|
||||
Public.toggle_pause_wave_without_votes()
|
||||
|
@ -70,6 +70,7 @@ function Public.reset_wave_defense()
|
||||
this.paused = false
|
||||
this.pause_without_votes = true
|
||||
this.pause_wave_in_ticks = 18000 -- 5 minutes
|
||||
this.next_pause_interval = game.tick + 216000 -- 1 hour
|
||||
this.game_lost = false
|
||||
this.get_random_close_spawner_attempts = 5
|
||||
this.group_size = 2
|
||||
|
@ -10,6 +10,11 @@ local function on_console_command(event)
|
||||
|
||||
local commands = {
|
||||
['editor'] = true,
|
||||
['open'] = true,
|
||||
['cheat'] = true,
|
||||
['permissions'] = true,
|
||||
['banlist'] = true,
|
||||
['config'] = true,
|
||||
['command'] = true,
|
||||
['silent-command'] = true,
|
||||
['sc'] = true,
|
||||
|
@ -7,6 +7,7 @@ local Global = require 'utils.global'
|
||||
local BottomFrame = require 'utils.gui.bottom_frame'
|
||||
local Gui = require 'utils.gui'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local Discord = require 'utils.discord_handler'
|
||||
|
||||
local this = {
|
||||
players = {},
|
||||
@ -163,6 +164,62 @@ commands.add_command(
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'repair',
|
||||
'Revives all ghost entities.',
|
||||
function(cmd)
|
||||
local player = game.player
|
||||
local param = tonumber(cmd.parameter)
|
||||
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local p = player.print
|
||||
if not player.admin then
|
||||
p("[ERROR] You're not admin!", Color.fail)
|
||||
return
|
||||
end
|
||||
|
||||
if param == nil then
|
||||
player.print('[ERROR] Must specify radius!', Color.fail)
|
||||
return
|
||||
end
|
||||
if param > 50 then
|
||||
player.print('[ERROR] Value is too big.', Color.fail)
|
||||
return
|
||||
end
|
||||
|
||||
if not this.revive_warning then
|
||||
this.revive_warning = true
|
||||
player.print('[WARNING] This command will revive all the ghost entities in the given radius, run this command again if you really want to do this!', Color.yellow)
|
||||
return
|
||||
end
|
||||
|
||||
local radius = {{x = (player.position.x + -param), y = (player.position.y + -param)}, {x = (player.position.x + param), y = (player.position.y + param)}}
|
||||
|
||||
local c = 0
|
||||
for _, v in pairs(player.surface.find_entities_filtered {type = 'entity-ghost', area = radius}) do
|
||||
if v and v.valid then
|
||||
c = c + 1
|
||||
v.silent_revive()
|
||||
end
|
||||
end
|
||||
|
||||
if c == 0 then
|
||||
player.print('No entities to repair were found!', Color.warning)
|
||||
this.revive_warning = nil
|
||||
return
|
||||
end
|
||||
|
||||
Discord.send_notification_raw(nil, player.name .. ' repaired ' .. c .. ' entities!')
|
||||
|
||||
player.play_sound {path = 'utility/new_objective', volume_modifier = 1}
|
||||
player.print('Repaired ' .. c .. ' entities!', Color.success)
|
||||
this.revive_warning = nil
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'dump_layout',
|
||||
'Dump the current map-layout.',
|
||||
|
12
utils/datastore/init.lua
Normal file
12
utils/datastore/init.lua
Normal file
@ -0,0 +1,12 @@
|
||||
require 'utils.datastore.server_ups_data'
|
||||
require 'utils.datastore.current_time_data'
|
||||
require 'utils.datastore.color_data'
|
||||
require 'utils.datastore.session_data'
|
||||
require 'utils.datastore.statistics'
|
||||
require 'utils.datastore.jail_data'
|
||||
require 'utils.datastore.quickbar_data'
|
||||
require 'utils.datastore.warning_on_join_data'
|
||||
require 'utils.datastore.message_on_join_data'
|
||||
require 'utils.datastore.player_tag_data'
|
||||
require 'utils.datastore.supporters'
|
||||
require 'utils.datastore.banhandler'
|
@ -9,6 +9,9 @@ local Event = require 'utils.event'
|
||||
local Utils = require 'utils.core'
|
||||
local table = require 'utils.table'
|
||||
local Gui = require 'utils.gui'
|
||||
local StatData = require 'utils.datastore.statistics'
|
||||
|
||||
StatData.add_normalize('jailed', 'Jailed')
|
||||
|
||||
local module_name = '[Jail handler] '
|
||||
|
||||
@ -72,7 +75,12 @@ Global.register(
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
local Public = {
|
||||
events = {
|
||||
on_player_jailed = Event.generate_event_name('on_player_jailed'),
|
||||
on_player_unjailed = Event.generate_event_name('on_player_unjailed')
|
||||
}
|
||||
}
|
||||
|
||||
local function validate_entity(entity)
|
||||
if not (entity and entity.valid) then
|
||||
@ -641,6 +649,10 @@ local function jail(player, offender, msg, raised, mute)
|
||||
set_data(jailed_data_set, offender, {jailed = true, actor = player, reason = msg, date = date})
|
||||
end
|
||||
|
||||
Event.raise(Public.events.on_player_jailed, {player_index = offender.index})
|
||||
|
||||
StatData.get_data(player):increase('jailed')
|
||||
|
||||
Utils.print_to(nil, message)
|
||||
local data = Server.build_embed_data()
|
||||
data.username = offender
|
||||
@ -703,6 +715,10 @@ local function jail_temporary(player, offender, msg, mute)
|
||||
votejail[offender.name].jailed = true
|
||||
end
|
||||
|
||||
Event.raise(Public.events.on_player_jailed, {player_index = offender.index})
|
||||
|
||||
StatData.get_data(player):increase('jailed')
|
||||
|
||||
offender.clear_console()
|
||||
|
||||
draw_notice_frame(offender)
|
||||
@ -728,6 +744,8 @@ local function free(player, offender)
|
||||
|
||||
set_data(jailed_data_set, offender, nil)
|
||||
|
||||
Event.raise(Public.events.on_player_unjailed, {player_index = offender.index})
|
||||
|
||||
Utils.print_to(nil, message)
|
||||
local data = Server.build_embed_data()
|
||||
data.username = offender
|
||||
|
@ -18,6 +18,14 @@ local this = {
|
||||
logistics = {}
|
||||
}
|
||||
|
||||
local ignored_items = {
|
||||
['blueprint'] = true,
|
||||
['blueprint-book'] = true,
|
||||
['deconstruction-planner'] = true,
|
||||
['spidertron-remote'] = true,
|
||||
['upgrade-planner'] = true
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(t)
|
||||
@ -123,7 +131,7 @@ function Public.save_quickbar(player)
|
||||
|
||||
for i = 1, 100 do
|
||||
local slot = player.get_quick_bar_slot(i)
|
||||
if slot ~= nil then
|
||||
if slot ~= nil and not ignored_items[slot.name] then
|
||||
slots[i] = slot.name
|
||||
end
|
||||
end
|
||||
|
@ -10,15 +10,15 @@ local Event = require 'utils.event'
|
||||
local table = require 'utils.table'
|
||||
|
||||
local set_timeout_in_ticks = Task.set_timeout_in_ticks
|
||||
|
||||
local session_data_set = 'sessions'
|
||||
local session = {}
|
||||
local online_track = {}
|
||||
local trusted = {}
|
||||
local settings = {
|
||||
-- local trusted_value = 2592000 -- 12h
|
||||
trusted_value = 5184000, -- 24h
|
||||
required_only_time_to_save_time = 36000, -- nearest prime to 10 minutes in ticks
|
||||
nth_tick = 18000 -- nearest prime to 5 minutes in ticks
|
||||
trusted_value = 24 * 60 * 3600, -- 24h
|
||||
required_only_time_to_save_time = 10 * 3600,
|
||||
nth_tick = 5 * 3600
|
||||
}
|
||||
local set_data = Server.set_data
|
||||
local try_get_data = Server.try_get_data
|
||||
|
515
utils/datastore/statistics.lua
Normal file
515
utils/datastore/statistics.lua
Normal file
@ -0,0 +1,515 @@
|
||||
-- created by Gerkiz for ComfyFactorio
|
||||
local Global = require 'utils.global'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Server = require 'utils.server'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local set_timeout_in_ticks = Task.set_timeout_in_ticks
|
||||
local statistics_dataset = 'statistics'
|
||||
|
||||
local set_data = Server.set_data
|
||||
local try_get_data = Server.try_get_data
|
||||
local e = defines.events
|
||||
local floor = math.floor
|
||||
|
||||
local events = {
|
||||
map_tags_made = e.on_chart_tag_added,
|
||||
chat_messages = e.on_console_chat,
|
||||
commands_used = e.on_console_command,
|
||||
machines_built = e.on_built_entity,
|
||||
items_picked_up = e.on_picked_up_item,
|
||||
tiles_built = e.on_player_built_tile,
|
||||
join_count = e.on_player_joined_game,
|
||||
deaths = e.on_player_died,
|
||||
entities_repaired = e.on_player_repaired_entity,
|
||||
items_crafted = e.on_player_crafted_item,
|
||||
capsules_used = e.on_player_used_capsule,
|
||||
tiles_removed = e.on_player_mined_tile,
|
||||
deconstructer_planner_used = e.on_player_deconstructed_area
|
||||
}
|
||||
|
||||
local settings = {
|
||||
required_only_time_to_save_time = 10 * 3600,
|
||||
afk_time = 5 * 3600,
|
||||
nth_tick = 5 * 3600
|
||||
}
|
||||
|
||||
local Public = {
|
||||
events = {
|
||||
on_player_removed = Event.generate_event_name('on_player_removed')
|
||||
}
|
||||
}
|
||||
|
||||
local normalized_names = {
|
||||
['map_tags_made'] = {name = 'Map-tags created', tooltip = "Tags that you've created in minimap."},
|
||||
['chat_messages'] = {name = 'Messages', tooltip = 'Messages sent in chat.'},
|
||||
['commands_used'] = {name = 'Commands', tooltip = 'Commands used in console.'},
|
||||
['machines_built'] = {name = 'Entities built', tooltip = 'Entities built by the player.'},
|
||||
['items_picked_up'] = {name = 'Items picked-up', tooltip = 'Items picked-up by the player.'},
|
||||
['tiles_built'] = {name = 'Tiles placed', tooltip = 'Tiles placed by the player.'},
|
||||
['join_count'] = {name = 'Join count', tooltip = 'How many times the player has joined the game.'},
|
||||
['deaths'] = {name = 'Deaths', tooltip = 'How many times the player has died.'},
|
||||
['entities_repaired'] = {name = 'Entities repaired', tooltip = 'How many entities the player has repaired.'},
|
||||
['items_crafted'] = {name = 'Items crafted', tooltip = 'How many items the player has crafted.'},
|
||||
['capsules_used'] = {name = 'Capsules used', tooltip = 'How many capsules the player has used.'},
|
||||
['tiles_removed'] = {name = 'Tiles removed', tooltip = 'How many tiles the player has removed.'},
|
||||
['deconstructer_planner_used'] = {name = 'Decon planner used', tooltip = 'How many times the player has used the deconstruction planner.'},
|
||||
['maps_played'] = {name = 'Maps played', tooltip = 'How many maps the player has played.'},
|
||||
['afk_time'] = {name = 'Total AFK', tooltip = 'How long the player has been AFK.'},
|
||||
['distance_moved'] = {name = 'Distance travelled', tooltip = 'How far the player has travelled.\nIncluding standing still in looped belts.'},
|
||||
['damage_dealt'] = {name = 'Damage dealt', tooltip = 'How much damage the player has dealt.'},
|
||||
['enemies_killed'] = {name = 'Enemies killed', tooltip = 'How many enemies the player has killed.'},
|
||||
['friendly_killed'] = {name = 'Friendlies killed', tooltip = 'How many friendlies the player has killed.\n This includes entities such as buildings etc.'},
|
||||
['rockets_launched'] = {name = 'Rockets launched', tooltip = 'How many rockets the player has launched.'},
|
||||
['research_complete'] = {name = 'Research completed', tooltip = 'How many researches the player has completed.'},
|
||||
['force_mined_machines'] = {name = 'Mined friendly entities', tooltip = 'How many friendly entities the player has mined.'},
|
||||
['trees'] = {name = 'Trees chopped', tooltip = 'How many trees the player has chopped.'},
|
||||
['rocks'] = {name = 'Rocks mined', tooltip = 'How many rocks the player has mined.'},
|
||||
['resources'] = {name = 'Ores mined', tooltip = 'How many ores the player has mined.'},
|
||||
['kicked'] = {name = 'Kicked', tooltip = 'How many times the player has been kicked.'}
|
||||
}
|
||||
local statistics = {}
|
||||
|
||||
-- Register the statistics table in the global table
|
||||
Global.register(
|
||||
{
|
||||
statistics = statistics
|
||||
},
|
||||
function(tbl)
|
||||
statistics = tbl.statistics
|
||||
|
||||
for _, stat in pairs(statistics) do
|
||||
setmetatable(stat, Public.metatable)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Metatable for the statistics table
|
||||
Public.metatable = {__index = Public}
|
||||
|
||||
-- Add a normalization entry to the normalized_names table
|
||||
function Public.add_normalize(name, normalize)
|
||||
if _LIFECYCLE == _STAGE.runtime then
|
||||
error('cannot call during runtime', 2)
|
||||
end
|
||||
|
||||
local mt = setmetatable({name = normalize}, Public.metatable)
|
||||
|
||||
normalized_names[name] = mt
|
||||
|
||||
return mt
|
||||
end
|
||||
|
||||
-- Set the tooltip for a statistic
|
||||
function Public:set_tooltip(tooltip)
|
||||
if _LIFECYCLE == _STAGE.runtime then
|
||||
error('cannot call during runtime', 2)
|
||||
end
|
||||
|
||||
self.tooltip = tooltip
|
||||
end
|
||||
|
||||
--- Returns the player table or false
|
||||
---@param player LuaPlayer|number
|
||||
---@return any
|
||||
local function get_data(player)
|
||||
local player_index = player and type(player) == 'number' and player or player and player.valid and player.index or false
|
||||
if not player_index then
|
||||
log('Invalid player index at get_data')
|
||||
return false
|
||||
end
|
||||
|
||||
local data = statistics[player_index]
|
||||
|
||||
if not data then
|
||||
local p = game.get_player(player_index)
|
||||
local name = p and p.valid and p.name or nil
|
||||
local player_data = {
|
||||
name = name,
|
||||
tick = 0
|
||||
}
|
||||
|
||||
for event, _ in pairs(events) do
|
||||
player_data[event] = 0
|
||||
end
|
||||
|
||||
local mt = setmetatable(player_data, Public.metatable)
|
||||
|
||||
statistics[player_index] = mt
|
||||
end
|
||||
|
||||
return statistics[player_index]
|
||||
end
|
||||
|
||||
local try_download_data_token =
|
||||
Token.register(
|
||||
function(data)
|
||||
local player_name = data.key
|
||||
local player = game.get_player(player_name)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local stats = data.value
|
||||
if stats then
|
||||
local s = setmetatable(stats, Public.metatable)
|
||||
statistics[player.index] = s
|
||||
else
|
||||
get_data(player)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local try_upload_data_token =
|
||||
Token.register(
|
||||
function(data)
|
||||
local player_name = data.key
|
||||
if not player_name then
|
||||
return
|
||||
end
|
||||
local stats = data.value
|
||||
local player = game.get_player(player_name)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if stats then
|
||||
-- we don't want to clutter the database with players less than 10 minutes played.
|
||||
if player.online_time <= settings.required_only_time_to_save_time then
|
||||
return
|
||||
end
|
||||
|
||||
set_data(statistics_dataset, player_name, get_data(player))
|
||||
else
|
||||
local d = get_data(player)
|
||||
if player.online_time >= settings.required_only_time_to_save_time then
|
||||
set_data(statistics_dataset, player_name, d)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Increase a statistic by a delta value
|
||||
function Public:increase(name, delta)
|
||||
if not self[name] then
|
||||
self[name] = 0
|
||||
end
|
||||
|
||||
self[name] = self[name] + (delta or 1)
|
||||
|
||||
self.tick = self.tick + 1
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-- Save the player's statistics
|
||||
function Public:save()
|
||||
local player = game.get_player(self.name)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if player.online_time <= settings.required_only_time_to_save_time then
|
||||
return
|
||||
end
|
||||
|
||||
if self.tick < 10 then
|
||||
return
|
||||
end
|
||||
|
||||
set_data(statistics_dataset, player.name, self)
|
||||
return self
|
||||
end
|
||||
|
||||
-- Clear the player's statistics
|
||||
function Public:clear(force_clear)
|
||||
if force_clear then
|
||||
statistics[self.name] = nil
|
||||
else
|
||||
local player = game.get_player(self.name)
|
||||
if not player or not player.valid then
|
||||
statistics[self.name] = nil
|
||||
return
|
||||
end
|
||||
local connected = player.connected
|
||||
|
||||
if not connected then
|
||||
statistics[self.name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Try to get the player's data from the dataset
|
||||
function Public:try_get_data()
|
||||
try_get_data(statistics_dataset, self.name, try_download_data_token)
|
||||
return self
|
||||
end
|
||||
|
||||
-- Try to upload the player's data to the dataset
|
||||
function Public:try_upload_data()
|
||||
try_get_data(statistics_dataset, self.name, try_upload_data_token)
|
||||
return self
|
||||
end
|
||||
|
||||
local nth_tick_token =
|
||||
Token.register(
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
get_data(player):save()
|
||||
end
|
||||
)
|
||||
|
||||
--- Uploads each connected players play time to the dataset
|
||||
local function upload_data()
|
||||
local players = game.connected_players
|
||||
local count = 0
|
||||
for i = 1, #players do
|
||||
count = count + 10
|
||||
local player = players[i]
|
||||
set_timeout_in_ticks(count, nth_tick_token, {player_index = player.index})
|
||||
end
|
||||
end
|
||||
|
||||
--- Checks if a player exists within the table
|
||||
---@param player_index string
|
||||
---@return boolean
|
||||
function Public.exists(player_index)
|
||||
return statistics[player_index] ~= nil
|
||||
end
|
||||
|
||||
--- Returns the table of statistics
|
||||
---@param player LuaPlayer
|
||||
---@return table|boolean
|
||||
function Public.get_player(player)
|
||||
return statistics and player and player.valid and statistics[player.index] or false
|
||||
end
|
||||
|
||||
-- Event handlers
|
||||
|
||||
Event.add(
|
||||
e.on_player_joined_game,
|
||||
function(event)
|
||||
get_data(event.player_index):try_get_data()
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_player_left_game,
|
||||
function(event)
|
||||
get_data(event.player_index):try_upload_data()
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
Public.events.on_player_removed,
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
statistics[player_index] = nil
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_player_removed,
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
statistics[player_index] = nil
|
||||
end
|
||||
)
|
||||
|
||||
Event.on_nth_tick(settings.nth_tick, upload_data)
|
||||
|
||||
Server.on_data_set_changed(
|
||||
statistics_dataset,
|
||||
function(data)
|
||||
local player = game.get_player(data.key)
|
||||
if player and player.valid then
|
||||
local stats = data.value
|
||||
if stats then
|
||||
local s = setmetatable(stats, Public.metatable)
|
||||
statistics[data.key] = s
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function on_marked_for_deconstruction_on_player_mined_entity(event)
|
||||
if not event.player_index then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player.valid or not player.connected then
|
||||
return
|
||||
end
|
||||
local entity = event.entity
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local data = get_data(event.player_index)
|
||||
if entity.type == 'resource' then
|
||||
data:increase('resources')
|
||||
elseif entity.type == 'tree' then
|
||||
data:increase('trees')
|
||||
elseif entity.type == 'simple-entity' then
|
||||
data:increase('rocks')
|
||||
elseif entity.force == player.force then
|
||||
data:increase('force_mined_machines')
|
||||
end
|
||||
end
|
||||
|
||||
for stat_name, event_name in pairs(events) do
|
||||
Event.add(
|
||||
event_name,
|
||||
function(event)
|
||||
if not event.player_index then
|
||||
return
|
||||
end
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player.valid or not player.connected then
|
||||
return
|
||||
end
|
||||
local data = get_data(event.player_index)
|
||||
data:increase(stat_name)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
Event.add(
|
||||
e.on_research_finished,
|
||||
function(event)
|
||||
local research = event.research
|
||||
if event.by_script or not research or not research.valid then
|
||||
return
|
||||
end
|
||||
local force = research.force
|
||||
if not force or not force.valid then
|
||||
return
|
||||
end
|
||||
for _, player in pairs(force.connected_players) do
|
||||
local data = get_data(player)
|
||||
data:increase('research_complete')
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_rocket_launched,
|
||||
function(event)
|
||||
local silo = event.rocket_silo
|
||||
if not silo or not silo.valid then
|
||||
return
|
||||
end
|
||||
local force = silo.force
|
||||
if not force or not force.valid then
|
||||
return
|
||||
end
|
||||
for _, player in pairs(force.connected_players) do
|
||||
local data = get_data(player)
|
||||
data:increase('rockets_launched')
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_entity_died,
|
||||
function(event)
|
||||
local character = event.cause
|
||||
if not character or not character.valid or character.type ~= 'character' then
|
||||
return
|
||||
end
|
||||
local player = character.player
|
||||
if not player or not player.valid or not player.connected then
|
||||
return
|
||||
end
|
||||
local entity = event.entity
|
||||
if not entity.valid or entity.force.name == 'neutral' then
|
||||
return
|
||||
end
|
||||
local data = get_data(player)
|
||||
if entity.force == player.force then
|
||||
data:increase('friendly_killed')
|
||||
return
|
||||
end
|
||||
data:increase('enemies_killed')
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_entity_damaged,
|
||||
function(event)
|
||||
local character = event.cause
|
||||
if not character or not character.valid or character.type ~= 'character' then
|
||||
return
|
||||
end
|
||||
local player = character.player
|
||||
if not player.valid or not player.connected then
|
||||
return
|
||||
end
|
||||
local entity = event.entity
|
||||
if not entity.valid or entity.force == player.force or entity.force.name == 'neutral' then
|
||||
return
|
||||
end
|
||||
|
||||
local final_damage = event.final_damage_amount
|
||||
|
||||
local data = get_data(player)
|
||||
data:increase('damage_dealt', floor(final_damage))
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_player_changed_position,
|
||||
function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player.valid or not player.connected or player.afk_time > settings.required_only_time_to_save_time then
|
||||
return
|
||||
end
|
||||
local data = get_data(event.player_index)
|
||||
data:increase('distance_moved')
|
||||
end
|
||||
)
|
||||
|
||||
Event.on_nth_tick(
|
||||
3600,
|
||||
function()
|
||||
if game.tick == 0 then
|
||||
return
|
||||
end
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local data = get_data(player)
|
||||
if player.afk_time > settings.afk_time then
|
||||
data:increase('afk_time')
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_player_created,
|
||||
function(event)
|
||||
get_data(event.player_index):increase('maps_played')
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
e.on_player_kicked,
|
||||
function(event)
|
||||
get_data(event.player_index):increase('kicked')
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(e.on_marked_for_deconstruction, on_marked_for_deconstruction_on_player_mined_entity)
|
||||
Event.add(e.on_player_mined_entity, on_marked_for_deconstruction_on_player_mined_entity)
|
||||
|
||||
Public.upload_data = upload_data
|
||||
Public.get_data = get_data
|
||||
Public.normalized_names = normalized_names
|
||||
|
||||
return Public
|
@ -19,14 +19,17 @@ local name_lookup = {}
|
||||
|
||||
-- GUI names
|
||||
local checkbox_name = Gui.uid_name()
|
||||
local checkbox_all_name = Gui.uid_name()
|
||||
local filter_name = Gui.uid_name()
|
||||
local clear_filter_name = Gui.uid_name()
|
||||
|
||||
-- global tables
|
||||
local enabled = {}
|
||||
local enabled_for_all = false
|
||||
local last_events = {}
|
||||
global.debug_event_view = {
|
||||
enabled = enabled,
|
||||
enabled_for_all = enabled_for_all,
|
||||
last_events = last_events,
|
||||
filter = ''
|
||||
}
|
||||
@ -83,6 +86,25 @@ local function on_gui_checked_state_changed(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_checked_state_changed_all(event)
|
||||
local element = event.element
|
||||
local state = element.state and true or false
|
||||
element.state = state
|
||||
if state then
|
||||
for name, _ in pairs(events) do
|
||||
local id = events[name]
|
||||
enabled[id] = true
|
||||
end
|
||||
enabled_for_all = true
|
||||
else
|
||||
for name, _ in pairs(events) do
|
||||
local id = events[name]
|
||||
enabled[id] = false
|
||||
end
|
||||
enabled_for_all = false
|
||||
end
|
||||
end
|
||||
|
||||
-- GUI
|
||||
|
||||
-- Create a table with events sorted by their names
|
||||
@ -116,6 +138,12 @@ function Public.show(container)
|
||||
filter_flow.add({type = 'label', caption = 'filter'})
|
||||
local filter_textfield = filter_flow.add({type = 'textfield', name = filter_name, text = filter})
|
||||
local clear_button = filter_flow.add({type = 'button', name = clear_filter_name, caption = 'clear'})
|
||||
filter_flow.add({type = 'flow'}).add {
|
||||
name = checkbox_all_name,
|
||||
type = 'checkbox',
|
||||
state = enabled_for_all or false,
|
||||
caption = 'Toggle all events'
|
||||
}
|
||||
|
||||
local scroll_pane = main_frame_flow.add({type = 'scroll-pane'})
|
||||
local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true})
|
||||
@ -127,6 +155,7 @@ function Public.show(container)
|
||||
end
|
||||
|
||||
Gui.on_checked_state_changed(checkbox_name, on_gui_checked_state_changed)
|
||||
Gui.on_checked_state_changed(checkbox_all_name, on_gui_checked_state_changed_all)
|
||||
|
||||
Gui.on_text_changed(
|
||||
filter_name,
|
||||
|
@ -108,7 +108,7 @@ end
|
||||
|
||||
--- Send a message to the connected channel.
|
||||
--- Requires a title and a description
|
||||
---@param scenario_name string
|
||||
---@param scenario_name string|nil
|
||||
---@param message string
|
||||
function Public.send_notification_raw(scenario_name, message)
|
||||
if not scenario_name then
|
||||
|
@ -14,7 +14,8 @@ local this = {
|
||||
disable_crashsite = false,
|
||||
crashed_ship_items = {},
|
||||
crashed_debris_items = {},
|
||||
custom_surface_name = nil
|
||||
custom_surface_name = nil,
|
||||
clear_mod_gui_top = false
|
||||
}
|
||||
|
||||
Global.register(
|
||||
@ -102,6 +103,10 @@ local chart_starting_area = function()
|
||||
end
|
||||
|
||||
local on_player_joined_game = function(event)
|
||||
if not this.clear_mod_gui_top then
|
||||
return
|
||||
end
|
||||
|
||||
Task.set_timeout_in_ticks(5, clear_mod_gui_top_frame_token, event)
|
||||
end
|
||||
|
||||
|
@ -27,7 +27,7 @@ local remove_data_recursively
|
||||
local data = {}
|
||||
local element_map = {}
|
||||
local settings = {
|
||||
mod_gui_top_frame = false,
|
||||
mod_gui_top_frame = true,
|
||||
disabled_tabs = {},
|
||||
disable_clear_invalid_data = true
|
||||
}
|
||||
@ -66,17 +66,17 @@ local main_toggle_button_name = Public.uid_name()
|
||||
local main_button_name = Public.uid_name()
|
||||
local close_button_name = Public.uid_name()
|
||||
|
||||
Public.button_style = 'mod_gui_button'
|
||||
|
||||
if not Public.mod_gui_button_enabled then
|
||||
Public.button_style = nil
|
||||
end
|
||||
|
||||
Public.frame_style = 'non_draggable_frame'
|
||||
|
||||
Public.top_main_gui_button = main_button_name
|
||||
Public.main_frame_name = main_frame_name
|
||||
Public.main_toggle_button_name = main_toggle_button_name
|
||||
Public.frame_style = 'non_draggable_frame'
|
||||
Public.button_style = 'mod_gui_button'
|
||||
Public.top_flow_button_enabled_style = 'menu_button_continue'
|
||||
Public.top_flow_button_disabled_style = Public.button_style
|
||||
|
||||
--- Verifies if a frame is valid and destroys it.
|
||||
---@param align userdata
|
||||
@ -575,7 +575,7 @@ function Public.add_mod_button(player, frame)
|
||||
return Public.get_button_flow(player)[frame.name]
|
||||
end
|
||||
|
||||
Public.get_button_flow(player).add(frame)
|
||||
return Public.get_button_flow(player).add(frame)
|
||||
end
|
||||
|
||||
---@param state boolean
|
||||
@ -764,7 +764,13 @@ end
|
||||
|
||||
local function top_button(player)
|
||||
if settings.mod_gui_top_frame then
|
||||
Public.add_mod_button(player, {type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style})
|
||||
local button = Public.add_mod_button(player, {type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style})
|
||||
if button then
|
||||
button.style.minimal_height = 36
|
||||
button.style.maximal_height = 36
|
||||
button.style.minimal_width = 40
|
||||
button.style.padding = -2
|
||||
end
|
||||
else
|
||||
if player.gui.top[main_button_name] then
|
||||
return
|
||||
@ -782,19 +788,42 @@ local function top_toggle_button(player)
|
||||
return
|
||||
end
|
||||
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_toggle_button_name,
|
||||
sprite = 'utility/preset',
|
||||
style = Public.button_style,
|
||||
tooltip = 'Click to hide top buttons!'
|
||||
}
|
||||
)
|
||||
b.style.padding = 2
|
||||
b.style.width = 20
|
||||
b.style.maximal_height = 38
|
||||
if Public.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
Public.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_toggle_button_name,
|
||||
sprite = 'utility/preset',
|
||||
tooltip = 'Click to hide top buttons!',
|
||||
style = Public.button_style
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 15
|
||||
b.style.maximal_width = 15
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_toggle_button_name,
|
||||
sprite = 'utility/preset',
|
||||
style = Public.button_style,
|
||||
tooltip = 'Click to hide top buttons!'
|
||||
}
|
||||
)
|
||||
b.style.padding = 2
|
||||
b.style.width = 20
|
||||
b.style.maximal_height = 38
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_main_frame(player)
|
||||
@ -951,6 +980,7 @@ Public.on_click(
|
||||
end
|
||||
local player = event.player
|
||||
local frame = Public.get_parent_frame(player)
|
||||
|
||||
if frame then
|
||||
remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
@ -999,9 +1029,17 @@ Public.on_click(
|
||||
local top = player.gui.top
|
||||
|
||||
if button.sprite == 'utility/preset' then
|
||||
for _, ele in pairs(top.children) do
|
||||
if ele and ele.valid and ele.name ~= main_toggle_button_name then
|
||||
ele.visible = false
|
||||
if Public.get_mod_gui_top_frame() then
|
||||
for _, ele in pairs(top.mod_gui_top_frame.mod_gui_inner_frame.children) do
|
||||
if ele and ele.valid and ele.name ~= main_toggle_button_name then
|
||||
ele.visible = false
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, ele in pairs(top.children) do
|
||||
if ele and ele.valid and ele.name ~= main_toggle_button_name then
|
||||
ele.visible = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1015,9 +1053,17 @@ Public.on_click(
|
||||
button.sprite = 'utility/expand_dots_white'
|
||||
button.tooltip = 'Click to show top buttons!'
|
||||
else
|
||||
for _, ele in pairs(top.children) do
|
||||
if ele and ele.valid and ele.name ~= main_toggle_button_name then
|
||||
ele.visible = true
|
||||
if Public.get_mod_gui_top_frame() then
|
||||
for _, ele in pairs(top.mod_gui_top_frame.mod_gui_inner_frame.children) do
|
||||
if ele and ele.valid and ele.name ~= main_toggle_button_name then
|
||||
ele.visible = true
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, ele in pairs(top.children) do
|
||||
if ele and ele.valid and ele.name ~= main_toggle_button_name then
|
||||
ele.visible = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
9
utils/gui/init.lua
Normal file
9
utils/gui/init.lua
Normal file
@ -0,0 +1,9 @@
|
||||
require 'utils.gui'
|
||||
require 'utils.gui.player_list'
|
||||
require 'utils.gui.admin'
|
||||
require 'utils.gui.group'
|
||||
require 'utils.gui.score'
|
||||
require 'utils.gui.statistics'
|
||||
require 'utils.gui.config'
|
||||
require 'utils.gui.poll'
|
||||
require 'utils.gui.server_select'
|
@ -767,7 +767,8 @@ local function player_joined(event)
|
||||
end
|
||||
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
Gui.add_mod_button(
|
||||
local button =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
@ -777,6 +778,14 @@ local function player_joined(event)
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
if button then
|
||||
button.style.font_color = {165, 165, 165}
|
||||
button.style.font = 'heading-3'
|
||||
button.style.minimal_height = 36
|
||||
button.style.maximal_height = 36
|
||||
button.style.minimal_width = 40
|
||||
button.style.padding = -2
|
||||
end
|
||||
else
|
||||
if player.gui.top[main_button_name] ~= nil then
|
||||
local frame = player.gui.top[main_frame_name]
|
||||
|
@ -132,8 +132,13 @@ local function create_main_button(event)
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
Gui.add_mod_button(
|
||||
local b =
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
@ -143,6 +148,14 @@ local function create_main_button(event)
|
||||
style = Gui.button_style
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 36
|
||||
b.style.maximal_height = 36
|
||||
b.style.minimal_width = 40
|
||||
b.style.padding = -2
|
||||
end
|
||||
else
|
||||
local main_button = player.gui.top[main_button_name]
|
||||
if not main_button or not main_button.valid then
|
||||
|
104
utils/gui/statistics.lua
Normal file
104
utils/gui/statistics.lua
Normal file
@ -0,0 +1,104 @@
|
||||
-- created by Gerkiz for ComfyFactorio
|
||||
|
||||
local Gui = require 'utils.gui'
|
||||
local Token = require 'utils.token'
|
||||
local StatData = require 'utils.datastore.statistics'
|
||||
local format_number = require 'util'.format_number
|
||||
local Server = require 'utils.server'
|
||||
|
||||
local Public = {}
|
||||
|
||||
local module_name = Gui.uid_name()
|
||||
|
||||
local ignored_stats = {
|
||||
['name'] = true,
|
||||
['tick'] = true
|
||||
}
|
||||
|
||||
local normalized_names = StatData.normalized_names
|
||||
|
||||
local function show_score(data)
|
||||
local player = data.player
|
||||
local frame = data.frame
|
||||
frame.clear()
|
||||
|
||||
local t = frame.add {type = 'table', column_count = 2}
|
||||
|
||||
local tooltip = 'Your statistics that are gathered throughout Comfy servers.'
|
||||
local secs = Server.get_current_time()
|
||||
if not secs then
|
||||
tooltip = 'Not currently connected to any backend. Statistics will reset.'
|
||||
end
|
||||
|
||||
local label =
|
||||
t.add {
|
||||
type = 'label',
|
||||
caption = tooltip
|
||||
}
|
||||
|
||||
label.style.font = 'heading-2'
|
||||
label.style.font_color = {r = 0.98, g = 0.66, b = 0.22}
|
||||
label.style.minimal_width = 125
|
||||
label.style.horizontal_align = 'center'
|
||||
|
||||
local line = frame.add {type = 'line'}
|
||||
line.style.top_margin = 8
|
||||
line.style.bottom_margin = 8
|
||||
|
||||
local stat_data = StatData.get_data(player)
|
||||
|
||||
local scroll_pane =
|
||||
frame.add(
|
||||
{
|
||||
type = 'scroll-pane',
|
||||
name = 'score_scroll_pane',
|
||||
direction = 'vertical',
|
||||
horizontal_scroll_policy = 'never',
|
||||
vertical_scroll_policy = 'auto'
|
||||
}
|
||||
)
|
||||
scroll_pane.style.maximal_height = 400
|
||||
local column_table = scroll_pane.add {type = 'table', column_count = 4}
|
||||
|
||||
for name, stat in pairs(stat_data) do
|
||||
if not ignored_stats[name] then
|
||||
local c = stat
|
||||
if stat and type(stat) == 'number' then
|
||||
c = format_number(stat, true)
|
||||
end
|
||||
local lines = {
|
||||
{caption = normalized_names[name].name, tooltip = normalized_names[name].tooltip or ''},
|
||||
{caption = c}
|
||||
}
|
||||
local default_color = {r = 0.9, g = 0.9, b = 0.9}
|
||||
|
||||
for _, column in ipairs(lines) do
|
||||
local l =
|
||||
column_table.add {
|
||||
type = 'label',
|
||||
caption = column.caption,
|
||||
tooltip = column.tooltip,
|
||||
color = column.color or default_color
|
||||
}
|
||||
l.style.font = 'heading-3'
|
||||
l.style.minimal_width = 175
|
||||
l.style.maximal_width = 175
|
||||
l.style.horizontal_align = 'left'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local show_stats_token = Token.register(show_score)
|
||||
|
||||
Gui.add_tab_to_gui({name = module_name, caption = 'Statistics', id = show_stats_token, admin = false})
|
||||
|
||||
Gui.on_click(
|
||||
module_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
Gui.reload_active_tab(player)
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
Loading…
Reference in New Issue
Block a user