mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-05-13 21:56:29 +02:00
planet_prison: add claim system
Adds claim system to mark player bases.
This commit is contained in:
parent
cfd35eb9bd
commit
284ed14b74
@ -8,6 +8,7 @@ local _layers = require("planet_prison.mod.layers")
|
||||
local _ai = require("planet_prison.mod.ai")
|
||||
local _bp = require("planet_prison.mod.bp")
|
||||
local _afk = require("planet_prison.mod.afk")
|
||||
local _claims = require("planet_prison.mod.claims")
|
||||
global.this._config = require("planet_prison.config")
|
||||
|
||||
global.this.maps = {
|
||||
@ -226,6 +227,8 @@ local function init_game()
|
||||
_bp.init()
|
||||
_ai.init()
|
||||
_timers.init()
|
||||
_claims.init(global.this._config.claim_markers,
|
||||
global.this._config.claim_max_distance)
|
||||
|
||||
local map = pick_map()
|
||||
local preset = global.this.presets[map.name]
|
||||
@ -380,6 +383,14 @@ local function get_non_obstructed_position(s, radius)
|
||||
return chunk
|
||||
end
|
||||
|
||||
local function switchable_perk(caption, status)
|
||||
if status then
|
||||
return string.format("[color=0,80,0]%s[/color]", caption)
|
||||
end
|
||||
|
||||
return string.format("[color=80,0,0]%s[/color]", caption)
|
||||
end
|
||||
|
||||
local function redraw_gui(p)
|
||||
p.gui.left.clear()
|
||||
|
||||
@ -649,7 +660,7 @@ local function on_chunk_generated(e)
|
||||
_layers.push_chunk(e.position)
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(e)
|
||||
local function mined_wreckage(e)
|
||||
if e.entity.name ~= "mineable-wreckage" then
|
||||
return
|
||||
end
|
||||
@ -676,6 +687,16 @@ local function on_player_mined_entity(e)
|
||||
e.buffer.insert(cand)
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(e)
|
||||
local ent = e.entity
|
||||
if not ent.valid then
|
||||
return
|
||||
end
|
||||
|
||||
mined_wreckage(e)
|
||||
_claims.on_player_mined_entity(ent)
|
||||
end
|
||||
|
||||
local function on_player_died(e)
|
||||
local index = e.player_index
|
||||
if not index then
|
||||
@ -894,6 +915,7 @@ local function on_entity_died(e)
|
||||
|
||||
hostile_death(e)
|
||||
character_death(e)
|
||||
_claims.on_entity_died(e.entity)
|
||||
end
|
||||
|
||||
|
||||
@ -929,6 +951,7 @@ local function on_built_entity(e)
|
||||
return
|
||||
end
|
||||
|
||||
_claims.on_built_entity(ent)
|
||||
merchant_exploit_check(ent)
|
||||
end
|
||||
|
||||
|
@ -36,6 +36,11 @@ public.player_ship_loot = {
|
||||
}
|
||||
|
||||
public.self_explode = 60 * 60 * 10
|
||||
public.claim_markers = {
|
||||
"gun-turret",
|
||||
"laser-turret",
|
||||
}
|
||||
public.claim_max_distance = 15
|
||||
|
||||
public.wreck_loot = {
|
||||
["iron-plate"] = {
|
||||
|
230
maps/planet_prison/mod/claims.lua
Normal file
230
maps/planet_prison/mod/claims.lua
Normal file
@ -0,0 +1,230 @@
|
||||
local public = {}
|
||||
local common = require(".common")
|
||||
|
||||
--[[
|
||||
init - Initialize claim system.
|
||||
@param names - Table of entity names that should be used as a marker.
|
||||
@param max_distance - Maximal distance allowed between markers
|
||||
--]]
|
||||
public.init = function(names, max_distance)
|
||||
if global.this == nil then
|
||||
global.this = {}
|
||||
end
|
||||
|
||||
if type(names) ~= "table" then
|
||||
names = { names }
|
||||
end
|
||||
|
||||
global.this._claims_info = {}
|
||||
global.this._claims_visible_to = {}
|
||||
global.this._claim_markers = names
|
||||
global.this._claim_max_dist = max_distance
|
||||
end
|
||||
|
||||
global.this._claim_new_claim = function(ent, deps)
|
||||
local comm = deps.common
|
||||
local point = {
|
||||
{
|
||||
x = comm.get_axis(ent.position, "x"),
|
||||
y = comm.get_axis(ent.position, "y"),
|
||||
}
|
||||
}
|
||||
|
||||
local claims = global.this._claims_info
|
||||
if claims[ent.force.name] == nil then
|
||||
claims[ent.force.name] = {}
|
||||
claims[ent.force.name].polygons = {}
|
||||
claims[ent.force.name].claims = {}
|
||||
claims[ent.force.name].collections = {}
|
||||
end
|
||||
|
||||
table.insert(claims[ent.force.name].collections, point)
|
||||
end
|
||||
|
||||
global.this._claim_on_build_entity = function(ent, deps)
|
||||
local max_dist = global.this._claim_max_dist
|
||||
local force = ent.force.name
|
||||
local comm = deps.common
|
||||
local data = global.this._claims_info[force]
|
||||
|
||||
if data == nil then
|
||||
global.this._claim_new_claim(ent, deps)
|
||||
return
|
||||
end
|
||||
|
||||
local in_range = false
|
||||
local collections = data.collections
|
||||
for i = 1, #collections do
|
||||
local points = collections[i]
|
||||
|
||||
for _, point in pairs(points) do
|
||||
point = point
|
||||
local dist = comm.get_distance(point, ent.position)
|
||||
if max_dist < dist then
|
||||
goto continue
|
||||
end
|
||||
|
||||
in_range = true
|
||||
point = {
|
||||
x = comm.get_axis(ent.position, "x"),
|
||||
y = comm.get_axis(ent.position, "y"),
|
||||
}
|
||||
table.insert(points, point)
|
||||
data.claims[i] = comm.get_convex_hull(points)
|
||||
|
||||
break
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
if not in_range then
|
||||
global.this._claim_new_claim(ent, deps)
|
||||
end
|
||||
end
|
||||
|
||||
global.this._claims_in_markers = function(name)
|
||||
for _, marker in pairs(global.this._claim_markers) do
|
||||
if name == marker then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--[[
|
||||
on_build_entity - Event processing function.
|
||||
@param ent - Entity
|
||||
--]]
|
||||
public.on_built_entity = function(ent)
|
||||
if not global.this._claims_in_markers(ent.name) then
|
||||
return
|
||||
end
|
||||
|
||||
local deps = {
|
||||
common = common,
|
||||
}
|
||||
global.this._claim_on_build_entity(ent, deps)
|
||||
end
|
||||
|
||||
global.this._claim_on_entity_died = function(ent, deps)
|
||||
local comm = deps.common
|
||||
local force = ent.force.name
|
||||
local data = global.this._claims_info[force]
|
||||
if data == nil then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, #data.collections do
|
||||
local points = data.collections[i]
|
||||
|
||||
for j = 1, #points do
|
||||
local point = points[j]
|
||||
if comm.positions_equal(point, ent.position) then
|
||||
table.remove(points, j)
|
||||
|
||||
data.claims[i] = comm.get_convex_hull(points)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if #points == 0 then
|
||||
table.remove(data.claims, i)
|
||||
table.remove(data.collections, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if #data.claims == 0 then
|
||||
global.this._claims_info[force] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
on_entity_died - Event processing function.
|
||||
@param ent - Entity
|
||||
--]]
|
||||
public.on_entity_died = function(ent)
|
||||
if not global.this._claims_in_markers(ent.name) then
|
||||
return
|
||||
end
|
||||
|
||||
local deps = {
|
||||
common = common,
|
||||
}
|
||||
global.this._claim_on_entity_died(ent, deps)
|
||||
end
|
||||
|
||||
--[[
|
||||
on_player_mined_entity - Event processing function.
|
||||
@param ent - Entity
|
||||
--]]
|
||||
public.on_player_mined_entity = function(ent)
|
||||
public.on_entity_died(ent)
|
||||
end
|
||||
|
||||
--[[
|
||||
get_claims - Get all claims data points for given force.
|
||||
@param f_name - Force name.
|
||||
--]]
|
||||
public.get_claims = function(f_name)
|
||||
if global.this._claims_info[f_name] == nil then
|
||||
return {}
|
||||
end
|
||||
|
||||
return global.this._claims_info[f_name].claims
|
||||
end
|
||||
|
||||
global.this._claims_update_visiblity = function()
|
||||
if #global.this._claims_visible_to == 0 then
|
||||
for _, info in pairs(global.this._claims_info) do
|
||||
for _, id in pairs(info.polygons) do
|
||||
if rendering.is_valid(id) then
|
||||
rendering.set_visible(id, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
for _, info in pairs(global.this._claims_info) do
|
||||
for _, id in pairs(info.polygons) do
|
||||
if rendering.is_valid(id) then
|
||||
rendering.set_visible(id, true)
|
||||
rendering.set_players(id, global.this._claims_visible_to)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
set_visibility_to - Specifies who can see the claims and redraws.
|
||||
@param name - Name of a player.
|
||||
--]]
|
||||
public.set_visibility_to = function(name)
|
||||
for _, p in pairs(global.this._claims_visible_to) do
|
||||
if p == name then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(global.this._claims_visible_to, name)
|
||||
global.this._claims_update_visiblity()
|
||||
end
|
||||
|
||||
--[[
|
||||
remove_visibility_from - Remove the claim visibility from the player.
|
||||
@param name - Name of a player.
|
||||
--]]
|
||||
public.remove_visibility_from = function(name)
|
||||
for i = 1, #global.this._claims_visible_to do
|
||||
local p = global.this._claims_visible_to[i]
|
||||
if p == name then
|
||||
table.remove(global.this._claims_visible_to, i)
|
||||
global.this._claims_update_visiblity()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return public
|
@ -39,6 +39,10 @@ get_axis - Extract axis value from any point format.
|
||||
@param axis - Single character string describing the axis.
|
||||
--]]
|
||||
public.get_axis = function(point, axis)
|
||||
if point.target then
|
||||
return public.get_axis(point.target, axis)
|
||||
end
|
||||
|
||||
if point[axis] then
|
||||
return point[axis]
|
||||
end
|
||||
@ -289,4 +293,204 @@ public.get_time = function(ticks)
|
||||
return time
|
||||
end
|
||||
|
||||
--[[
|
||||
polygon_insert - Append vertex in clockwise order.
|
||||
@param vertex - Point to insert,
|
||||
@param vertices - Tables of vertices.
|
||||
--]]
|
||||
public.polygon_append_vertex = function(vertices, vertex)
|
||||
table.insert(vertices, vertex)
|
||||
|
||||
local x_avg, y_avg = 0, 0
|
||||
for _, v in pairs(vertices) do
|
||||
x_avg = x_avg + public.get_axis(v, "x")
|
||||
y_avg = y_avg + public.get_axis(v, "y")
|
||||
end
|
||||
x_avg = x_avg / #vertices
|
||||
y_avg = y_avg / #vertices
|
||||
|
||||
local delta_x, delta_y, rad1, rad2
|
||||
for i = 1, #vertices, 1 do
|
||||
for j = 1, #vertices - i do
|
||||
local v = vertices[j]
|
||||
delta_x = public.get_axis(v, "x") - x_avg
|
||||
delta_y = public.get_axis(v, "y") - y_avg
|
||||
rad1 = ((math.atan2(delta_x, delta_y) * (180 / 3.14)) + 360) % 360
|
||||
|
||||
v = vertices[j + 1]
|
||||
delta_x = public.get_axis(v, "x") - x_avg
|
||||
delta_y = public.get_axis(v, "y") - y_avg
|
||||
rad2 = ((math.atan2(delta_x, delta_y) * (180 / 3.14)) + 360) % 360
|
||||
if rad1 > rad2 then
|
||||
vertices[j], vertices[j + 1] = vertices[j + 1], vertices[j]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
positions_equal - Checks if given positions are equal.
|
||||
@param a - Position a
|
||||
@param b - Position b
|
||||
--]]
|
||||
public.positions_equal = function(a, b)
|
||||
local p1 = public.get_axis(a, "x")
|
||||
local p2 = public.get_axis(b, "x")
|
||||
|
||||
if p1 ~= p2 then
|
||||
return false
|
||||
end
|
||||
|
||||
p1 = public.get_axis(a, "y")
|
||||
p2 = public.get_axis(b, "y")
|
||||
|
||||
if p1 ~= p2 then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function rev(array, index)
|
||||
if index == nil then
|
||||
index = 0
|
||||
end
|
||||
|
||||
index = #array - index
|
||||
return array[index]
|
||||
end
|
||||
|
||||
--[[
|
||||
deepcopy - Makes a deep copy of an object.
|
||||
@param orig - Object to copy.
|
||||
--]]
|
||||
public.deepcopy = function(orig)
|
||||
local orig_type = type(orig)
|
||||
local copy
|
||||
if orig_type == 'table' then
|
||||
copy = {}
|
||||
for orig_key, orig_value in next, orig, nil do
|
||||
copy[public.deepcopy(orig_key)] = public.deepcopy(orig_value)
|
||||
end
|
||||
setmetatable(copy, public.deepcopy(getmetatable(orig)))
|
||||
else -- number, string, boolean, etc
|
||||
copy = orig
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
local function convex_hull_turn(a, b, c)
|
||||
local x1, x2, x3, y1, y2, y3
|
||||
x1 = public.get_axis(a, "x")
|
||||
x2 = public.get_axis(b, "x")
|
||||
|
||||
y1 = public.get_axis(a, "y")
|
||||
y2 = public.get_axis(b, "y")
|
||||
|
||||
if c then
|
||||
x3 = public.get_axis(c, "x")
|
||||
y3 = public.get_axis(c, "y")
|
||||
return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)
|
||||
end
|
||||
|
||||
return (x1 * y2) - (y1 * x2)
|
||||
end
|
||||
|
||||
--[[
|
||||
convex_hull - Generate convex hull out of given vertices.
|
||||
@param vertices - Table of positions.
|
||||
--]]
|
||||
public.get_convex_hull = function(_vertices)
|
||||
if #_vertices == 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local vertices = public.deepcopy(_vertices)
|
||||
|
||||
-- Get the lowest point
|
||||
local v, y1, y2, x1, x2, lowest_index
|
||||
local lowest = vertices[1]
|
||||
for i = 2, #vertices do
|
||||
v = vertices[i]
|
||||
y1 = public.get_axis(v, "y")
|
||||
y2 = public.get_axis(lowest, "y")
|
||||
|
||||
if y1 < y2 then
|
||||
lowest = v
|
||||
lowest_index = i
|
||||
elseif y1 == y2 then
|
||||
x1 = public.get_axis(v, "x")
|
||||
x2 = public.get_axis(lowest, "x")
|
||||
if x1 < x2 then
|
||||
lowest = v
|
||||
lowest_index = i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.remove(vertices, lowest_index)
|
||||
x1 = public.get_axis(lowest, "x")
|
||||
y1 = public.get_axis(lowest, "y")
|
||||
|
||||
-- Sort by angle to horizontal axis.
|
||||
local rad1, rad2, dist1, dist2
|
||||
|
||||
local i, j = 1, 1
|
||||
while i <= #vertices do
|
||||
while j <= #vertices - i do
|
||||
v = vertices[j]
|
||||
x2 = public.get_axis(v, "x")
|
||||
y2 = public.get_axis(v, "y")
|
||||
rad1 = (math.atan2(y2 - y1, x2 - x1) * (180/3.14) + 320) % 360
|
||||
|
||||
v = vertices[j + 1]
|
||||
x2 = public.get_axis(v, "x")
|
||||
y2 = public.get_axis(v, "y")
|
||||
rad2 = (math.atan2(y2 - y1, x2 - x1) * (180/3.14) + 320) % 360
|
||||
|
||||
if rad1 > rad2 then
|
||||
vertices[j + 1], vertices[j] = vertices[j], vertices[j + 1]
|
||||
elseif rad1 == rad2 then
|
||||
dist1 = public.get_distance(lowest, vertices[j])
|
||||
dist2 = public.get_distance(lowest, vertices[j + 1])
|
||||
if dist1 > dist2 then
|
||||
table.remove(vertices, j + 1)
|
||||
else
|
||||
table.remove(vertices, j)
|
||||
end
|
||||
end
|
||||
|
||||
j = j + 1
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if #vertices <= 3 then
|
||||
return {}
|
||||
end
|
||||
|
||||
-- Traverse points.
|
||||
local stack = {
|
||||
vertices[1],
|
||||
vertices[2],
|
||||
vertices[3],
|
||||
}
|
||||
local point
|
||||
for i = 4, #vertices do
|
||||
point = vertices[i]
|
||||
|
||||
while #stack > 1
|
||||
and convex_hull_turn(point, rev(stack, 1), rev(stack)) >= 0 do
|
||||
table.remove(stack)
|
||||
end
|
||||
|
||||
table.insert(stack, point)
|
||||
end
|
||||
|
||||
table.insert(stack, lowest)
|
||||
return stack
|
||||
end
|
||||
|
||||
return public
|
||||
|
Loading…
x
Reference in New Issue
Block a user