diff --git a/modules/towny/connected_building.lua b/modules/towny/connected_building.lua new file mode 100644 index 00000000..51dbc15c --- /dev/null +++ b/modules/towny/connected_building.lua @@ -0,0 +1,53 @@ +local Public = {} + +local connection_radius = 3 + +local function is_entity_isolated(surface, entity) + local position_x = entity.position.x + local position_y = entity.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 = entity.force.name})) do + if game.entity_prototypes[e.name] and game.recipe_prototypes[e.name] or e.name == "market" then + count = count + 1 + if count > 1 then return end + end + end + + return true +end + +local function refund_entity(event) + local entity_name = event.created_entity.name + + if event.player_index then + game.players[event.player_index].insert({name = entity_name, count = 1}) + return + end + + if event.robot then + local inventory = event.robot.get_inventory(defines.inventory.robot_cargo) + inventory.insert({name = entity_name, count = 1}) + return + end +end + +function Public.prevent_isolation(event) + local entity = event.created_entity + if not entity.valid then return end + local surface = event.created_entity.surface + + if is_entity_isolated(surface, entity) then + refund_entity(event) + surface.create_entity({ + name = "flying-text", + position = entity.position, + text = "Building is not connected to the town!", + color = {r=0.77, g=0.0, b=0.0} + }) + entity.destroy() + end +end + +return Public \ No newline at end of file diff --git a/modules/towny/main.lua b/modules/towny/main.lua index a48670ef..d35ac8ec 100644 --- a/modules/towny/main.lua +++ b/modules/towny/main.lua @@ -1,16 +1,38 @@ -local found_town_center = require "modules.towny.found_town_center" +local Town_center = require "modules.towny.town_center" +local Team = require "modules.towny.team" +local Connected_building = require "modules.towny.connected_building" local function on_player_joined_game(event) + local player = game.players[event.player_index] + + if player.force.index == 1 then + player.print("Towny is enabled on this server!", {255, 255, 0}) + player.print("Place a stone furnace, to found a new town center. Or join a town by visiting another player's center.", {255, 255, 0}) + end + + if player.online_time == 0 then player.insert({name = "stone-furnace", count = 1}) end +end + +local function on_player_respawned(event) local player = game.players[event.player_index] - if player.online_time == 0 then - player.insert({name = "pistol", count = 1}) - player.insert({name = "firearm-magazine", count = 16}) - player.insert({name = "stone-furnace", count = 1}) - end + if player.force.index ~= 1 then return end + player.insert({name = "stone-furnace", count = 1}) end local function on_built_entity(event) - found_town_center(event) + if Town_center.found(event) then return end + Connected_building.prevent_isolation(event) +end + +local function on_robot_built_entity(event) + Connected_building.prevent_isolation(event) +end + +local function on_entity_died(event) + local entity = event.entity + if entity.name == "market" then + Team.kill_force(entity.force.name) + end end local function on_init() @@ -22,4 +44,7 @@ end local Event = require 'utils.event' Event.on_init(on_init) Event.add(defines.events.on_player_joined_game, on_player_joined_game) -Event.add(defines.events.on_built_entity, on_built_entity) \ No newline at end of file +Event.add(defines.events.on_player_respawned, on_player_respawned) +Event.add(defines.events.on_robot_built_entity, on_robot_built_entity) +Event.add(defines.events.on_built_entity, on_built_entity) +Event.add(defines.events.on_entity_died, on_entity_died) \ No newline at end of file diff --git a/modules/towny/team.lua b/modules/towny/team.lua index c9f00792..220dc135 100644 --- a/modules/towny/team.lua +++ b/modules/towny/team.lua @@ -1,10 +1,5 @@ local Public = {} -function Public.set_homeless_player(player) - if player.character then player.character.die() end - player.force = game.forces.player -end - function Public.add_new_force(force_name) game.create_force(force_name) @@ -17,13 +12,19 @@ function Public.kill_force(force_name) local market = global.towny.town_centers[force_name] local surface = market.surface - for _, player in pairs(force.players) do Public.set_homeless_player(player) end + for _, player in pairs(force.players) do + if player.character then player.character.die() end + player.force = game.forces.player + end for _, e in pairs(surface.find_entities_filtered({force = force_name})) do e.active = false end - merge_forces(force_name, "neutral") + game.merge_forces(force_name, "neutral") - game.print(force_name .. "'s town has fallen!", {255, 255, 0}) + global.towny.town_centers[force_name] = nil + global.towny.size_of_town_centers = global.towny.size_of_town_centers - 1 + + game.print(">> " .. force_name .. "'s town has fallen!", {255, 255, 0}) end return Public \ No newline at end of file diff --git a/modules/towny/found_town_center.lua b/modules/towny/town_center.lua similarity index 76% rename from modules/towny/found_town_center.lua rename to modules/towny/town_center.lua index c0765fae..7bca2218 100644 --- a/modules/towny/found_town_center.lua +++ b/modules/towny/town_center.lua @@ -1,4 +1,5 @@ local Team = require "modules.towny.team" +local Public = {} local table_insert = table.insert @@ -16,13 +17,27 @@ for y = -31, 31, 1 do table_insert(town_wall_vectors, {-32, y}) end +local clear_blacklist_types = { + ["simple-entity"] = true, + ["tree"] = true, + ["cliff"] = true, +} + local function draw_town_spawn(player_name) local market = global.towny.town_centers[player_name] local position = market.position local surface = market.surface + local area = {{position.x - town_radius, position.y - town_radius}, {position.x + town_radius, position.y + town_radius}} + + for _, e in pairs(surface.find_entities_filtered({area = area, force = "neutral"})) do + if not clear_blacklist_types[e.type] then + e.destroy() + end + end + for _, vector in pairs(town_wall_vectors) do - local p = {position.x + vector[1], position.x + vector[2]} + local p = {position.x + vector[1], position.y + vector[2]} if surface.can_place_entity({name = "stone-wall", position = p, force = player_name}) then surface.create_entity({name = "stone-wall", position = p, force = player_name}) end @@ -67,10 +82,20 @@ local function is_valid_location(surface, entity) end end - if count <= 4 then return true end + if count > 3 then + surface.create_entity({ + name = "flying-text", + position = entity.position, + text = "Area has too many non-neutral entities!", + color = {r=0.77, g=0.0, b=0.0} + }) + return + end + + return true end -local function found_town_center(event) +function Public.found(event) local entity = event.created_entity if entity.name ~= "stone-furnace" then return end @@ -97,7 +122,9 @@ local function found_town_center(event) draw_town_spawn(player_name) player.force = game.forces[player_name] - game.print(player.name .. " has founded a new town!", {255, 255, 0}) + game.print(">> " .. player.name .. " has founded a new town!", {255, 255, 0}) + + return true end -return found_town_center \ No newline at end of file +return Public \ No newline at end of file