2018-11-20 12:46:19 +02:00
|
|
|
local Event = require 'utils.event'
|
2018-11-26 03:07:03 +02:00
|
|
|
local Utils = require 'utils.core'
|
2018-09-23 00:25:13 +02:00
|
|
|
local Game = require 'utils.game'
|
2019-01-16 20:44:55 +02:00
|
|
|
local RS = require 'map_gen.shared.redmew_surface'
|
2018-06-03 15:47:12 +02:00
|
|
|
|
2018-06-05 18:00:25 +02:00
|
|
|
global.original_last_users_by_ent_pos = {}
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Event.on_init(
|
|
|
|
function()
|
|
|
|
global.ag_surface = game.create_surface('antigrief', {autoplace_controls = {coal = {frequency = 'normal', richness = 'normal', size = 'none'}, ['copper-ore'] = {frequency = 'normal', richness = 'normal', size = 'none'}, ['crude-oil'] = {frequency = 'normal', richness = 'normal', size = 'none'}, desert = {frequency = 'normal', richness = 'normal', size = 'none'}, dirt = {frequency = 'normal', richness = 'normal', size = 'none'}, ['enemy-base'] = {frequency = 'normal', richness = 'normal', size = 'none'}, grass = {frequency = 'normal', richness = 'normal', size = 'none'}, ['iron-ore'] = {frequency = 'normal', richness = 'normal', size = 'none'}, sand = {frequency = 'normal', richness = 'normal', size = 'none'}, stone = {frequency = 'normal', richness = 'normal', size = 'none'}, trees = {frequency = 'normal', richness = 'normal', size = 'none'}, ['uranium-ore'] = {frequency = 'normal', richness = 'normal', size = 'none'}}, cliff_settings = {cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff'}, height = 2000000, peaceful_mode = false, seed = 3461559752, starting_area = 'very-low', starting_points = {{x = 0, y = 0}}, terrain_segmentation = 'normal', water = 'normal', width = 2000000})
|
|
|
|
global.ag_surface.always_day = true
|
|
|
|
end
|
|
|
|
)
|
2018-06-03 15:47:12 +02:00
|
|
|
|
2018-06-05 18:00:25 +02:00
|
|
|
local function is_mocked(entity)
|
2018-11-20 12:46:19 +02:00
|
|
|
return rawget(entity, 'mock')
|
2018-06-05 18:00:25 +02:00
|
|
|
end
|
|
|
|
|
2018-06-03 15:47:12 +02:00
|
|
|
local function place_entity_on_surface(entity, surface, replace, player)
|
2018-11-20 12:46:19 +02:00
|
|
|
local new_entity = nil
|
|
|
|
for _, e in ipairs(surface.find_entities_filtered {position = entity.position}) do
|
|
|
|
if replace or e.type == 'entity-ghost' then
|
|
|
|
e.destroy()
|
|
|
|
end
|
2018-06-03 15:47:12 +02:00
|
|
|
end
|
2018-11-20 12:46:19 +02:00
|
|
|
local entities_to_be_replaced = surface.find_entities_filtered {position = entity.position}
|
|
|
|
if (replace or #entities_to_be_replaced == 0 or entities_to_be_replaced[1].type == entity.type) then
|
|
|
|
new_entity = surface.create_entity {name = entity.name, position = entity.position, force = entity.force, direction = entity.direction}
|
|
|
|
if new_entity then
|
|
|
|
if not is_mocked(entity) then
|
|
|
|
new_entity.copy_settings(entity)
|
|
|
|
end
|
|
|
|
if player then
|
|
|
|
new_entity.last_user = player
|
|
|
|
end
|
|
|
|
end
|
2018-06-04 22:24:18 +02:00
|
|
|
end
|
2018-11-20 12:46:19 +02:00
|
|
|
return new_entity
|
2018-06-03 15:47:12 +02:00
|
|
|
end
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Event.add(
|
|
|
|
defines.events.on_chunk_generated,
|
|
|
|
function(event)
|
|
|
|
if event.surface.name == 'antigrief' then
|
|
|
|
local tiles = {}
|
|
|
|
for x = event.area.left_top.x, event.area.right_bottom.x - 1 do
|
|
|
|
for y = event.area.left_top.y, event.area.right_bottom.y - 1 do
|
|
|
|
table.insert(tiles, {name = 'lab-dark-2', position = {x, y}})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
event.surface.set_tiles(tiles)
|
|
|
|
end
|
2018-06-03 15:47:12 +02:00
|
|
|
end
|
2018-11-20 12:46:19 +02:00
|
|
|
)
|
2018-06-03 15:47:12 +02:00
|
|
|
|
2018-06-05 18:00:25 +02:00
|
|
|
local function get_position_str(pos)
|
2018-11-20 12:46:19 +02:00
|
|
|
return string.format('%d|%d', pos.x, pos.y)
|
2018-06-05 18:00:25 +02:00
|
|
|
end
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
local function on_entity_changed(event)
|
|
|
|
local entity = event.entity or event.destination
|
|
|
|
local player = Game.get_player_by_index(event.player_index)
|
|
|
|
if player.admin or not entity.valid then
|
|
|
|
return
|
|
|
|
end --Freebees for admins
|
|
|
|
if entity.last_user ~= player and entity.force == player.force then --commented out to be able to debug
|
|
|
|
place_entity_on_surface(entity, global.ag_surface, true, event.player_index)
|
|
|
|
end
|
|
|
|
if entity.last_user then
|
|
|
|
global.original_last_users_by_ent_pos[get_position_str(entity.position)] = entity.last_user.index
|
|
|
|
end
|
2018-06-05 18:00:25 +02:00
|
|
|
end
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Event.add(
|
|
|
|
defines.events.on_robot_pre_mined,
|
|
|
|
function(event)
|
|
|
|
--The bot isnt the culprit! The last user is! They marked it for deconstruction!
|
|
|
|
if event.entity.valid and event.entity.last_user then
|
|
|
|
event.player_index = event.entity.last_user.index
|
|
|
|
on_entity_changed(event)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
2018-06-05 19:02:01 +02:00
|
|
|
|
2018-06-05 18:00:25 +02:00
|
|
|
local function get_pre_rotate_direction(entity)
|
2018-11-20 12:46:19 +02:00
|
|
|
--Some entities have 8 rotation steps and some have 4. So a mathmatical reverse is not possible
|
|
|
|
entity.rotate {reverse = true}
|
|
|
|
local direction = entity.direction
|
|
|
|
entity.rotate()
|
|
|
|
return direction
|
2018-06-05 18:00:25 +02:00
|
|
|
end
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Event.add(
|
|
|
|
defines.events.on_player_rotated_entity,
|
|
|
|
function(event)
|
|
|
|
local entity = event.entity
|
2018-06-06 15:32:20 +02:00
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
if not entity.valid then
|
|
|
|
return
|
|
|
|
end
|
2018-06-05 19:18:50 +02:00
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
local ag_entities = global.ag_surface.find_entities_filtered {position = entity.position}
|
|
|
|
--If a player has rotated twice we want to preserve the original state.
|
|
|
|
if #ag_entities == 0 or not ag_entities[1].last_user or ag_entities[1].last_user ~= entity.last_user then
|
|
|
|
--Mock entity us used because the api doesnt support pre_player_rotated entity.
|
|
|
|
--The mocked entity has the entity state before rotation
|
|
|
|
--We also dont know who rotated it and dont want the griefers name there so we set it to 1
|
|
|
|
local mock_entity = {
|
|
|
|
name = entity.name,
|
|
|
|
position = entity.position,
|
|
|
|
mock = true,
|
|
|
|
last_user = Game.get_player_by_index(1),
|
|
|
|
force = entity.force,
|
|
|
|
direction = get_pre_rotate_direction(entity)
|
|
|
|
}
|
|
|
|
event.entity = mock_entity
|
|
|
|
on_entity_changed(event)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
2018-06-05 18:00:25 +02:00
|
|
|
Event.add(defines.events.on_pre_entity_settings_pasted, on_entity_changed)
|
2018-06-03 15:47:12 +02:00
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Event.add(
|
|
|
|
defines.events.on_entity_died,
|
|
|
|
function(event)
|
|
|
|
--is a player on the same force as the destroyed object
|
|
|
|
if event.entity and event.entity.valid and event.entity.force.name == 'player' and event.cause and event.cause.force == event.entity.force and event.cause.type == 'player' then
|
|
|
|
local new_entity = place_entity_on_surface(event.entity, global.ag_surface, true, event.cause.player)
|
|
|
|
if new_entity and event.entity.type == 'container' then
|
|
|
|
local items = event.entity.get_inventory(defines.inventory.chest).get_contents()
|
|
|
|
if items then
|
|
|
|
for item, n in pairs(items) do
|
|
|
|
new_entity.insert {name = item, count = n}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-06-04 22:24:18 +02:00
|
|
|
end
|
2018-06-06 15:32:20 +02:00
|
|
|
end
|
2018-11-20 12:46:19 +02:00
|
|
|
)
|
2018-06-05 18:00:25 +02:00
|
|
|
|
|
|
|
Event.add(defines.events.on_player_mined_entity, on_entity_changed)
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Event.add(
|
|
|
|
defines.events.on_marked_for_deconstruction,
|
|
|
|
function(event)
|
|
|
|
if event.entity.last_user then
|
|
|
|
global.original_last_users_by_ent_pos[get_position_str(event.entity.position)] = event.entity.last_user.index
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
2018-06-05 18:00:25 +02:00
|
|
|
|
2018-06-03 15:47:12 +02:00
|
|
|
local Module = {}
|
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
Module.undo =
|
|
|
|
function(player)
|
|
|
|
if type(player) == 'nil' or type(player) == 'string' then
|
|
|
|
return --No support for strings!
|
|
|
|
elseif type(player) == 'number' then
|
|
|
|
player = Game.get_player_by_index(player)
|
|
|
|
end
|
2018-06-05 01:34:58 +02:00
|
|
|
|
2018-11-20 12:46:19 +02:00
|
|
|
--Remove all items from all surfaces that player placed an entity on
|
|
|
|
for _, surface in pairs(game.surfaces) do
|
|
|
|
if surface ~= global.ag_surface then
|
|
|
|
for _, e in ipairs(surface.find_entities_filtered {force = player.force.name}) do
|
|
|
|
if e.last_user == player then
|
|
|
|
e.destroy()
|
|
|
|
end
|
|
|
|
end
|
2018-06-05 01:34:58 +02:00
|
|
|
end
|
|
|
|
end
|
2018-11-20 12:46:19 +02:00
|
|
|
|
|
|
|
for _, e in ipairs(global.ag_surface.find_entities_filtered {}) do
|
|
|
|
if e.last_user == player then
|
|
|
|
--Place removed entity IF no collision is detected
|
|
|
|
local last_user = global.original_last_users_by_ent_pos[get_position_str(e.position)]
|
2019-01-16 20:44:55 +02:00
|
|
|
local new_entity = place_entity_on_surface(e, RS.get_surface(), false, last_user)
|
2018-11-20 12:46:19 +02:00
|
|
|
--Transfer items
|
|
|
|
if new_entity then
|
2019-01-19 18:34:29 +02:00
|
|
|
local event_player = Utils.ternary(new_entity.last_user, new_entity.last_user, game.player)
|
|
|
|
local event = {created_entity = new_entity, player_index = event_player.index, stack = {}}
|
2018-11-20 12:46:19 +02:00
|
|
|
script.raise_event(defines.events.on_built_entity, event)
|
|
|
|
|
|
|
|
if e.type == 'container' then
|
|
|
|
local items = e.get_inventory(defines.inventory.chest).get_contents()
|
|
|
|
if items then
|
|
|
|
for item, n in pairs(items) do
|
|
|
|
new_entity.insert {name = item, count = n}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
e.destroy() --destory entity only if a new entity was created
|
2018-06-05 19:02:01 +02:00
|
|
|
end
|
2018-06-04 23:26:52 +02:00
|
|
|
end
|
2018-06-03 15:47:12 +02:00
|
|
|
end
|
2018-06-04 23:26:52 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
Module.antigrief_surface_tp = function()
|
2018-11-20 12:46:19 +02:00
|
|
|
if game.player then
|
|
|
|
if game.player.surface == global.ag_surface then
|
2019-01-16 20:44:55 +02:00
|
|
|
game.player.teleport(game.player.position, RS.get_surface())
|
2018-11-20 12:46:19 +02:00
|
|
|
else
|
|
|
|
game.player.teleport(game.player.position, global.ag_surface)
|
|
|
|
end
|
2018-06-04 23:26:52 +02:00
|
|
|
end
|
2018-06-03 15:47:12 +02:00
|
|
|
end
|
|
|
|
|
2018-06-05 01:34:58 +02:00
|
|
|
Module.count_removed_entities = function(player)
|
2018-11-20 12:46:19 +02:00
|
|
|
return #Utils.find_entities_by_last_user(player, global.ag_surface)
|
2018-06-05 01:34:58 +02:00
|
|
|
end
|
|
|
|
|
2018-06-03 15:47:12 +02:00
|
|
|
return Module
|