Feature Update (#237)

See PR for details, there are too many to be included here.
This commit is contained in:
2023-08-16 02:47:34 +09:00
committed by GitHub
parent cdd34ebaea
commit 46f6215d94
64 changed files with 4417 additions and 289 deletions

View File

@@ -27,6 +27,14 @@ Event.add(defines.events.on_player_created, function(event)
end
end
end
if config.armor.enable then
player.insert{name=config.armor.main, count=1}
for _, item in pairs(config.armor.item) do
player.insert{name=item.equipment, count=item.count}
end
end
end)
Event.on_init(function()

View File

@@ -70,9 +70,11 @@ function Public.add_compilatron(entity, name)
if not entity and not entity.valid then
return
end
if name == nil then
return
end
Public.compilatrons[name] = entity
local message =
entity.surface.create_entity(
@@ -95,6 +97,7 @@ end
Event.add(defines.events.on_player_created, function(event)
if event.player_index ~= 1 then return end
local player = game.players[event.player_index]
for location in pairs(locations) do
Public.spawn_compilatron(player.surface, location)
end

View File

@@ -11,13 +11,28 @@ local filepath = "log/decon.log"
local function add_log(data)
game.write_file(filepath, data .. "\n", true, 0) -- write data
end
local function get_secs ()
local function get_secs()
return format_time(game.tick, { hours = true, minutes = true, seconds = true, string = true })
end
local function pos_tostring (pos)
local function pos_to_string(pos)
return tostring(pos.x) .. "," .. tostring(pos.y)
end
local function pos_to_gps_string(pos)
return '[gps=' .. tostring(pos.x) .. ',' .. tostring(pos.y) .. ']'
end
--- Print a message to all players who match the value of admin
local function print_to_players(admin, message)
for _, player in ipairs(game.connected_players) do
if player.admin == admin then
player.print(message)
end
end
end
Event.on_init(function()
game.write_file(filepath, "\n", false, 0) -- write data
end)
@@ -25,8 +40,17 @@ end)
if config.decon_area then
Event.add(defines.events.on_player_deconstructed_area, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
add_log(get_secs() .. "," .. player.name .. ",decon_area," .. pos_tostring(e.area.left_top) .. "," .. pos_tostring(e.area.right_bottom))
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local items = e.surface.find_entities_filtered{area=e.area, force=player.force}
if #items > 250 then
print_to_players(true, player.name .. ' tried to deconstruct the area ' .. pos_to_gps_string(e.area.left_top) .. ' to ' .. pos_to_gps_string(e.area.right_bottom) .. ' that have ' .. #items .. ' items, but were not allowed.')
end
add_log(get_secs() .. "," .. player.name .. ",decon_area," .. pos_to_string(e.area.left_top) .. "," .. pos_to_string(e.area.right_bottom))
end)
end
@@ -34,30 +58,38 @@ if config.built_entity then
Event.add(defines.events.on_built_entity, function (e)
if not e.player_index then return end
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ent = e.created_entity
add_log(get_secs() .. "," .. player.name .. ",built_entity," .. ent.name .. "," .. pos_tostring(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
add_log(get_secs() .. "," .. player.name .. ",built_entity," .. ent.name .. "," .. pos_to_string(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
end
if config.mined_entity then
Event.add(defines.events.on_player_mined_entity, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ent = e.entity
add_log(get_secs() .. "," .. player.name .. ",mined_entity," .. ent.name .. "," .. pos_tostring(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
add_log(get_secs() .. "," .. player.name .. ",mined_entity," .. ent.name .. "," .. pos_to_string(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
end
if config.fired_rocket then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then return end
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-rocket," .. pos_tostring(player.position) .. "," .. pos_tostring(player.shooting_state.position))
add_log(get_secs() .. "," .. player.name .. ",shot-rocket," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
end
@@ -65,12 +97,18 @@ end
if config.fired_explosive_rocket then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then return end
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "explosive-rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-explosive-rocket," .. pos_tostring(player.position) .. "," .. pos_tostring(player.shooting_state.position))
add_log(get_secs() .. "," .. player.name .. ",shot-explosive-rocket," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
end
@@ -78,12 +116,20 @@ end
if config.fired_nuke then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
if Roles.player_has_flag(player, "deconlog-bypass") then
return
end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then return end
if not item or not item.valid or not item.valid_for_read then
return
end
if item.name == "atomic-bomb" then
add_log(get_secs() .. "," .. player.name .. ",shot-nuke," .. pos_tostring(player.position) .. "," .. pos_tostring(player.shooting_state.position))
add_log(get_secs() .. "," .. player.name .. ",shot-nuke," .. pos_to_string(player.position) .. "," .. pos_to_string(player.shooting_state.position))
end
end)
end

View File

@@ -6,12 +6,20 @@ local Colors = require 'utils.color_presets' --- @dep utils.color_presets
local write_json, format_time = _C.write_json, _C.format_time --- @dep expcore.common
local config = require 'config.discord_alerts' --- @dep config.discord_alerts
local playtime_format = { short = true, hours = true, minutes = true, string = true }
local playtime_format = {hours = true, minutes = true, short = true, string = true}
local function append_playtime(player_name)
if not config.show_playtime then return player_name end
if not config.show_playtime then
return player_name
end
local player = game.get_player(player_name)
if not player then return player_name end
return player.name..' ('..format_time(player.online_time, playtime_format)..')'
if not player then
return player_name
end
return player.name ..' (' .. format_time(player.online_time, playtime_format) .. ')'
end
local function get_player_name(event)
@@ -24,10 +32,10 @@ local function to_hex(color)
local function hex(bit)
local major, minor = math.modf(bit/16)
major, minor = major+1, minor*16+1
return hex_digits:sub(major, major)..hex_digits:sub(minor, minor)
return hex_digits:sub(major, major) .. hex_digits:sub(minor, minor)
end
return '0x'..hex(color.r)..hex(color.g)..hex(color.b)
return '0x' .. hex(color.r) .. hex(color.g) .. hex(color.b)
end
local function emit_event(args)
@@ -40,12 +48,14 @@ local function emit_event(args)
end
local tick = args.tick or game.tick
local tick_formatted = format_time(tick, {days = true, hours = true, minutes = true, string = true, long = true})
local tick_formatted = format_time(tick, {days = false, hours = true, minutes = true, short = true, string = true})
local players_online = 0
local admins_online = 0
for _, player in pairs(game.connected_players) do
players_online = players_online+1
players_online = players_online + 1
if player.admin then
admins_online = admins_online + 1
end
@@ -93,8 +103,9 @@ if config.entity_protection then
title='Entity Protection',
description='A player removed protected entities',
color=Colors.yellow,
['Player']='<inline>'..append_playtime(player_name),
['Entity']='<inline>'..event.entity.name
['Player']='<inline>' .. append_playtime(player_name),
['Entity']='<inline>' .. event.entity.name,
['Location']=event.entity.position
}
end)
end
@@ -108,9 +119,9 @@ if config.player_reports then
title='Report',
description='A player was reported',
color=Colors.yellow,
['Player']='<inline>'..append_playtime(player_name),
['By']='<inline>'..append_playtime(by_player_name),
['Report Count']='<inline>'..Reports.count_reports(player_name),
['Player']='<inline>' .. append_playtime(player_name),
['By']='<inline>' .. append_playtime(by_player_name),
['Report Count']='<inline>' .. Reports.count_reports(player_name),
['Reason']=event.reason
}
end)
@@ -121,9 +132,9 @@ if config.player_reports then
title='Reports Removed',
description='A player has a report removed',
color=Colors.green,
['Player']='<inline>'..player_name,
['By']='<inline>'..event.removed_by_name,
['Report Count']='<inline>'..event.batch_count
['Player']='<inline>' .. player_name,
['By']='<inline>' .. event.removed_by_name,
['Report Count']='<inline>' .. event.batch_count
}
end)
end
@@ -138,9 +149,9 @@ if config.player_warnings then
title='Warning',
description='A player has been given a warning',
color=Colors.yellow,
['Player']='<inline>'..player_name,
['By']='<inline>'..by_player_name,
['Warning Count']='<inline>'..Warnings.count_warnings(player),
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player_name,
['Warning Count']='<inline>' .. Warnings.count_warnings(player),
['Reason']=event.reason
}
end)
@@ -151,9 +162,9 @@ if config.player_warnings then
title='Warnings Removed',
description='A player has a warning removed',
color=Colors.green,
['Player']='<inline>'..player_name,
['By']='<inline>'..event.removed_by_name,
['Warning Count']='<inline>'..event.batch_count
['Player']='<inline>' .. player_name,
['By']='<inline>' .. event.removed_by_name,
['Warning Count']='<inline>' .. event.batch_count
}
end)
end
@@ -167,8 +178,8 @@ if config.player_jail then
title='Jail',
description='A player has been jailed',
color=Colors.yellow,
['Player']='<inline>'..player_name,
['By']='<inline>'..by_player_name,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player_name,
['Reason']=event.reason
}
end)
@@ -178,8 +189,8 @@ if config.player_jail then
title='Unjail',
description='A player has been unjailed',
color=Colors.green,
['Player']='<inline>'..player_name,
['By']='<inline>'..by_player_name
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player_name
}
end)
end
@@ -193,8 +204,8 @@ if config.player_bans then
title='Banned',
description='A player has been banned',
color=Colors.red,
['Player']='<inline>'..event.player_name,
['By']='<inline>'..by_player.name,
['Player']='<inline>' .. event.player_name,
['By']='<inline>' .. by_player.name,
['Reason']=event.reason
}
end
@@ -206,8 +217,8 @@ if config.player_bans then
title='Un-Banned',
description='A player has been un-banned',
color=Colors.green,
['Player']='<inline>'..event.player_name,
['By']='<inline>'..by_player.name
['Player']='<inline>' .. event.player_name,
['By']='<inline>' .. by_player.name
}
end
end)
@@ -221,7 +232,7 @@ if config.player_mutes then
title='Muted',
description='A player has been muted',
color=Colors.yellow,
['Player']='<inline>'..player_name
['Player']='<inline>' .. player_name
}
end)
Event.add(defines.events.on_player_unmuted, function(event)
@@ -230,7 +241,7 @@ if config.player_mutes then
title='Un-Muted',
description='A player has been un-muted',
color=Colors.green,
['Player']='<inline>'..player_name
['Player']='<inline>' .. player_name
}
end)
end
@@ -245,8 +256,8 @@ if config.player_kicks then
title='Kick',
description='A player has been kicked',
color=Colors.orange,
['Player']='<inline>'..player_name,
['By']='<inline>'..by_player.name,
['Player']='<inline>' .. player_name,
['By']='<inline>' .. by_player.name,
['Reason']=event.reason
}
end
@@ -261,7 +272,7 @@ if config.player_promotes then
title='Promote',
description='A player has been promoted',
color=Colors.green,
['Player']='<inline>'..player_name
['Player']='<inline>' .. player_name
}
end)
Event.add(defines.events.on_player_demoted, function(event)
@@ -270,7 +281,7 @@ if config.player_promotes then
title='Demote',
description='A player has been demoted',
color=Colors.yellow,
['Player']='<inline>'..player_name
['Player']='<inline>' .. player_name
}
end)
end
@@ -282,9 +293,9 @@ Event.add(defines.events.on_console_command, function(event)
if config[event.command] then
emit_event{
title=event.command:gsub('^%l', string.upper),
description='/'..event.command..' was used',
description='/' .. event.command .. ' was used',
color=Colors.grey,
['By']='<inline>'..player_name,
['By']='<inline>' .. player_name,
['Details'] = event.parameters ~= '' and event.parameters or nil
}
end

View File

@@ -0,0 +1,23 @@
local Event = require 'utils.event'
local controllers_with_inventory = {
[defines.controllers.character] = true,
[defines.controllers.god] = true,
[defines.controllers.editor] = true,
}
Event.add(defines.events.on_player_mined_entity, function(event)
if (not event.entity.valid) or (event.entity.type ~= 'inserter') or event.entity.drop_target then
return
end
local item_entity = event.entity.surface.find_entity('item-on-ground', event.entity.drop_position)
if item_entity then
local player = game.get_player(event.player_index)
if controllers_with_inventory[player.controller_type] then
player.mine_entity(item_entity)
end
end
end)

64
modules/addons/miner.lua Normal file
View File

@@ -0,0 +1,64 @@
local Event = require 'utils.event_core' --- @dep utils.event_core
local function miner_check(entity, event)
if ((math.abs(entity.position.x - event.entity.position.x) < entity.prototype.mining_drill_radius) and (math.abs(entity.position.y - event.entity.position.y) < entity.prototype.mining_drill_radius)) then
if entity.mining_target ~= nil and entity.mining_target.valid then
if entity.mining_target.amount > 0 then
return
end
local resources = entity.surface.find_entities_filtered{area={{entity.position.x - entity.prototype.mining_drill_radius, entity.position.y - entity.prototype.mining_drill_radius}, {entity.position.x + entity.prototype.mining_drill_radius, entity.position.y + entity.prototype.mining_drill_radius}}, type='resource'}
for _, resource in pairs(resources) do
if resource.amount > 0 then
-- if any tile in the radius have resources
return
end
end
if entity.to_be_deconstructed(entity.force) then
-- if it is already waiting to be deconstruct
return
else
if entity.fluidbox and #entity.fluidbox > 0 then
-- if require fluid to mine
return
end
if next(entity.circuit_connected_entities.red) ~= nil or next(entity.circuit_connected_entities.green) ~= nil then
-- connected to circuit network
return
end
if not entity.minable then
-- if it is minable
return
end
if not entity.prototype.selectable_in_game then
-- if it can select
return
end
if entity.has_flag('not-deconstructable') then
-- if it can deconstruct
return
end
entity.order_deconstruction(entity.force)
end
end
end
end
Event.add(defines.events.on_resource_depleted, function(event)
local entities = event.entity.surface.find_entities_filtered{area={{event.entity.position.x-1, event.entity.position.y-1}, {event.entity.position.x+1, event.entity.position.y+1}}, type='mining-drill'}
if #entities == 0 then
return
end
for _, entity in pairs(entities) do
miner_check(entity, event)
end
end)

View File

@@ -25,7 +25,10 @@ Event.add(Protection.events.on_repeat_violation, function(event)
end
-- Jail if needed
if repeat_count[player.index] < 3 then return end
if repeat_count[player.index] < 3 then
return
end
local player_name_color = format_chat_player_name(player)
Jail.jail_player(player, '<protection>', 'Removed too many protected entities, please wait for a moderator.')
game.print{'protection-jail.jail', player_name_color}

View File

@@ -9,17 +9,20 @@ local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.comm
--- Returns the playtime of the reporter. Used when calculating the total playtime of all reporters
local function reporter_playtime(_, by_player_name, _)
local player = game.get_player(by_player_name)
if player == nil then return 0 end
if player == nil then
return 0
end
return player.online_time
end
--- Tests the combined playtime of all reporters against the reported player
Event.add(Reports.events.on_player_reported, function(event)
local player = game.get_player(event.player_index)
local total_playtime = Reports.count_reports(player, reporter_playtime)
if total_playtime < player.online_time*1.5 then return end
-- Combined playtime is greater than 150% of the reported's playtime
local player_name_color = format_chat_player_name(player)
Jail.jail_player(player, '<reports>', 'Reported by too many players, please wait for a moderator.')
game.print{'report-jail.jail', player_name_color}
end)
-- player less than 30 min
if (Reports.count_reports(player) > 1) and (total_playtime > math.max(player.online_time * 2, 108000)) then
local player_name_color = format_chat_player_name(player)
Jail.jail_player(player, '<reports>', 'Reported by too many players, please wait for a moderator.')
game.print{'report-jail.jail', player_name_color}
end
end)

View File

@@ -12,7 +12,7 @@ end)
-- Apply an offset to a LuaPosition
local function apply_offset(position, offset)
return { x = position.x + (offset.x or offset[1]), y = position.y + (offset.y or offset[2]) }
return {x=position.x + (offset.x or offset[1]), y=position.y + (offset.y or offset[2])}
end
-- Apply the offset to the turrets default position
@@ -22,23 +22,33 @@ end
-- Get or create the force used for entities in spawn
local function get_spawn_force()
local force = game.forces['Spawn']
if force and force.valid then return force end
force = game.create_force('Spawn')
local force = game.forces['spawn']
if force and force.valid then
return force
end
force = game.create_force('spawn')
force.set_cease_fire('player', true)
game.forces['player'].set_cease_fire('Spawn', true)
-- force.set_friend('player', true)
game.forces['player'].set_cease_fire('spawn', true)
-- game.forces['player'].set_friend('spawn', true)
return force
end
-- Protects an entity and sets its force to the spawn force
-- Protects an entity
-- and sets its force to the spawn force
local function protect_entity(entity, set_force)
if entity and entity.valid then
entity.destructible = false
entity.minable = false
entity.rotatable = false
entity.operable = false
if not set_force then entity.health = 0 end
if set_force then entity.force = get_spawn_force() end
if set_force then
entity.force = get_spawn_force()
end
end
end
@@ -51,8 +61,8 @@ local function spawn_turrets()
-- Makes a new turret if it is not found
if not turret or not turret.valid then
turret = surface.create_entity{name='gun-turret', position=pos, force='Spawn'}
protect_entity(turret, true)
turret = surface.create_entity{name='gun-turret', position=pos, force='spawn'}
protect_entity(turret)
end
-- Adds ammo to the turret
@@ -68,12 +78,16 @@ local function spawn_belts(surface, position)
position = apply_offset(position, config.afk_belts.offset)
local belt_type = config.afk_belts.belt_type
local belt_details = {{-0.5, -0.5, 2}, {0.5, -0.5, 4}, {-0.5, 0.5, 0}, {0.5, 0.5, 6}} -- x, y,dir
for _, belt_set in pairs(config.afk_belts.locations) do
local set_position = apply_offset(position, belt_set)
for _, belt in pairs(belt_details) do
local pos = apply_offset(set_position, belt)
local belt_entity = surface.create_entity{name=belt_type, position=pos, force='neutral', direction=belt[3]}
if config.afk_belts.protected then protect_entity(belt_entity) end
local belt_entity = surface.create_entity{name=belt_type, position=pos, force='spawn', direction=belt[3]}
if config.afk_belts.protected then
protect_entity(belt_entity)
end
end
end
end
@@ -83,9 +97,11 @@ local function spawn_pattern(surface, position)
position = apply_offset(position, config.pattern.offset)
local tiles_to_make = {}
local pattern_tile = config.pattern.pattern_tile
for _, tile in pairs(config.pattern.locations) do
table.insert(tiles_to_make, {name=pattern_tile, position=apply_offset(position, tile)})
end
surface.set_tiles(tiles_to_make)
end
@@ -104,9 +120,13 @@ end
local function spawn_entities(surface, position)
position = apply_offset(position, config.entities.offset)
for _, entity in pairs(config.entities.locations) do
local pos = apply_offset(position, { x=entity[2], y=entity[3] })
local pos = apply_offset(position, {x=entity[2], y=entity[3]})
entity = surface.create_entity{name=entity[1], position=pos, force='neutral'}
if config.entities.protected then protect_entity(entity) end
if config.entities.protected then
protect_entity(entity)
end
entity.operable = config.entities.operable
end
end
@@ -114,7 +134,8 @@ end
-- Generates an area with no water or entities, no water area is larger
local function spawn_area(surface, position)
local dr = config.spawn_area.deconstruction_radius
local dr2 = dr^2
local tr = config.spawn_area.tile_radius
local tr2 = tr^2
local decon_tile = config.spawn_area.deconstruction_tile
local fr = config.spawn_area.landfill_radius
@@ -132,7 +153,7 @@ local function spawn_area(surface, position)
local y2 = (y+0.5)^2
local dst = x2+y2
local pos = {x=position.x+x, y=position.y+y}
if dst < dr2 then
if dst < tr2 then
-- If it is inside the decon radius always set the tile
table.insert(tiles_to_make, {name=decon_tile, position=pos})
elseif dst < fr2 and surface.get_tile(pos).collides_with('player-layer') then
@@ -144,10 +165,34 @@ local function spawn_area(surface, position)
-- Remove entities then set the tiles
local entities_to_remove = surface.find_entities_filtered{position=position, radius=dr, name='character', invert=true}
for _, entity in pairs(entities_to_remove) do entity.destroy() end
for _, entity in pairs(entities_to_remove) do
entity.destroy()
end
surface.set_tiles(tiles_to_make)
end
local function spawn_resource_tiles(surface)
for _, v in ipairs(config.resource_tiles.resources) do
if v.enabled then
for x=v.offset[1], v.offset[1] + v.size[1] do
for y=v.offset[2], v.offset[2] + v.size[2] do
surface.create_entity({name=v.name, amount=v.amount, position={x, y}})
end
end
end
end
end
local function spawn_resource_patches(surface)
for _, v in ipairs(config.resource_patches.resources) do
if v.enabled then
for i=1, v.num_patches do
surface.create_entity({name=v.name, amount=v.amount, position={v.offset[1] + v.offset_next[1] * (i - 1), v.offset[2] + v.offset_next[2] * (i - 1)}})
end
end
end
end
-- Only add a event handler if the turrets are enabled
if config.turrets.enabled then
Event.on_nth_tick(config.turrets.refill_time, function()
@@ -156,6 +201,19 @@ if config.turrets.enabled then
end)
end
if config.resource_refill_nearby.enabled then
-- could have a flag in global that early returns if true, and reset it on_tick
Event.on_nth_tick(36000, function()
if game.tick < 10 then
return
end
for _, ore in pairs(game.players[1].surface.find_entities_filtered{position=game.players[1].force.get_spawn_position(game.players[1].surface), radius=config.resource_refill_nearby.range, name=config.resource_refill_nearby.resources_name}) do
ore.amount = ore.amount + math.random(config.resource_refill_nearby.amount[1], config.resource_refill_nearby.amount[2])
end
end)
end
-- When the first player joins create the spawn area
Event.add(defines.events.on_player_created, function(event)
if event.player_index ~= 1 then return end
@@ -169,8 +227,10 @@ Event.add(defines.events.on_player_created, function(event)
if config.afk_belts.enabled then spawn_belts(s, p) end
if config.turrets.enabled then spawn_turrets() end
if config.entities.enabled then spawn_entities(s, p) end
if config.resource_tiles.enabled then spawn_resource_tiles(s) end
if config.resource_patches.enabled then spawn_resource_patches(s) end
player.teleport(p, s)
end)
-- Way to access global table
return turrets
return turrets

View File

@@ -1,6 +1,7 @@
---LuaPlayerBuiltEntityEventFilters
---Events.set_event_filter(defines.events.on_built_entity, {{filter = "name", name = "fast-inserter"}})
local Event = require 'utils.event' --- @dep utils.event
local config = require 'config.station_auto_name' --- @dep config.chat_reply
--Credit to Cooldude2606 for using his lua magic to make this function.
local directions = {
@@ -46,10 +47,9 @@ local function station_name_changer(event)
local boundingBox = entity.bounding_box
-- expanded box for recourse search:
local bounding2 = { {boundingBox.left_top.x -100 ,boundingBox.left_top.y -100} , {boundingBox.right_bottom.x +100, boundingBox.right_bottom.y +100 } }
local bounding2 = {{boundingBox.left_top.x-100 ,boundingBox.left_top.y-100} , {boundingBox.right_bottom.x+100, boundingBox.right_bottom.y+100 }}
-- gets all resources in bounding_box2:
local recourses = game.surfaces[1].find_entities_filtered{area = bounding2, type = "resource"}
if #recourses > 0 then -- save cpu time if their are no recourses in bounding_box2
local closest_distance
local px, py = boundingBox.left_top.x, boundingBox.left_top.y
@@ -70,12 +70,17 @@ local function station_name_changer(event)
if item_name then -- prevent errors if something went wrong
local item_name2 = item_name:gsub("^%l", string.upper):gsub('-', ' ') -- removing the - and making first letter capital
local Item_ore_fluid = "item"
if item_name == "crude-oil" then
Item_ore_fluid = "fluid"
local item_type = 'item'
if item_name == 'crude-oil' then
item_type = 'fluid'
end
--Final string:
entity.backer_name = string.format("[L] [img=%s.%s] %s %s (%s)", Item_ore_fluid, item_name, item_name2, entity.backer_name, Angle( entity ))
entity.backer_name = config.station_name:gsub('__icon__', '[img=' .. item_type .. '.' .. item_name .. ']')
:gsub('__item_name__', item_name2)
:gsub('__backer_name__', entity.backer_name)
:gsub('__direction__', Angle(entity))
:gsub('__x__', math.floor(entity.position.x))
:gsub('__y__', math.floor(entity.position.y))
end
end
end

View File

@@ -10,7 +10,7 @@ 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 = {}
local tree_queue = { _head=0 }
Global.register({ tree_queue, chache }, function(tbl)
Global.register({tree_queue, chache}, function(tbl)
tree_queue = tbl[1]
chache = tbl[2]
end)

View File

@@ -0,0 +1,24 @@
--[[-- Commands Module - Bot queue
- Adds a command that allows changing bot queue
@commands Bot Queue
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
Commands.new_command('bot-queue-get', 'Get bot queue')
:set_flag('admin_only')
:register(function(player)
local s = player.force.max_successful_attempts_per_tick_per_construction_queue
local f = player.force.max_failed_attempts_per_tick_per_construction_queue
return Commands.success{'expcom-bot-queue.result', s, f}
end)
Commands.new_command('bot-queue-set', 'Set bot queue')
:add_param('amount', 'integer-range', 1, 20)
:set_flag('admin_only')
:register(function(player, amount)
player.force.max_successful_attempts_per_tick_per_construction_queue = 3 * amount
player.force.max_failed_attempts_per_tick_per_construction_queue = 1 * amount
return Commands.success{'expcom-bot-queue.result', 3 * amount, 1 * amount}
end)

View File

@@ -17,4 +17,27 @@ end}
:set_flag('admin_only')
:register(function(_, player)
player.cheat_mode = not player.cheat_mode
end)
return Commands.success
end)
Commands.new_command('research-all', 'Set all research for your force.')
:set_flag('admin_only')
:add_param('force', true, 'force')
:set_defaults{force=function(player)
return player.force
end}
:register(function(_, force)
force.research_all_technologies()
return Commands.success
end)
Commands.new_command('toggle-always-day', 'Toggles always day in surface')
:set_flag('admin_only')
:add_param('surface', true, 'surface')
:set_defaults{surface=function(player)
return player.surface
end}
:register(function(_, surface)
surface.always_day = not surface.always_day
return Commands.success{'expcom-cheat.day', surface.always_day}
end)

View File

@@ -0,0 +1,30 @@
--[[-- Commands Module - Enemy
- Adds a command of handling enemy
@commands Enemy
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
Commands.new_command('kill-biters', 'Kill all biters (only)')
:set_flag('admin_only')
:register(function(_, _)
game.forces['enemy'].kill_all_units()
return Commands.success
end)
Commands.new_command('remove-biters', 'Remove biters and prevent generation')
:set_flag('admin_only')
:add_param('surface', true, 'surface')
:set_defaults{surface=function(player)
return player.surface
end}
:register(function(_, surface)
for _, entity in pairs(surface.find_entities_filtered({force='enemy'})) do
entity.destroy()
end
surface.map_gen_settings.autoplace_controls['enemy-base'].size = 'none'
return Commands.success
end)

View File

@@ -0,0 +1,18 @@
--[[-- Commands Module - Toggle Friendly Fire
- Adds a command that toggle all friendly fire
@commands Toggle Friendly Fire
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
-- For Modded Server Use
Commands.new_command('toggle-friendly-fire', 'Toggle Friendly Fire')
:add_param('force', true, 'force')
:set_defaults{force=function(player)
return player.force
end}
:register(function(_, force)
force.friendly_fire = not force.friendly_fire
return Commands.success{'expcom-ff.ff', force.friendly_fire}
end)

View File

@@ -0,0 +1,31 @@
--[[-- Commands Module - Lawnmower
- Adds a command that clean up biter corpse and nuclear hole
@commands Lawnmower
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
Commands.new_command('lawnmower', 'Clean up biter corpse, decoratives and nuclear hole')
:add_param('range', false, 'integer-range', 1, 200)
:register(function(player, range)
local tile_to_do = {}
player.surface.destroy_decoratives({position=player.position, radius=range})
local entities = player.surface.find_entities_filtered{position=player.position, radius=range, type='corpse', name={'transport-caution-corpse', 'invisible-transport-caution-corpse'}}
for _, entity in pairs(entities) do
entity.destroy()
end
local tiles = player.surface.find_tiles_filtered{position=player.position, radius=range, name={'nuclear-ground'}}
for _, tile in pairs(tiles) do
table.insert(tile_to_do, {name='grass-1', position=tile.position})
end
player.surface.set_tiles(tile_to_do)
return Commands.success
end)

View File

@@ -0,0 +1,32 @@
--[[-- Commands Module - Pollution Handle
- Adds a command that allows modifying pollution
@commands Pollution Handle
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
Commands.new_command('pollution-clear', 'Clear pollution')
:set_flag('admin_only')
:add_alias('pol-clr')
:add_param('surface', true, 'surface')
:set_defaults{surface=function(player)
return player.surface
end}
:register(function(player, surface)
surface.clear_pollution()
return Commands.success{'expcom-pol.clr', player}
end)
Commands.new_command('pollution-off', 'Disable pollution')
:set_flag('admin_only')
:add_alias('pol-off')
:register(function(player)
game.map_settings.pollution.enabled = false
for _, v in pairs(game.surfaces) do
v.clear_pollution()
end
return Commands.success{'expcom-pol.off', player.name}
end)

View File

@@ -36,8 +36,8 @@ 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) }
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
@@ -51,7 +51,6 @@ local function get_area_key(area)
return string.format('%i,%i', math.floor(area.left_top.x), math.floor(area.left_top.y))
end
--- Show a protected entity to a player
local function show_protected_entity(player, entity)
local key = get_entity_key(entity)

View File

@@ -12,7 +12,7 @@ local max_time_to_live = 4294967295 -- unit32 max
-- @command repair
-- @tparam number range the range to repair stuff in, there is a max limit to this
Commands.new_command('repair', 'Repairs entities on your force around you')
:add_param('range', false, 'integer-range', 1,config.max_range)
:add_param('range', false, 'integer-range', 1, config.max_range)
:register(function(player, range)
local revive_count = 0
local heal_count = 0

View File

@@ -0,0 +1,94 @@
local Event = require 'utils.event' --- @dep utils.event
local Common = require 'expcore.common' --- @dep utils.event
local Global = require 'utils.global' --- @dep utils.global
local config = require 'config.research' --- @dep config.research
local config_bonus = Common.opt_require 'config.bonus' --- @dep config.bonus
local Commands = require 'expcore.commands' --- @dep expcore.commands
local format_time = _C.format_time --- @dep expcore.common
local research = {}
Global.register(research, function(tbl)
research = tbl
end)
local research_time_format = {hours=true, minutes=true, seconds=true, time=true, string=true}
research.res_queue_enable = false
local base_rate = 0
if config.bonus.enabled then
for k, _ in pairs(config_bonus.force_bonus) do
if config_bonus.force_bonus[k].name == config.bonus.name then
base_rate = config_bonus.force_bonus[k].max
end
end
end
local function research_notification(event)
local is_inf_res = false
for i=1, #config.inf_res do
if (event.research.name == config.inf_res[i].name) and (event.research.level >= config.inf_res[i].level) then
is_inf_res = true
end
end
if config.bonus_inventory.enabled then
if (event.research.force.mining_drill_productivity_bonus * 10) <= (config.bonus_inventory.limit / config.bonus_inventory.rate) then
if event.research.force.technologies['toolbelt'].researched then
event.research.force[config.bonus_inventory.name] = (math.floor(event.research.force.mining_drill_productivity_bonus * 10) * config.bonus_inventory.rate) + 10
else
event.research.force[config.bonus_inventory.name] = math.floor(event.research.force.mining_drill_productivity_bonus * 10) * config.bonus_inventory.rate
end
end
end
if is_inf_res then
if config.bonus.enabled then
if event.research.name == 'mining-productivity-4' and event.research.force.technologies['mining-productivity-4'].level > 4 then
event.research.force[config.bonus.name] = base_rate + event.research.force.technologies['mining-productivity-4'].level * config.bonus.rate
end
end
if not (event.by_script) then
game.print{'expcom-res.inf', format_time(game.tick, research_time_format), event.research.name, event.research.level}
end
else
if not (event.by_script) then
game.print{'expcom-res.msg', format_time(game.tick, research_time_format), event.research.name}
end
end
end
local function res_queue(force)
if force.rockets_launched == 0 or force.technologies['mining-productivity-4'].level <= 4 then
return
end
local res_q = force.research_queue
if #res_q < config.queue_amount then
for i=1, config.queue_amount - #res_q do
force.add_research(force.technologies['mining-productivity-4'])
end
end
end
Event.add(defines.events.on_research_finished, function(event)
research_notification(event)
if research.res_queue_enable then
res_queue(event.research.force)
end
end)
Commands.new_command('auto-research', 'Automatically queue up research')
:add_alias('ares')
:register(function(player)
research.res_queue_enable = not research.res_queue_enable
if research.res_queue_enable then
res_queue(player.force)
end
return Commands.success{'expcom-res.res', research.res_queue_enable}
end)

View File

@@ -10,9 +10,29 @@ local function teleport(player)
local surface = player.surface
local spawn = player.force.get_spawn_position(surface)
local position = surface.find_non_colliding_position('character', spawn, 32, 1)
if not position then return false end
if player.driving then player.driving = false end -- kicks a player out a vehicle if in one
player.teleport(position, surface)
-- return false if no new position
if not position then
return false
end
if player.vehicle then
-- Teleport the entity
local entity = player.vehicle
local goto_position = surface.find_non_colliding_position(entity.name, position, 32, 1)
-- Surface teleport can only be done for players and cars at the moment. (with surface as an peramitor it gives this error)
if entity.type == "car" then
entity.teleport(goto_position, surface)
elseif surface.index == entity.surface.index then
-- Try teleport the entity
if not entity.teleport(goto_position) then
player.driving = false
player.teleport(position, surface)
end
end
else
-- Teleport the player
player.teleport(position, surface)
end
return true
end

View File

@@ -0,0 +1,15 @@
--[[-- Commands Module - Set game speed
- Adds a command that allows changing game speed
@commands Set game speed
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
Commands.new_command('game-speed', 'Set game speed')
:add_param('amount', 'number-range', 0.2, 1)
:set_flag('admin_only')
:register(function(_, amount)
game.speed = math.round(amount, 3)
return Commands.success{'expcom-speed.result', string.format('%.3f', amount)}
end)

View File

@@ -9,9 +9,31 @@ require 'config.expcore.command_general_parse'
local function teleport(from_player, to_player)
local surface = to_player.surface
local position = surface.find_non_colliding_position('character', to_player.position, 32, 1)
if not position then return false end -- return false if no new position
if from_player.driving then from_player.driving = false end -- kicks a player out a vehicle if in one
from_player.teleport(position, surface)
-- return false if no new position
if not position then
return false
end
if from_player.vehicle then
-- Teleport the entity
local entity = from_player.vehicle
local goto_position = surface.find_non_colliding_position(entity.name, position, 32, 1)
-- Surface teleport can only be done for players and cars at the moment. (with surface as an peramitor it gives this error)
if entity.type == "car" then
entity.teleport(goto_position, surface)
elseif surface.index == entity.surface.index then
-- Try teleport the entity
if not entity.teleport(goto_position) then
from_player.driving = false
from_player.teleport(position, surface)
end
end
else
-- Teleport the player
from_player.teleport(position, surface)
end
return true
end
@@ -50,6 +72,7 @@ Commands.new_command('bring', 'Teleports a player to you.')
-- return if the teleport failed
return Commands.error{'expcom-tp.no-position-found'}
end
from_player.print('Come here my friend')
end)
--- Teleports you to a player.
@@ -58,7 +81,6 @@ end)
Commands.new_command('goto', 'Teleports you to a player.')
:add_param('player', false, 'player-online')
:add_alias('tp-me', 'tpme')
:set_flag('admin_only')
:register(function(player, to_player)
if to_player.index == player.index then
-- return if attempting to teleport to self
@@ -68,4 +90,4 @@ Commands.new_command('goto', 'Teleports you to a player.')
-- return if the teleport failed
return Commands.error{'expcom-tp.no-position-found'}
end
end)
end)

View File

@@ -0,0 +1,22 @@
--[[-- Commands Module - Set Automatic Train
- Adds a command that set all train back to automatic
@commands Set Automatic Train
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
local format_number = require('util').format_number
Commands.new_command('set-trains-to-automatic', 'Set All Trains to Automatic')
:register(function(player)
local count = 0
for _, v in pairs(player.force.get_trains()) do
if v.manual_mode then
count = count + 1
v.manual_mode = false
end
end
return Commands.success{'expcom-train.manual-result', format_number(count)}
end)

View File

@@ -0,0 +1,28 @@
--- Adds a virtual layer to store power to save space.
-- @addon Virtual Layer
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
local vlayer = require 'modules.control.vlayer'
Commands.new_command('personal-battery-recharge', 'Recharge Player Battery upto a portion with vlayer')
:add_param('amount', 'number-range', 0.2, 1)
:register(function(player, amount)
local armor = player.get_inventory(defines.inventory.character_armor)[1].grid
for i=1, #armor.equipment do
if armor.equipment[i].energy < (armor.equipment[i].max_energy * amount) then
local energy_required = (armor.equipment[i].max_energy * amount) - armor.equipment[i].energy
if vlayer.power.energy >= energy_required then
armor.equipment[i].energy = armor.equipment[i].max_energy * amount
vlayer.power.energy = vlayer.power.energy - energy_required
else
armor.equipment[i].energy = armor.equipment[i].energy + vlayer.power.energy
vlayer.power.energy = 0
end
end
end
return Commands.success
end)

View File

@@ -0,0 +1,64 @@
--- Adds a waterfill
-- @addon Virtual Waterfill
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 SelectionConvertArea = 'ConvertArea'
--- 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
Commands.new_command('waterfill', 'Change tile to water')
:register(function(player)
local inv = player.get_main_inventory()
if (inv.get_item_count('cliff-explosives')) == 0 then
return player.print{'expcom-waterfill.waterfill-cliff'}
end
if Selection.is_selecting(player, SelectionConvertArea) then
Selection.stop(player)
else
Selection.start(player, SelectionConvertArea)
return Commands.success{'expcom-waterfill.entered-area-selection'}
end
return Commands.success
end)
--- When an area is selected to add protection to the area
Selection.on_selection(SelectionConvertArea, function(event)
local area = aabb_align_expand(event.area)
local player = game.get_player(event.player_index)
local entities = player.surface.find_entities_filtered{area=area, name='steel-chest'}
local tiles_to_make = {}
local inv = player.get_main_inventory()
local clf_exp = inv.get_item_count('cliff-explosives')
for _, entity in pairs(entities) do
if clf_exp >= 1 then
if entity.get_inventory(defines.inventory.chest).is_empty() then
if (math.floor(player.position.x) ~= math.floor(entity.position.x)) or (math.floor(player.position.y) ~= math.floor(entity.position.y)) then
table.insert(tiles_to_make, {name='water-mud', position=entity.position})
entity.destroy()
else
player.print{'expcom-waterfill.waterfill-distance'}
end
end
clf_exp = clf_exp - 1
inv.remove({name='cliff-explosives', count=1})
else
break
end
end
event.surface.set_tiles(tiles_to_make)
end)

223
modules/control/vlayer.lua Normal file
View File

@@ -0,0 +1,223 @@
--- Adds a virtual layer to store power to save space.
-- @addon Virtual Layer
local Global = require 'utils.global' --- @dep utils.global
local Event = require 'utils.event' --- @dep utils.event
local config = require 'config.vlayer' --- @dep config.vlayer
local vlayer = {}
Global.register(vlayer, function(tbl)
vlayer = tbl
end)
vlayer.storage = {}
vlayer.storage.item = {}
vlayer.storage.input = {}
vlayer.storage.item_m = {}
vlayer.power = {}
vlayer.power.entity = {}
vlayer.power.energy = 0
vlayer.power.circuit = {}
vlayer.circuit = {}
vlayer.circuit.output = {}
for i=1, 11 do
vlayer.circuit.output[i] = {}
vlayer.circuit.output[i].count = 0
end
vlayer.circuit.output[1].signal = {type='virtual', name='signal-P'}
vlayer.circuit.output[2].signal = {type='virtual', name='signal-S'}
vlayer.circuit.output[3].signal = {type='virtual', name='signal-M'}
vlayer.circuit.output[4].signal = {type='virtual', name='signal-C'}
vlayer.circuit.output[5].signal = {type='virtual', name='signal-D'}
vlayer.circuit.output[6].signal = {type='virtual', name='signal-T'}
vlayer.circuit.output[7].signal = {type='virtual', name='signal-L'}
vlayer.circuit.output[8].signal = {type='virtual', name='signal-A'}
vlayer.circuit.output[9].signal = {type='virtual', name='signal-B'}
vlayer.circuit.output[10].signal = {type='item', name='solar-panel'}
vlayer.circuit.output[11].signal = {type='item', name='accumulator'}
vlayer.storage.item['solar-panel'] = 0
vlayer.storage.item['accumulator'] = 0
if config.land.enabled then
vlayer.storage.item[config.land.tile] = 0
vlayer.storage.item_a = {}
vlayer.storage.item_a['solar-panel'] = 0
vlayer.storage.item_a['accumulator'] = 0
end
local vlayer_storage_item = {}
for i=2, 8 do
vlayer_storage_item['solar-panel-' .. i] = {name='solar-panel', multiplier=4 ^ (i - 1)}
vlayer_storage_item['accumulator-' .. i] = {name='accumulator', multiplier=4 ^ (i - 1)}
end
--[[
25,000 / 416 s
昼 208秒 ソーラー効率100%
夕方 83秒 1秒ごとにソーラー発電量が約1.2%ずつ下がり、やがて0%になる
夜 41秒 ソーラー発電量が0%になる
朝方 83秒 1秒ごとにソーラー発電量が約1.2%ずつ上がり、やがて100%になる
0.75 Day 12,500 208s
0.25 Sunset 5,000 83s
0.45 Night 2,500 41s
0.55 Sunrise 5,000 83s
]]
Event.on_nth_tick(config.update_tick, function()
-- storage handle
for k, v in pairs(vlayer.storage.input) do
if ((v == nil) or (not v.valid)) then
vlayer.input[k] = nil
else
local chest = v.get_inventory(defines.inventory.chest)
local chest_content = chest.get_contents()
if config.land.enabled then
for item_name, count in pairs(chest_content) do
if (vlayer.storage.item[item_name] ~= nil) then
if item_name == config.land.tile then
vlayer.storage.item[item_name] = vlayer.storage.item[item_name] + count
else
vlayer.storage.item_a[item_name] = vlayer.storage.item_a[item_name] + count
end
chest.remove({name=item_name, count=count})
elseif (vlayer_storage_item[item_name] ~= nil) then
vlayer.storage.item_a[vlayer_storage_item[item_name].name] = vlayer.storage.item_a[vlayer_storage_item[item_name].name] + (count * vlayer_storage_item[item_name].multiplier)
chest.remove({name=item_name, count=count})
end
end
local land_req = (vlayer.storage.item['solar-panel'] * config.land.requirement['solar-panel']) + (vlayer.storage.item['accumulator'] * config.land.requirement['accumulator'])
local land_surplus = (vlayer.storage.item[config.land.tile] * config.land.result) - land_req
if (vlayer.storage.item_a['solar-panel'] > 0 and vlayer.storage.item_a['accumulator'] > 0) then
local land_allocation = math.floor(land_surplus / (config.land.requirement['solar-panel'] + config.land.requirement['accumulator']))
vlayer.storage.item['solar-panel'] = vlayer.storage.item['solar-panel'] + math.min(vlayer.storage.item_a['solar-panel'], land_allocation)
vlayer.storage.item_a['solar-panel'] = vlayer.storage.item_a['solar-panel'] - math.min(vlayer.storage.item_a['solar-panel'], land_allocation)
vlayer.storage.item['accumulator'] = vlayer.storage.item['accumulator'] + math.min(vlayer.storage.item_a['accumulator'], land_allocation)
vlayer.storage.item_a['accumulator'] = vlayer.storage.item_a['accumulator'] - math.min(vlayer.storage.item_a['accumulator'], land_allocation)
elseif (vlayer.storage.item_a['solar-panel'] > 0 and vlayer.storage.item_a['accumulator'] == 0) then
local land_allocation = math.floor(land_surplus / config.land.requirement['solar-panel'])
vlayer.storage.item['solar-panel'] = vlayer.storage.item['solar-panel'] + math.min(vlayer.storage.item_a['solar-panel'], land_allocation)
vlayer.storage.item_a['solar-panel'] = vlayer.storage.item_a['solar-panel'] - math.min(vlayer.storage.item_a['solar-panel'], land_allocation)
else
local land_allocation = math.floor(land_surplus / config.land.requirement['accumulator'])
vlayer.storage.item['accumulator'] = vlayer.storage.item['accumulator'] + math.min(vlayer.storage.item_a['accumulator'], land_allocation)
vlayer.storage.item_a['accumulator'] = vlayer.storage.item_a['accumulator'] - math.min(vlayer.storage.item_a['accumulator'], land_allocation)
end
vlayer.circuit.output[1].count = math.floor(vlayer.storage.item['solar-panel'] * 0.06 * game.surfaces['nauvis'].solar_power_multiplier)
vlayer.circuit.output[2].count = math.floor(vlayer.storage.item['solar-panel'] * 873 * game.surfaces['nauvis'].solar_power_multiplier / 20800)
vlayer.circuit.output[3].count = vlayer.storage.item['accumulator'] * 5
vlayer.circuit.output[7].count = (vlayer.storage.item[config.land.tile] * config.land.result) - (vlayer.storage.item['solar-panel'] * config.land.requirement['solar-panel']) - (vlayer.storage.item['accumulator'] * config.land.requirement['accumulator'])
vlayer.circuit.output[8].count = vlayer.storage.item_a['solar-panel']
vlayer.circuit.output[9].count = vlayer.storage.item_a['accumulator']
vlayer.circuit.output[10].count = vlayer.storage.item['solar-panel']
vlayer.circuit.output[11].count = vlayer.storage.item['accumulator']
else
for item_name, count in pairs(chest_content) do
if (vlayer.storage.item[item_name] ~= nil) then
vlayer.storage.item[item_name] = vlayer.storage.item[item_name] + count
chest.remove({name=item_name, count=count})
elseif (vlayer_storage_item[item_name] ~= nil) then
vlayer.storage.item[vlayer_storage_item[item_name].name] = vlayer.storage.item[vlayer_storage_item[item_name].name] + (count * vlayer_storage_item[item_name].multiplier)
chest.remove({name=item_name, count=count})
end
end
vlayer.circuit.output[1].count = math.floor(vlayer.storage.item['solar-panel'] * 0.06 * game.surfaces['nauvis'].solar_power_multiplier)
vlayer.circuit.output[2].count = math.floor(vlayer.storage.item['solar-panel'] * 873 * game.surfaces['nauvis'].solar_power_multiplier / 20800)
vlayer.circuit.output[3].count = (vlayer.storage.item['accumulator'] * 5) + (config.energy_base_limit / 1000000)
vlayer.circuit.output[10].count = vlayer.storage.item['solar-panel']
vlayer.circuit.output[11].count = vlayer.storage.item['accumulator']
end
end
end
-- power handle
local vlayer_power_capacity_total = math.floor(((vlayer.storage.item['accumulator'] * 5000000) + (config.energy_base_limit * #vlayer.power.entity)) / 2)
local vlayer_power_capacity = math.floor(vlayer_power_capacity_total / #vlayer.power.entity)
if config.always_day or game.surfaces['nauvis'].always_day then
vlayer.power.energy = vlayer.power.energy + math.floor(vlayer.storage.item['solar-panel'] * 60000 * game.surfaces['nauvis'].solar_power_multiplier / config.update_tick)
else
local tick = game.tick % 25000
if tick <= 5000 or tick > 17500 then
vlayer.power.energy = vlayer.power.energy + math.floor(vlayer.storage.item['solar-panel'] * 60000 * game.surfaces['nauvis'].solar_power_multiplier / config.update_tick)
elseif tick <= 10000 then
vlayer.power.energy = vlayer.power.energy + math.floor(vlayer.storage.item['solar-panel'] * 60000 * game.surfaces['nauvis'].solar_power_multiplier / config.update_tick * (1 - ((tick - 5000) / 5000)))
elseif (tick > 12500) and (tick <= 17500) then
vlayer.power.energy = vlayer.power.energy + math.floor(vlayer.storage.item['solar-panel'] * 60000 * game.surfaces['nauvis'].solar_power_multiplier / config.update_tick * ((tick - 5000) / 5000))
end
end
if config.battery_limit then
if vlayer.power.energy > vlayer_power_capacity_total then
vlayer.power.energy = vlayer_power_capacity_total
end
end
for k, v in pairs(vlayer.power.entity) do
if (v == nil) or (not v.valid)then
vlayer.power.entity[k] = nil
else
v.electric_buffer_size = vlayer_power_capacity
v.power_production = math.floor(vlayer_power_capacity / 60)
v.power_usage = math.floor(vlayer_power_capacity / 60)
if vlayer.power.energy < vlayer_power_capacity then
v.energy = math.floor((v.energy + vlayer.power.energy) / 2)
vlayer.power.energy = v.energy
elseif v.energy < vlayer_power_capacity then
local energy_change = vlayer_power_capacity - v.energy
if energy_change < vlayer.power.energy then
v.energy = v.energy + energy_change
vlayer.power.energy = vlayer.power.energy - energy_change
else
v.energy = v.energy + vlayer.power.energy
vlayer.power.energy = 0
end
end
end
end
-- circuit handle
vlayer.circuit.output[4].count = math.floor(vlayer.power.energy / 1000000)
vlayer.circuit.output[5].count = math.floor(game.tick / 25000)
vlayer.circuit.output[6].count = game.tick % 25000
for k, v in pairs(vlayer.power.circuit) do
if (v == nil) or (not v.valid) then
vlayer.power.circuit[k] = nil
else
local circuit_o = v.get_or_create_control_behavior()
for i=1, #vlayer.circuit.output do
circuit_o.set_signal(i, {signal=vlayer.circuit.output[i].signal, count=vlayer.circuit.output[i].count})
end
end
end
end)
return vlayer

View File

@@ -95,8 +95,9 @@ function Warps.make_warp_tag(warp_id)
-- Edit the existing tag if it is present
local tag = warp.tag
if tag and tag.valid then
tag.text = 'Warp: '..name
tag.text = 'Warp: ' .. name
tag.icon = icon
return false
end
@@ -108,7 +109,7 @@ function Warps.make_warp_tag(warp_id)
tag = force.add_chart_tag(surface, {
position = {position.x+0.5, position.y+0.5},
text = 'Warp: '..name,
text = 'Warp: ' .. name,
icon = icon
})
@@ -205,9 +206,11 @@ function Warps.remove_warp_area(warp_id)
-- Restore the original tiles before the creation of the warp
local tiles = {}
for _, tile in pairs(config.tiles) do
table.insert(tiles, {name=old_tile, position={tile[2]+position.x, tile[3]+position.y}})
end
surface.set_tiles(tiles)
local area = {
@@ -224,7 +227,6 @@ function Warps.remove_warp_area(warp_id)
entity.die(entity.force)
end
end
-- Rechart map area, useful if warp is not covered by a radar
game.forces[warp.force_name].chart(surface, area)
end
@@ -240,8 +242,9 @@ Warps.set_spawn_warp(warp_id, game.player.force)
function Warps.set_spawn_warp(warp_id, force)
-- Check the force owns this warp
local warp = WrapData:get(warp_id)
if warp.force_name ~= force.name then return end
if warp.force_name ~= force.name then
return
end
-- Set this warp as the spawn
local warp_ids = force_warps[warp.force_name]
if not warp_ids then
@@ -249,7 +252,6 @@ function Warps.set_spawn_warp(warp_id, force)
force_warps[warp.force_name] = warp_ids
end
warp_ids.spawn = warp_id
-- Set the forces spawn to this warp
force.set_spawn_position(warp.position, warp.surface)
end

View File

@@ -5,29 +5,39 @@
local Roles = require 'expcore.roles' --- @dep expcore.roles
local Event = require 'utils.event' --- @dep utils.event
local config = require 'config.bonuses' --- @dep config.bonuses
local config = require 'config.bonus' --- @dep config.bonuses
local Commands = require 'expcore.commands' --- @dep expcore.commands
require 'config.expcore.command_general_parse'
--- Stores the bonus for the player
-- Stores the bonus for the player
local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data
local PlayerBonus = PlayerData.Settings:combine('Bonus')
PlayerBonus:set_default(0)
PlayerBonus:set_metadata{
permission = 'command/bonus',
stringify = function(value)
if not value or value == 0 then return 'None set' end
return (value*100)..'%'
if not value or value == 0 then
return 'None set'
end
return value
end
}
--- Apply a bonus amount to a player
local function apply_bonus(player, amount)
if not amount then return end
if not player.character then return end
for bonus, min_max in pairs(config) do
local increase = min_max[2]*amount
player[bonus] = min_max[1]+increase
--- Apply a bonus to a player
local function apply_bonus(player, stage)
if not player.character then
return
end
for _, v in pairs(config.player_bonus) do
if v.enabled then
if stage == 0 then
player[v.name] = v.min
else
player[v.name] = v.min + (v.max - v.min) * stage / 10
end
end
end
end
@@ -38,14 +48,25 @@ end)
--- Changes the amount of bonus you receive
-- @command bonus
-- @tparam number amount range 0-50 the percent increase for your bonus
-- @tparam number amount range 0-10 the increase for your bonus
Commands.new_command('bonus', 'Changes the amount of bonus you receive')
:add_param('amount', 'integer-range', 0,50)
:add_param('amount', 'integer-range', 0, 10)
:register(function(player, amount)
local percent = amount/100
PlayerBonus:set(player, percent)
if amount > config.player_bonus_level then
if not Roles.player_allowed(player, 'command/bonus/2') then
Commands.print{'expcom-bonus.perm', 2}
return
end
elseif amount <= config.player_bonus_level then
if not Roles.player_allowed(player, 'command/bonus') then
Commands.print{'expcom-bonus.perm', 1}
return
end
end
PlayerBonus:set(player, amount)
Commands.print{'expcom-bonus.set', amount}
Commands.print({'expcom-bonus.wip'}, 'orange')
end)
--- When a player respawns re-apply bonus
@@ -54,21 +75,40 @@ Event.add(defines.events.on_player_respawned, function(event)
apply_bonus(player, PlayerBonus:get(player))
end)
--- When a player dies allow them to have instant respawn
Event.add(defines.events.on_player_died, function(event)
local player = game.players[event.player_index]
if Roles.player_has_flag(player, 'instance-respawn') then
player.ticks_to_respawn = 120
end
end)
--- Remove bonus if a player no longer has access to the command
local function role_update(event)
local player = game.players[event.player_index]
if not Roles.player_allowed(player, 'command/bonus') then
PlayerBonus:remove(player)
apply_bonus(player, 0)
end
end
--- When a player dies allow them to have instant respawn
Event.add(defines.events.on_player_died, function(event)
local player = game.players[event.player_index]
if Roles.player_has_flag(player, 'instant-respawn') then
player.ticks_to_respawn = 120
end
end)
Event.add(defines.events.on_player_created, function(event)
if event.player_index ~= 1 then
return
end
for _, v in pairs(config.force_bonus) do
if v.enabled then
game.players[event.player_index].force[v.name] = game.players[event.player_index].force[v.name] + v.max
end
end
for _, v in pairs(config.surface_bonus) do
if v.enabled then
game.players[event.player_index].surface[v.name] = game.players[event.player_index].surface[v.name] + v.max
end
end
end)
Event.add(Roles.events.on_role_assigned, role_update)
Event.add(Roles.events.on_role_unassigned, role_update)
Event.add(Roles.events.on_role_unassigned, role_update)

View File

@@ -0,0 +1,76 @@
local Commands = require 'expcore.commands' --- @dep expcore.commands
local config = require 'config.personal_logistic' --- @dep config.personal-logistic
--[[
Command 2:
add filter based of inventory
Command 3:
add filter of those not in inventory: all 0
game.item_prototypes
Command 4:
Spidertron request
]]
local function pl(player, amount)
local c = player.clear_personal_logistic_slot
for k, v in pairs(config.request) do
c(config.start + v.key)
end
if (amount == 0) then
return
else
local stats = player.force.item_production_statistics
local s = player.set_personal_logistic_slot
for k, v in pairs(config.request) do
local v_min = math.ceil(v.min * amount)
local v_max = math.ceil(v.max * amount)
if v.stack ~= nil and v.stack ~= 1 and v.type ~= 'weapon' then
v_min = math.floor(v_min / v.stack) * v.stack
v_max = math.ceil(v_max / v.stack) * v.stack
end
if v.upgrade_of == nil then
if v.type ~= nil then
if stats.get_input_count(k) < config.production_required[v.type] then
v_min = 0
end
end
s(config.start + v.key, {name=k, min=v_min, max=v_max})
else
if v.type ~= nil then
if stats.get_input_count(k) >= config.production_required[v.type] then
s(config.start + v.key, {name=k, min=v_min, max=v_max})
local vuo = v.upgrade_of
while (vuo ~= nil) do
s(config.start + config.request[vuo].key, {name=vuo, min=0, max=0})
vuo = config.request[vuo].upgrade_of
end
else
s(config.start + v.key, {name=k, min=0, max=v_max})
end
end
end
end
end
end
Commands.new_command('personal-logistic', 'Set Personal Logistic (0 to cancel all)')
:add_param('amount', 'integer-range', 0, 10)
:add_alias('pl')
:register(function(player, amount)
if player.force.technologies['logistic-robotics'].researched then
pl(player, amount / 10)
return Commands.success
else
player.print('Player logistic not researched')
end
end)

View File

@@ -175,4 +175,4 @@ for statistic, event_name in pairs(config.counters) do
if not player.valid or not player.connected then return end
stat:increment(player)
end)
end
end

View File

@@ -32,6 +32,14 @@ function Public.open_dubug(player)
return
end
--[[
local screen_element = player.gui.screen
frame = screen_element.add{type = 'frame', name = main_frame_name, caption = 'Debuggertron 3000'}
frame.style.size = {900, 600}
frame.auto_center = true
]]
frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3002', direction = 'vertical'}
local frame_style = frame.style
frame_style.height = 600

View File

@@ -75,7 +75,7 @@ Gui.element{
local reason = element.parent.entry.text
local action_name = SelectedAction:get(player)
local reason_callback = config.buttons[action_name].reason_callback
if reason == nil or not reason:find("/S") then reason = 'no reason given' end
if reason == nil or not reason:find("%S") then reason = 'no reason given' end
reason_callback(player, reason)
SelectedPlayer:remove(player)
SelectedAction:remove(player)

207
modules/gui/research.lua Normal file
View File

@@ -0,0 +1,207 @@
--- research milestone gui
-- @addon research milestone
local Gui = require 'expcore.gui' --- @dep expcore.gui
local Global = require 'utils.global' --- @dep utils.global
local Event = require 'utils.event' --- @dep utils.event
local Roles = require 'expcore.roles' --- @dep expcore.roles
local config = require 'config.research' --- @dep config.clock
local format_time = _C.format_time --- @dep expcore.common
local research = {}
Global.register(research, function(tbl)
research = tbl
end)
research.time = {}
local res = {}
local res_i = {}
local res_total = 0
local research_time_format = {hours=true, minutes=true, seconds=true, time=true, string=true}
local empty_time = format_time(0, {hours=true, minutes=true, seconds=true, time=true, string=true, null=true})
local function research_res_n(res_)
local res_n = 1
for k, _ in pairs(res_) do
if research.time[k] == 0 then
res_n = k - 1
break
end
end
if research.time[#res_] > 0 then
if res_n == 1 then
res_n = #res_
end
end
if res_n < 3 then
res_n = 3
end
return res_n
end
for i=1, #config.milestone do
res_total = res_total + config.milestone[i].time * 60
res_i[config.milestone[i].name] = i
research.time[i] = 0
res[i] = {
name = '[technology=' .. config.milestone[i].name .. '] ' .. config.milestone[i].name:gsub('-', ' '),
prev = res_total,
prev_disp = format_time(res_total, research_time_format),
}
end
local clock_container =
Gui.element(function(event_trigger, parent)
local container = Gui.container(parent, event_trigger, 200)
local scroll_table = Gui.scroll_table(container, 400, 4)
scroll_table.add{
name = 'clock_text',
caption = 'Time:',
type = 'label',
style = 'heading_1_label'
}
scroll_table.add{
name = 'clock_text_2',
caption = '',
type = 'label',
style = 'heading_1_label'
}
scroll_table.add{
name = 'clock_text_3',
caption = '',
type = 'label',
style = 'heading_1_label'
}
scroll_table.add{
name = 'clock_display',
caption = empty_time,
type = 'label',
style = 'heading_1_label'
}
for i=1, 8 do
scroll_table.add{
name = 'research_display_n_' .. i,
caption = '',
type = 'label',
style = 'heading_1_label'
}
scroll_table.add{
name = 'research_display_d_' .. i,
caption = empty_time,
type = 'label',
style = 'heading_1_label'
}
scroll_table.add{
name = 'research_display_p_' .. i,
caption = '',
type = 'label',
style = 'heading_1_label'
}
scroll_table.add{
name = 'research_display_t_' .. i,
caption = empty_time,
type = 'label',
style = 'heading_1_label'
}
end
local res_n = research_res_n(res)
for j=1, 8 do
local res_j = res_n + j - 3
if res[res_j] ~= nil then
local res_r = res[res_j]
scroll_table['research_display_n_' .. j].caption = res_r.name
if research.time[res_j] < res[res_j].prev then
scroll_table['research_display_d_' .. j].caption = '-' .. format_time(res[res_j].prev - research.time[res_j], research_time_format)
else
scroll_table['research_display_d_' .. j].caption = format_time(research.time[res_j] - res[res_j].prev, research_time_format)
end
scroll_table['research_display_p_' .. j].caption = res_r.prev_disp
scroll_table['research_display_t_' .. j].caption = format_time(research.time[res_j], research_time_format)
else
scroll_table['research_display_n_' .. j].caption = ''
scroll_table['research_display_d_' .. j].caption = ''
scroll_table['research_display_p_' .. j].caption = ''
scroll_table['research_display_t_' .. j].caption = ''
end
end
return container.parent
end)
:add_to_left_flow()
Gui.left_toolbar_button('item/space-science-pack', {'expcom-res.main-tooltip'}, clock_container, function(player)
return Roles.player_allowed(player, 'gui/research')
end)
Event.add(defines.events.on_research_finished, function(event)
if event.research.name == nil then
return
elseif res_i[event.research.name] == nil then
return
end
local n_i = res_i[event.research.name]
research.time[n_i] = game.tick
local res_n = research_res_n(res)
local res_disp = {}
for j=1, 8 do
local res_j = res_n + j - 3
res_disp[j] = {}
if res[res_j] ~= nil then
local res_r = res[res_j]
res_disp[j]['n'] = res_r.name
if research.time[res_j] < res[res_j].prev then
res_disp[j]['d'] = '-' .. format_time(res[res_j].prev - research.time[res_j], research_time_format)
else
res_disp[j]['d'] = format_time(research.time[res_j] - res[res_j].prev, research_time_format)
end
res_disp[j]['p'] = res_r.prev_disp
res_disp[j]['t'] = format_time(research.time[res_j], research_time_format)
else
res_disp[j]['n'] = ''
res_disp[j]['d'] = ''
res_disp[j]['p'] = ''
res_disp[j]['t'] = ''
end
end
for _, player in pairs(game.connected_players) do
local frame = Gui.get_left_element(player, clock_container)
for j=1, 8 do
frame.container.scroll.table['research_display_n_' .. j].caption = res_disp[j]['n']
frame.container.scroll.table['research_display_d_' .. j].caption = res_disp[j]['d']
frame.container.scroll.table['research_display_p_' .. j].caption = res_disp[j]['p']
frame.container.scroll.table['research_display_t_' .. j].caption = res_disp[j]['t']
end
end
end)
Event.on_nth_tick(60, function()
local current_time = format_time(game.tick, research_time_format)
for _, player in pairs(game.connected_players) do
local frame = Gui.get_left_element(player, clock_container)
frame.container.scroll.table['clock_display'].caption = current_time
end
end)

View File

@@ -58,7 +58,9 @@ local function set_location(event)
local label = player.gui.screen[server_ups.name]
local res = player.display_resolution
local uis = player.display_scale
label.location = { x=res.width-423*uis, y=30*uis }
-- below ups and clock
-- label.location = {x=res.width-423*uis, y=50*uis}
label.location = {x=res.width-363*uis, y=31*uis}
end
-- Draw the label when the player joins
@@ -70,9 +72,10 @@ Event.add(defines.events.on_player_created, function(event)
end)
-- Update the caption for all online players
-- percentage of game speed
Event.on_nth_tick(60, function()
if External.valid() then
local caption = 'SUPS = '..External.get_server_ups()
local caption = External.get_server_ups() .. ' (' .. string.format('%.1f', External.get_server_ups() * 5 / 3) .. '%)'
for _, player in pairs(game.connected_players) do
player.gui.screen[server_ups.name].caption = caption
end

276
modules/gui/vlayer.lua Normal file
View File

@@ -0,0 +1,276 @@
--- Adds a virtual layer to store power to save space.
-- @addon Virtual Layer
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 config = require 'config.vlayer' --- @dep config.vlayer
local format_number = require('util').format_number
local vlayer = require 'modules.control.vlayer'
local vlayer_container
local vlayer_display = {}
local function pos_to_gps_string(pos)
return '[gps=' .. tostring(pos.x) .. ',' .. tostring(pos.y) .. ']'
end
for i=1, #config.gui.content do
if config.gui.content[i].type == 'item' or config.gui.content[i].type == 'signal' then
vlayer_display[i] = {
type = config.gui.content[i].type,
name = config.gui.content[i].name,
count = 0
}
end
end
local function vlayer_convert_chest(player)
local entities = player.surface.find_entities_filtered{position=player.position, radius=8, name='steel-chest', force=player.force}
if (not entities or (#entities == 0)) then
return nil
end
local target_chest = player.surface.get_closest(player.position, entities)
if (not target_chest) then
player.print('No Steel Chest Detected')
return nil
end
if (not target_chest.get_inventory(defines.inventory.chest).is_empty()) then
player.print('Chest is not emptied')
return nil
end
local pos = target_chest.position
if (not target_chest.destroy()) then
player.print('Unable to convert chest')
return nil
end
return {x=math.floor(pos.x), y=math.floor(pos.y)}
end
local function vlayer_convert_chest_storage_input(player)
local pos = vlayer_convert_chest(player)
if (pos) then
local vlayer_storage = player.surface.create_entity{name='logistic-chest-storage', position=pos, force='neutral'}
game.print(player.name .. ' built a vlayer input on ' .. pos_to_gps_string(pos))
vlayer_storage.destructible = false
vlayer_storage.minable = false
vlayer_storage.operable = true
vlayer_storage.last_user = player
table.insert(vlayer.storage.input, vlayer_storage)
end
end
local function vlayer_convert_chest_power(player)
local pos = vlayer_convert_chest(player)
if (pos) then
if (player.surface.can_place_entity{name='electric-energy-interface', position=pos})then
local vlayer_power = player.surface.create_entity{name='electric-energy-interface', position=pos, force='neutral'}
game.print(player.name .. ' built a vlayer energy interface on ' .. pos_to_gps_string(pos))
vlayer_power.destructible = false
vlayer_power.minable = false
vlayer_power.operable = false
vlayer_power.last_user = player
vlayer_power.electric_buffer_size = math.floor(config.energy_base_limit / 2)
vlayer_power.power_production = math.floor(config.energy_base_limit / 60)
vlayer_power.power_usage = math.floor(config.energy_base_limit / 60)
vlayer_power.energy = 0
table.insert(vlayer.power.entity, vlayer_power)
else
player.print('Unable to build energy entity')
end
end
end
local function vlayer_convert_chest_circuit(player)
local pos = vlayer_convert_chest(player)
if (pos) then
local circuit_o = player.surface.create_entity{name='constant-combinator', position=pos, force='neutral'}
circuit_o.destructible = false
circuit_o.minable = false
circuit_o.operable = true
circuit_o.last_user = player
local circuit_oc = circuit_o.get_or_create_control_behavior()
circuit_oc.set_signal(1, {signal={type='virtual', name='signal-P'}, count=0})
circuit_oc.set_signal(2, {signal={type='virtual', name='signal-S'}, count=0})
circuit_oc.set_signal(3, {signal={type='virtual', name='signal-M'}, count=0})
circuit_oc.set_signal(4, {signal={type='virtual', name='signal-C'}, count=0})
circuit_oc.set_signal(5, {signal={type='virtual', name='signal-D'}, count=0})
circuit_oc.set_signal(6, {signal={type='virtual', name='signal-T'}, count=0})
circuit_oc.set_signal(7, {signal={type='virtual', name='signal-L'}, count=0})
circuit_oc.set_signal(8, {signal={type='virtual', name='signal-A'}, count=0})
circuit_oc.set_signal(9, {signal={type='virtual', name='signal-B'}, count=0})
circuit_oc.set_signal(10, {signal={type='item', name='solar-panel'}, count=0})
circuit_oc.set_signal(11, {signal={type='item', name='accumulator'}, count=0})
table.insert(vlayer.power.circuit, circuit_o)
game.print(player.name .. ' built a vlayer circuit on ' .. pos_to_gps_string(pos))
end
end
local function vlayer_convert_remove(player)
local entities = player.surface.find_entities_filtered{name={'logistic-chest-storage', 'constant-combinator', 'electric-energy-interface'}, position=player.position, radius=8, force='neutral', limit=1}
if (not entities or #entities == 0) then
player.print('Entity not found')
else
for _, v in pairs(entities) do
local name = v.name
game.print(player.name .. ' removed a vlayer ' .. config.print_out[v.name] .. ' on ' .. pos_to_gps_string(v.position))
v.destroy()
if name == 'logistic-chest-storage' then
for k, vl in pairs(vlayer.storage.input) do
if not vl.valid then
vlayer.storage.input[k] = nil
end
end
elseif name == 'constant-combinator' then
for k, vl in pairs(vlayer.power.circuit) do
if not vl.valid then
vlayer.power.circuit[k] = nil
end
end
elseif name == 'electric-energy-interface' then
for k, vl in pairs(vlayer.power.entity) do
if not vl.valid then
vlayer.power.entity[k] = nil
end
end
end
end
end
end
local vlayer_gui_update
local button_power =
Gui.element{
name = 'button_1',
type = 'button',
caption = 'Power Entity',
style = 'button'
}:on_click(function(player)
vlayer_convert_chest_power(player)
vlayer_gui_update()
end)
local button_storage_input =
Gui.element{
name = 'button_2',
type = 'button',
caption = 'Storage Input',
style = 'button'
}:on_click(function(player)
vlayer_convert_chest_storage_input(player)
vlayer_gui_update()
end)
local button_circuit =
Gui.element{
name = 'button_3',
type = 'button',
caption = 'Circuit',
style = 'button'
}:on_click(function(player)
vlayer_convert_chest_circuit(player)
vlayer_gui_update()
end)
local button_remove =
Gui.element{
name = 'button_4',
type = 'button',
caption = 'Remove',
style = 'button'
}:on_click(function(player)
vlayer_convert_remove(player)
vlayer_gui_update()
end)
function vlayer_gui_update()
local button_power_enabled = #vlayer.power.entity < config.interface_limit.energy
local button_storage_input_enabled = #vlayer.storage.input < config.interface_limit.storage_input
local button_circuit_enabled = #vlayer.power.circuit < config.interface_limit.circuit
for _, player in pairs(game.connected_players) do
local frame = Gui.get_left_element(player, vlayer_container)
frame.container.scroll.table[button_power.name].enabled = button_power_enabled
frame.container.scroll.table[button_storage_input.name].enabled = button_storage_input_enabled
frame.container.scroll.table[button_circuit.name].enabled = button_circuit_enabled
end
end
vlayer_container =
Gui.element(function(event_trigger, parent)
local player = Gui.get_player_from_element(parent)
local container = Gui.container(parent, event_trigger, 300)
Gui.header(container, 'VLAYER', '', true)
local scroll_table = Gui.scroll_table(container, 300, 2)
for i=1, #config.gui.content do
scroll_table.add{
name = 'vlayer_display_' .. i,
caption = config.gui.content[i].title,
type = config.gui.type,
style = config.gui.style
}
end
button_power(scroll_table)
button_storage_input(scroll_table)
button_circuit(scroll_table)
button_remove(scroll_table)
if (config.land.enabled ~= true) then
for i=7, 12 do
scroll_table['vlayer_display_' .. i].visible = false
end
end
if not (Roles.player_allowed(player, 'gui/vlayer-edit')) then
scroll_table['vlayer_display_' .. #config.gui.content - 1].visible = false
scroll_table['vlayer_display_' .. #config.gui.content].visible = false
scroll_table[button_power.name].visible = false
scroll_table[button_storage_input.name].visible = false
scroll_table[button_circuit.name].visible = false
scroll_table[button_remove.name].visible = false
end
scroll_table[button_power.name].enabled = (#vlayer.power.entity < config.interface_limit.energy)
scroll_table[button_storage_input.name].enabled = (#vlayer.storage.input < config.interface_limit.storage_input)
scroll_table[button_circuit.name].enabled = (#vlayer.power.circuit < config.interface_limit.circuit)
return container.parent
end)
:add_to_left_flow()
Gui.left_toolbar_button('entity/solar-panel', {'vlayer.main-tooltip'}, vlayer_container, function(player)
return Roles.player_allowed(player, 'gui/vlayer')
end)
Event.on_nth_tick(config.update_tick, function()
for _, v in pairs(vlayer_display) do
if v.type == 'item' then
v.count = format_number(vlayer.storage.item[v.name])
elseif v.type == 'signal' then
v.count = format_number(vlayer.circuit.output[v.name].count)
end
end
for _, player in pairs(game.connected_players) do
local frame = Gui.get_left_element(player, vlayer_container)
for k, v in pairs(vlayer_display) do
frame.container.scroll.table['vlayer_display_' .. k].caption = v.count
end
end
end)

View File

@@ -111,7 +111,7 @@ Gui.element{
-- Check if there are player entities in the way (has a bigger radius because the enities that can be placed by a player are larger)
local entities = surface.find_entities_filtered{
radius = config.standard_proximity_radius + 4.5,
radius = config.standard_proximity_radius + 2.5,
position = position,
collision_mask = {
'item-layer', 'object-layer', 'player-layer', 'water-tile'
@@ -119,7 +119,7 @@ Gui.element{
}
-- Remove 1 because that is the current player
if #entities > 1 then
player_return({'expcore-commands.command-fail', {'warp-list.too-close-to-entities', config.standard_proximity_radius + 4.5}}, 'orange_red', player)
player_return({'expcore-commands.command-fail', {'warp-list.too-close-to-entities', config.standard_proximity_radius + 2.5}}, 'orange_red', player)
if game.player then game.player.play_sound{path='utility/wire_pickup'} end
local character = player.character
for _, entity in pairs(entities) do
@@ -832,7 +832,7 @@ Event.add(defines.events.on_player_created, function(event)
Warps.set_spawn_warp(spawn_id, force)
Warps.make_warp_tag(spawn_id)
local entities = player.surface.find_entities_filtered{ type = 'electric-pole', position = spawn_position, radius = 20, limit = 1 }
local entities = player.surface.find_entities_filtered{type='electric-pole', position=spawn_position, radius=20, limit=1}
if entities and entities[1] then
local warp = Warps.get_warp(spawn_id)
warp.electric_pole = entities[1]