local Public = {} local connection_radius = 7 local entity_type_whitelist = { ['accumulator'] = true, ['ammo-turret'] = true, ['arithmetic-combinator'] = true, ['artillery-turret'] = true, ['assembling-machine'] = true, ['boiler'] = true, ['constant-combinator'] = true, ['container'] = true, ['curved-rail'] = true, ['decider-combinator'] = true, ['electric-pole'] = true, ['electric-turret'] = true, ['fluid-turret'] = true, ['furnace'] = true, ['gate'] = true, ['generator'] = true, ['heat-interface'] = true, ['heat-pipe'] = true, ['infinity-container'] = true, ['infinity-pipe'] = true, ['inserter'] = true, ['lamp'] = true, ['land-mine'] = true, ['loader'] = true, ['logistic-container'] = true, ['market'] = true, ['mining-drill'] = true, ['offshore-pump'] = true, ['pipe'] = true, ['pipe-to-ground'] = true, ['programmable-speaker'] = true, ['pump'] = true, ['radar'] = true, ['rail-chain-signal'] = true, ['rail-signal'] = true, ['reactor'] = true, ['roboport'] = true, ['rocket-silo'] = true, ['solar-panel'] = true, ['splitter'] = true, ['storage-tank'] = true, ['straight-rail'] = true, ['train-stop'] = true, ['transport-belt'] = true, ['underground-belt'] = true, ['wall'] = true } local function is_position_isolated(surface, force, position) local position_x = position.x local position_y = position.y local area = {{position_x - connection_radius, position_y - connection_radius}, {position_x + connection_radius, position_y + connection_radius}} local count = 0 for _, e in pairs(surface.find_entities_filtered({area = area, force = force.name})) do if entity_type_whitelist[e.type] then count = count + 1 if count > 1 then return end end end return true end local function refund_item(event, item_name) if event.player_index then game.players[event.player_index].insert({name = item_name, count = 1}) return end if event.robot then local inventory = event.robot.get_inventory(defines.inventory.robot_cargo) inventory.insert({name = item_name, count = 1}) return end end local function error_floaty(surface, position, msg) surface.create_entity( { name = 'flying-text', position = position, text = msg, color = {r = 0.77, g = 0.0, b = 0.0} } ) end local function is_town_market_nearby(entity) local area = {{entity.position.x - 48, entity.position.y - 48}, {entity.position.x + 48, entity.position.y + 48}} local markets = entity.surface.find_entities_filtered({name = 'market', area = area}) if not markets[1] then return false end for _, market in pairs(markets) do if market.force.index > 3 then return true end end return false end function Public.prevent_isolation(event) local entity = event.created_entity if not entity.valid then return end if entity.force.index == 1 then return end if not entity_type_whitelist[entity.type] then return end local surface = event.created_entity.surface if is_position_isolated(surface, entity.force, entity.position) then error_floaty(surface, entity.position, {'modules_towny.message_error_building'}) refund_item(event, event.stack.name) entity.destroy() return true end end function Public.prevent_isolation_landfill(event) if event.item.name ~= 'landfill' then return end local surface = game.surfaces[event.surface_index] local tiles = event.tiles local force if event.player_index then force = game.players[event.player_index].force else force = event.robot.force end for _, placed_tile in pairs(tiles) do local position = placed_tile.position if is_position_isolated(surface, force, position) then error_floaty(surface, position, {'modules_towny.message_error_tile'}) surface.set_tiles({{name = 'water', position = position}}, true) refund_item(event, 'landfill') end end end local square_min_distance_to_spawn = 80 ^ 2 function Public.restrictions(event) local entity = event.created_entity if not entity.valid then return end if entity.force.index == 1 then if is_town_market_nearby(entity) then refund_item(event, event.stack.name) error_floaty(entity.surface, entity.position, {'modules_towny.message_error_close_town'}) entity.destroy() end return end if not entity_type_whitelist[entity.type] then return end if entity.position.x ^ 2 + entity.position.y ^ 2 > square_min_distance_to_spawn then return end refund_item(event, event.stack.name) error_floaty(entity.surface, entity.position, {'modules_towny.message_error_close_spawn'}) entity.destroy() end return Public