185 lines
6.4 KiB
Lua
185 lines
6.4 KiB
Lua
--- Tools for working with entities.
|
|
-- @module Entity.Entity
|
|
-- @usage local Entity = require('__stdlib__/stdlib/entity/entity')
|
|
|
|
local Entity = {
|
|
__class = 'Entity',
|
|
__index = require('__stdlib__/stdlib/core')
|
|
}
|
|
setmetatable(Entity, Entity)
|
|
|
|
--- Tests whether an entity has access to a given field.
|
|
-- @tparam LuaEntity entity the entity to test the access to a field
|
|
-- @tparam string field_name the field name
|
|
-- @treturn boolean true if the entity has access to the field, false if the entity threw an exception when trying to access the field
|
|
function Entity.has(entity, field_name)
|
|
assert(entity, 'missing entity argument')
|
|
assert(field_name, 'missing field name argument')
|
|
|
|
local status =
|
|
pcall(
|
|
function()
|
|
return entity[field_name]
|
|
end
|
|
)
|
|
return status
|
|
end
|
|
|
|
--- Gets the user data that is associated with an entity.
|
|
-- The user data is stored in the global object and it persists between loads.
|
|
--> The user data will be removed from an entity when the entity becomes invalid.
|
|
-- @tparam LuaEntity entity the entity to look up
|
|
-- @treturn ?|nil|Mixed the user data, or nil if no data exists for the entity
|
|
function Entity.get_data(entity)
|
|
assert(entity, 'missing entity argument')
|
|
if not global._entity_data then
|
|
return nil
|
|
end
|
|
|
|
local unit_number = entity.unit_number
|
|
if unit_number then
|
|
return global._entity_data[unit_number]
|
|
else
|
|
local entity_name = entity.name
|
|
if not global._entity_data[entity_name] then
|
|
return nil
|
|
end
|
|
|
|
local entity_category = global._entity_data[entity_name]
|
|
for _, entity_data in pairs(entity_category) do
|
|
if Entity._are_equal(entity_data.entity, entity) then
|
|
return entity_data.data
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
end
|
|
|
|
--- Associates the user data to an entity.
|
|
-- The user data will be stored in the global object and it will persist between loads.
|
|
--> The user data will be removed from an entity when the entity becomes invalid.
|
|
-- @tparam LuaEntity entity the entity with which to associate the user data
|
|
-- @tparam ?|nil|Mixed data the data to set, or nil to delete the data associated with the entity
|
|
-- @treturn ?|nil|Mixed the previous data associated with the entity, or nil if the entity had no previous data
|
|
function Entity.set_data(entity, data)
|
|
assert(entity, 'missing entity argument')
|
|
|
|
if not global._entity_data then
|
|
global._entity_data = {}
|
|
end
|
|
|
|
local unit_number = entity.unit_number
|
|
if unit_number then
|
|
local prev = global._entity_data[unit_number]
|
|
global._entity_data[unit_number] = data
|
|
return prev
|
|
else
|
|
local entity_name = entity.name
|
|
if not global._entity_data[entity_name] then
|
|
global._entity_data[entity_name] = {}
|
|
end
|
|
|
|
local entity_category = global._entity_data[entity_name]
|
|
|
|
for i = #entity_category, 1, -1 do
|
|
local entity_data = entity_category[i]
|
|
if not entity_data.entity.valid then
|
|
table.remove(entity_category, i)
|
|
end
|
|
if Entity._are_equal(entity_data.entity, entity) then
|
|
local prev = entity_data.data
|
|
if data then
|
|
entity_data.data = data
|
|
else
|
|
table.remove(entity_category, i)
|
|
end
|
|
return prev
|
|
end
|
|
end
|
|
table.insert(entity_category, { entity = entity, data = data })
|
|
end
|
|
return nil
|
|
end
|
|
|
|
--- Freezes an entity, by making it inactive, inoperable, and non-rotatable, or unfreezes by doing the reverse.
|
|
-- @tparam LuaEntity entity the entity to freeze or unfreeze
|
|
-- @tparam[opt=true] boolean mode if true, freezes the entity, if false, unfreezes the entity. If not specified, it is set to true
|
|
-- @treturn LuaEntity the entity that has been frozen or unfrozen
|
|
function Entity.set_frozen(entity, mode)
|
|
assert(entity, 'missing entity argument')
|
|
mode = mode == false and true or false
|
|
entity.active = mode
|
|
entity.operable = mode
|
|
entity.rotatable = mode
|
|
return entity
|
|
end
|
|
|
|
--- Makes an entity indestructible so that it cannot be damaged or mined neither by the player nor by their enemy factions.
|
|
-- @tparam LuaEntity entity the entity to make indestructable
|
|
-- @tparam[opt=true] boolean mode if true, makes the entity indestructible, if false, makes the entity destructable
|
|
-- @treturn LuaEntity the entity that has been made indestructable or destructable
|
|
function Entity.set_indestructible(entity, mode)
|
|
assert(entity, 'missing entity argument')
|
|
mode = mode == false and true or false
|
|
entity.minable = mode
|
|
entity.destructible = mode
|
|
return entity
|
|
end
|
|
|
|
--- Tests if two entities are equal.
|
|
-- If they don't have a reference equality and ***entity\_a*** has ***equals*** function, it will be called with ***entity\_b*** as its first argument.
|
|
-- @tparam LuaEntity entity_a
|
|
-- @tparam LuaEntity entity_b
|
|
-- @treturn boolean
|
|
function Entity._are_equal(entity_a, entity_b)
|
|
if entity_a == nil then
|
|
return entity_a == entity_b
|
|
elseif entity_a == entity_b then
|
|
return true
|
|
elseif Entity.has(entity_a, 'equals') and entity_a.equals ~= nil then
|
|
return entity_a.equals(entity_b)
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function Entity.find_resources(entity, all)
|
|
if entity.type == 'mining-drill' then
|
|
local radius = entity.prototype.mining_drill_radius
|
|
local name = (not all and (entity.mining_target and entity.mining_target.name)) or nil
|
|
return entity.surface.count_entities_filtered {
|
|
type = 'resource',
|
|
name = name,
|
|
position = entity.position,
|
|
radius = radius,
|
|
}
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function Entity.is_damaged(entity)
|
|
return entity.get_health_ratio() < 1
|
|
end
|
|
Entity.damaged = Entity.is_damaged
|
|
|
|
function Entity.is_circuit_connected(entity)
|
|
local list = entity.circuit_connected_entities
|
|
return list and (next(list.red) or next(list.green))
|
|
end
|
|
|
|
function Entity.count_circuit_connections(entity)
|
|
local list = entity.circuit_connected_entities
|
|
return list and #list.red + #list.green
|
|
end
|
|
|
|
function Entity.has_fluidbox(entity)
|
|
local box = entity.fluidbox
|
|
return box and #box > 0
|
|
end
|
|
|
|
function Entity.can_deconstruct(entity)
|
|
return entity.minable and entity.prototype.selectable_in_game and not entity.has_flag('not-deconstructable')
|
|
end
|
|
|
|
return Entity
|