Merge branch 'dev' into dev2

This commit is contained in:
2023-12-22 13:37:33 +09:00
committed by GitHub
10 changed files with 370 additions and 24 deletions

View File

@@ -44,6 +44,8 @@ return {
'modules.commands.vlayer',
'modules.commands.enemy',
'modules.commands.waterfill',
'modules.commands.artillery',
'modules.commands.surface-clearing',
--- Addons
'modules.addons.chat-popups',
@@ -93,6 +95,7 @@ return {
'modules.gui.research',
'modules.gui.module',
'modules.gui.playerdata',
'modules.gui.surveillance',
'modules.graftorio.require', -- graftorio
--- Config Files

View File

@@ -232,7 +232,11 @@ Roles.new_role('Member','Mem')
'command/auto-research',
'command/manual-train',
'command/lawnmower',
'command/waterfill'
'command/waterfill',
'command/artillery-target-remote',
'command/clear-item-on-ground',
'command/clear-blueprint',
'gui/surveillance'
}
local hours3, hours15 = 3*216000, 15*60

View File

@@ -1,6 +1,6 @@
return {
-- type of machine to handle together
default_module_row_count = 4,
default_module_row_count = 6,
module_slot_max = 4,
machine_prod_disallow = {
['beacon'] = true

View File

@@ -7,14 +7,24 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles
local Gui = require 'expcore.gui' --- @dep expcore.gui
local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data
-- Global queue used to store trees that need to be removed, also chache for player roles
local chache = {}
-- Global queue used to store trees that need to be removed, also cache for player roles
local cache = {}
local tree_queue = { _head=0 }
Global.register({tree_queue, chache}, function(tbl)
Global.register({tree_queue, cache}, function(tbl)
tree_queue = tbl[1]
chache = tbl[2]
cache = tbl[2]
end)
local function get_permission(player_index)
if cache[player_index] == nil then
local player = game.players[player_index]
if Roles.player_allowed(player, 'fast-tree-decon') then cache[player_index] = 'fast'
elseif Roles.player_allowed(player, 'standard-decon') then cache[player_index] = 'standard'
else cache[player_index] = player.force end
end
return cache[player_index]
end
-- Left menu button to toggle between fast decon and normal decon marking
local HasEnabledDecon = PlayerData.Settings:combine('HasEnabledDecon')
@@ -36,20 +46,14 @@ Event.add(defines.events.on_marked_for_deconstruction, function(event)
-- Check which type of decon a player is allowed
local index = event.player_index
if not index then return end
if chache[index] == nil then
local player = game.players[index]
if Roles.player_allowed(player, 'fast-tree-decon') then chache[index] = 'fast'
elseif Roles.player_allowed(player, 'standard-decon') then chache[index] = 'standard'
else chache[index] = player.force end
end
-- Check what should happen to this entity
local entity = event.entity
local allow = chache[index]
if not entity or not entity.valid then return end
-- Not allowed to decon this entity
local last_user = entity.last_user
local allow = get_permission(index)
if last_user and allow ~= 'standard' and allow ~= 'fast' then
entity.cancel_deconstruction(allow)
return
@@ -58,7 +62,6 @@ Event.add(defines.events.on_marked_for_deconstruction, function(event)
-- Allowed to decon this entity, but not fast
if allow ~= 'fast' then return end
local player = game.get_player(index)
if not HasEnabledDecon:get(player) then return end
@@ -91,9 +94,34 @@ Event.add(defines.events.on_tick, function()
tree_queue._head = head
end)
-- Clear the chache
-- Clear the cache
Event.on_nth_tick(300, function()
for key, _ in pairs(chache) do
chache[key] = nil
for key, _ in pairs(cache) do
cache[key] = nil
end
end)
end)
-- Clear trees when hit with a car
Event.add(defines.events.on_entity_damaged, function(event)
if not (event.damage_type.name == 'impact' and event.force) then
return
end
if not (event.entity.type == 'tree' or event.entity.type == 'simple-entity') then
return
end
if (not event.cause) or (event.cause.type ~= 'car')then
return
end
local driver = event.cause.get_driver()
if not driver then return end
local allow = get_permission(driver.player.index)
if allow == "fast" and HasEnabledDecon:get(driver.player) then
event.entity.destroy()
else
event.entity.order_deconstruction(event.force, driver.player)
end
end)

View File

@@ -0,0 +1,84 @@
--[[-- Commands Module - Artillery
- Adds a command that help shot artillery
@commands Artillery
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
local Selection = require 'modules.control.selection' --- @dep modules.control.selection
local SelectionArtyArea = 'ArtyArea'
local function location_break(player, pos)
if player.force.is_chunk_charted(player.surface, {x=math.floor(pos.left_top.x / 32), y=math.floor(pos.left_top.y / 32)}) then
return true
elseif player.force.is_chunk_charted(player.surface, {x=math.floor(pos.left_top.x / 32), y=math.floor(pos.right_bottom.y / 32)}) then
return true
elseif player.force.is_chunk_charted(player.surface, {x=math.floor(pos.right_bottom.x / 32), y=math.floor(pos.left_top.y / 32)}) then
return true
elseif player.force.is_chunk_charted(player.surface, {x=math.floor(pos.right_bottom.x / 32), y=math.floor(pos.right_bottom.y / 32)}) then
return true
else
return false
end
end
--- align an aabb to the grid by expanding it
local function aabb_align_expand(aabb)
return {
left_top = {x = math.floor(aabb.left_top.x), y = math.floor(aabb.left_top.y)},
right_bottom = {x = math.ceil(aabb.right_bottom.x), y = math.ceil(aabb.right_bottom.y)}
}
end
--- when an area is selected to add protection to the area
Selection.on_selection(SelectionArtyArea, function(event)
local area = aabb_align_expand(event.area)
local player = game.get_player(event.player_index)
if player == nil then
return
end
if not (game.players[event.player_index].cheat_mode or location_break(player, event.area)) then
return Commands.error
end
local count = 0
local hit = {}
for _, e in pairs(player.surface.find_entities_filtered({area=area, type={'unit-spawner', 'turret'}, force='enemy'})) do
local skip = false
for _, pos in ipairs(hit) do
if math.sqrt(math.abs(e.position.x - pos.x) ^ 2 + math.abs(e.position.y - pos.y) ^ 2) < 6 then
skip = true
break
end
end
if not skip then
player.surface.create_entity{name='artillery-flare', position=e.position, force=player.force, life_time=120, movement={0, 0}, height=0, vertical_speed=0, frame_speed=0}
table.insert(hit, e.position)
count = count + 1
if count > 400 then
break
end
end
end
end)
Commands.new_command('artillery-target-remote', 'Artillery Target Remote')
:register(function(player)
if Selection.is_selecting(player, SelectionArtyArea) then
Selection.stop(player)
else
Selection.start(player, SelectionArtyArea)
end
return Commands.success
end)

View File

@@ -15,5 +15,5 @@ Commands.new_command('last-location', 'Sends you the last location of a player')
:add_param('player', false, 'player')
:register(function(player, action_player)
local action_player_name_color = format_chat_player_name(action_player)
player.print{'expcom-lastlocation.response', action_player_name_color, action_player.position.x, action_player.position.y}
end)
player.print{'expcom-lastlocation.response', action_player_name_color, string.format('%.1f', action_player.position.x), string.format('%.1f', action_player.position.y)}
end)

View File

@@ -0,0 +1,33 @@
--[[-- Commands Module - Clear Item On Ground
- Adds a command that clear item on ground so blueprint can deploy safely
@commands Clear Item On Ground
]]
local copy_items_stack = _C.copy_items_stack --- @dep expcore.common
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
Commands.new_command('clear-item-on-ground', 'Clear Item On Ground')
:add_param('range', false, 'integer-range', 1, 1000)
:register(function(player, range)
for _, e in pairs(player.surface.find_entities_filtered{position=player.position, radius=range, name='item-on-ground'}) do
if e.stack then
-- calling move_items_stack(e.stack) will crash to desktop
-- https://forums.factorio.com/viewtopic.php?f=7&t=110322
copy_items_stack{e.stack}
e.stack.clear()
end
end
return Commands.success
end)
Commands.new_command('clear-blueprint', 'Clear Blueprint')
:add_param('range', false, 'integer-range', 1, 1000)
:register(function(player, range)
for _, e in pairs(player.surface.find_entities_filtered{position=player.position, radius=range, type='entity-ghost'}) do
e.destroy()
end
return Commands.success
end)

View File

@@ -38,6 +38,12 @@ Selection.on_selection(SelectionConvertArea, function(event)
local player = game.get_player(event.player_index)
local entities = player.surface.find_entities_filtered{area=area, name='steel-chest'}
if #entities == 0 then
player.print('No steel chest found')
return
end
local tiles_to_make = {}
local inv = player.get_main_inventory()
local clf_exp = inv.get_item_count('cliff-explosives')

View File

@@ -67,21 +67,36 @@ local function clear_module(player, area, machine)
end
end
local function apply_module(player, area, machine, module)
local function apply_module(player, area, machine, modules)
for _, entity in pairs(player.surface.find_entities_filtered{area=area, name=machine, force=player.force}) do
if config.machine_craft[machine] then
local m_current_recipe = entity.get_recipe()
if m_current_recipe ~= nil then
if config.module_allowed[m_current_recipe.name] then
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=module} end
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=modules}
entity.last_user = player
else
for k in pairs(modules) do
if k:find('productivity') then
modules[k:gsub('productivity', 'effectivity')] = modules[k]
modules[k] = nil
end
end
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=modules}
entity.last_user = player
end
else
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=module}
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=modules}
entity.last_user = player
end
else
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=module}
entity.surface.create_entity{name='item-request-proxy', target=entity, position=entity.position, force=entity.force, modules=modules}
entity.last_user = player
end
end
end

View File

@@ -0,0 +1,173 @@
---- module surveillance
-- @addon surveillance
local Gui = require 'expcore.gui' --- @dep expcore.gui
local Roles = require 'expcore.roles' --- @dep expcore.roles
local Event = require 'utils.event' --- @dep utils.event
local cctv_container
local cctv_player =
Gui.element(function(name, parent, player_list)
return parent.add{
name = name,
type = 'drop-down',
items = player_list,
selected_index = #player_list > 0 and 1
}
end)
:style{
horizontally_stretchable = true
}
local cctv_type =
Gui.element{
type = 'drop-down',
name = 'cctv_status',
items = {'Enable', 'Disable'},
selected_index = 2
}:style{
width = 96
}:on_selection_changed(function(_, element, _)
if element.selected_index == 1 then
element.parent.parent.parent.cctv_display.visible = true
else
element.parent.parent.parent.cctv_display.visible = false
end
end)
local cctv_status =
Gui.element{
type = 'drop-down',
name = 'cctv_status',
items = {'Player', 'Static'},
selected_index = 1
}:style{
width = 96
}
local cctv_location =
Gui.element{
type = 'button',
caption = 'set'
}:style{
width = 48
}:on_click(function(player, element, _)
element.parent.parent.parent.cctv_display.position = player.position
end)
local zoom_in =
Gui.element{
type = 'button',
caption = '+'
}:style{
width = 32
}:on_click(function(_, element, _)
local display = element.parent.parent.parent.cctv_display
if display.zoom < 2.0 then
display.zoom = display.zoom + 0.05
end
end)
local zoom_out =
Gui.element{
type = 'button',
caption = '-'
}:style{
width = 32
}:on_click(function(_, element, _)
local display = element.parent.parent.parent.cctv_display
if display.zoom > 0.2 then
display.zoom = display.zoom - 0.05
end
end)
local camera_set =
Gui.element(function(_, parent, name, player_list)
local camera_set = parent.add{type='flow', direction='vertical', name=name}
local buttons = Gui.scroll_table(camera_set, 480, 6, 'buttons')
cctv_player(buttons, player_list)
cctv_type(buttons)
cctv_status(buttons)
cctv_location(buttons)
zoom_out(buttons)
zoom_in(buttons)
local camera = camera_set.add{
type = 'camera',
name = 'cctv_display',
position = {x=0, y=0},
surface_index = game.surfaces['nauvis'].index,
zoom = 0.75,
}
camera.visible = false
camera.style.minimal_width = 480
camera.style.minimal_height = 360
return camera_set
end)
cctv_container =
Gui.element(function(event_trigger, parent)
local container = Gui.container(parent, event_trigger, 480)
local scroll = container.add{name='scroll', type='scroll-pane', direction='vertical'}
scroll.style.maximal_height = 704
local player_list = {}
for _, player in pairs(game.connected_players) do
table.insert(player_list, player.name)
end
camera_set(scroll, 'cctv_st_1', player_list)
camera_set(scroll, 'cctv_st_2', player_list)
return container.parent
end)
:add_to_left_flow()
Gui.left_toolbar_button('entity/radar', 'Surveillance GUI', cctv_container, function(player)
return Roles.player_allowed(player, 'gui/surveillance')
end)
local function gui_update()
local player_list = {}
for _, player in pairs(game.connected_players) do
table.insert(player_list, player.name)
end
for _, player in pairs(game.connected_players) do
local frame = Gui.get_left_element(player, cctv_container)
frame.container.scroll['cctv_st_1'].buttons.table[cctv_player.name].items = player_list
frame.container.scroll['cctv_st_2'].buttons.table[cctv_player.name].items = player_list
end
end
Event.add(defines.events.on_player_joined_game, gui_update)
Event.add(defines.events.on_player_left_game, gui_update)
Event.add(defines.events.on_tick, function(_)
for _, player in pairs(game.connected_players) do
local frame = Gui.get_left_element(player, cctv_container)
for i=1, 2 do
local scroll_table_name = 'cctv_st_' .. i
local current_camera_set = frame.container.scroll[scroll_table_name]
local switch_index = current_camera_set.buttons.table[cctv_status.name].selected_index
if switch_index == 1 then
local selected_index = current_camera_set.buttons.table[cctv_player.name].selected_index
if selected_index > 0 then
current_camera_set['cctv_display'].position = game.players[selected_index].position
current_camera_set['cctv_display'].surface_index = game.players[selected_index].surface_index
else
current_camera_set['cctv_display'].position = {x=0, y=0}
current_camera_set['cctv_display'].surface_index = game.surfaces['nauvis'].index
end
end
end
end
end)