1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00

Merge pull request #322 from blubFisch/town-protection

Town protection
This commit is contained in:
Gerkiz 2022-10-05 21:19:40 +02:00 committed by GitHub
commit 2607d77ffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 137 additions and 0 deletions

View File

@ -0,0 +1,105 @@
local Public = {}
local Event = require 'utils.event'
local ScenarioTable = require 'maps.scrap_towny_ffa.table'
local CommonFunctions = require 'utils.common'
local zone_size = 100
local beam_type = 'electric-beam-no-sound'
local lifetime_ticks = 4 * 60 * 60 * 60
local function draw_borders(zone)
local surface = zone.surface
local right = zone.box.right_bottom.x
local left = zone.box.left_top.x
local top = zone.box.left_top.y
local bottom = zone.box.right_bottom.y
surface.create_entity({name = beam_type, position = {right, top},
source = {right, top}, target = {right, bottom + 1}}) -- intentional offset here to correct visual appearance
surface.create_entity({name = beam_type, position = {right, bottom},
source = {right, bottom}, target = {left, bottom}})
surface.create_entity({name = beam_type, position = {left, bottom},
source = {left, bottom}, target = {left, top}})
surface.create_entity({name = beam_type, position = {left, top},
source = {left, top}, target = {right, top}})
end
local function remove_drawn_borders(zone)
for _, e in pairs(zone.surface.find_entities_filtered({area = zone.box, name = beam_type})) do
if e.valid then
e.destroy()
end
end
end
function Public.add_zone(surface, force, center, lifetime_update_callback)
local this = ScenarioTable.get_table()
local box = {left_top = {x = center.x - zone_size / 2, y = center.y - zone_size / 2},
right_bottom = {x = center.x + zone_size / 2, y = center.y + zone_size / 2}}
local zone = {surface = surface, force = force, center = center, box = box,
lifetime_end = game.tick + lifetime_ticks, lifetime_update_callback = lifetime_update_callback}
this.exclusion_zones[force.name] = zone
draw_borders(zone)
end
function Public.remove_zone(zone)
local this = ScenarioTable.get_table()
remove_drawn_borders(zone)
this.exclusion_zones[zone.force.name] = nil
end
local function vector_norm(vector)
return math.sqrt(vector.x ^ 2 + vector.y ^ 2)
end
local function update_zone_lifetime()
local this = ScenarioTable.get_table()
for _, zone in pairs(this.exclusion_zones) do
if game.tick > zone.lifetime_end then
Public.remove_zone(zone)
end
zone.lifetime_update_callback(zone.force)
end
end
local function on_player_changed_position(event)
local player = game.get_player(event.player_index)
local surface = player.surface
if not surface or not surface.valid then
return
end
local this = ScenarioTable.get_table()
for _, zone in pairs(this.exclusion_zones) do
if not (zone.force == player.force or zone.force.get_friend(player.force)) then
if CommonFunctions.point_in_bounding_box(player.position, zone.box) then
local center_diff = { x = player.position.x - zone.center.x, y = player.position.y - zone.center.y}
center_diff.x = center_diff.x / vector_norm(center_diff)
center_diff.y = center_diff.y / vector_norm(center_diff)
player.teleport({ player.position.x + center_diff.x, player.position.y + center_diff.y}, surface)
if player.character then
-- Kick players out of vehicles if they try to drive in
if player.character.driving then
player.character.driving = false
end
-- Damage player
player.character.health = player.character.health - 25
player.character.surface.create_entity({name = 'water-splash', position = player.position})
if player.character.health <= 0 then
player.character.die('enemy')
end
end
end
end
end
end
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
Event.on_nth_tick(60, update_zone_lifetime)
return Public

View File

@ -37,6 +37,7 @@ function Public.reset_table()
this.mining_entity = {}
this.mining_target = {}
this.spaceships = {}
this.exclusion_zones = {}
end
function Public.get_table()

View File

@ -8,6 +8,7 @@ local string_lower = string.lower
local Server = require 'utils.server'
local Map = require 'maps.scrap_towny_ffa.map'
local ScenarioTable = require 'maps.scrap_towny_ffa.table'
local ExclusionZone = require 'maps.scrap_towny_ffa.exclusion_zone'
local outlander_color = {150, 150, 150}
local outlander_chat_color = {170, 170, 170}
@ -796,6 +797,7 @@ local function kill_force(force_name, cause)
end
end
ExclusionZone.remove_zone(this.exclusion_zones[force_name])
game.merge_forces(force_name, 'neutral')
this.town_centers[force_name] = nil
this.number_of_towns = this.number_of_towns - 1

View File

@ -13,6 +13,7 @@ local Building = require 'maps.scrap_towny_ffa.building'
local Colors = require 'maps.scrap_towny_ffa.colors'
local Enemy = require 'maps.scrap_towny_ffa.enemy'
local Color = require 'utils.color_presets'
local ExclusionZone = require 'maps.scrap_towny_ffa.exclusion_zone'
local town_radius = 27
local radius_between_towns = 64
@ -367,6 +368,19 @@ function Public.update_coin_balance(force)
rendering.set_text(town_center.coins_text, 'Coins: ' .. town_center.coin_balance)
end
function Public.update_protection_display(force)
local this = ScenarioTable.get_table()
local town_center = this.town_centers[force.name]
local zone = this.exclusion_zones[force.name]
local info
if zone then
info = string.format("%.0f", (zone.lifetime_end - game.tick) / 60 / 60) .. ' minutes'
else
info = "Expired"
end
rendering.set_text(town_center.zone_text, 'Protection: ' .. info)
end
local function found_town(event)
local entity = event.created_entity
-- is a valid entity placed?
@ -513,10 +527,25 @@ local function found_town(event)
scale_with_zoom = false
}
town_center.zone_text = rendering.draw_text {
text = 'Town protection: (..)',
surface = surface,
forces = {force_name},
target = town_center.market,
target_offset = {0, -2.25},
color = {200, 200, 200},
scale = 1.00,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
this.number_of_towns = this.number_of_towns + 1
Enemy.clear_enemies(position, surface, town_radius * 5)
draw_town_spawn(force_name)
ExclusionZone.add_zone(surface, force, position, Public.update_protection_display)
Public.update_protection_display(force)
-- set the spawn point
local pos = {x = town_center.market.position.x, y = town_center.market.position.y + 4}