mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-30 23:17:53 +02:00
new module
This commit is contained in:
parent
ce714f6518
commit
1b1b7b620b
295
modules/render.lua
Normal file
295
modules/render.lua
Normal file
@ -0,0 +1,295 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local this = {
|
||||
renders = {}
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local target_entities = {
|
||||
'character',
|
||||
'tank',
|
||||
'car',
|
||||
'radar',
|
||||
'lab',
|
||||
'furnace',
|
||||
'locomotive',
|
||||
'cargo-wagon',
|
||||
'fluid-wagon',
|
||||
'artillery-wagon',
|
||||
'artillery-turret',
|
||||
'laser-turret',
|
||||
'gun-turret',
|
||||
'flamethrower-turret',
|
||||
'silo',
|
||||
'spidertron'
|
||||
}
|
||||
|
||||
local Public = {}
|
||||
|
||||
local sqrt = math.sqrt
|
||||
local random = math.random
|
||||
local remove = table.remove
|
||||
local speed = 0.06
|
||||
|
||||
--- Draws a new render.
|
||||
---@param target table
|
||||
---@param sprite string
|
||||
---@param surface userdata
|
||||
---@return integer
|
||||
function Public.new_render(target, sprite, surface)
|
||||
return rendering.draw_sprite {target = target, sprite = sprite, surface = surface}
|
||||
end
|
||||
|
||||
--- Sets a new target for a given render.
|
||||
---@param surface userdata
|
||||
---@return table
|
||||
---@return table
|
||||
function Public.new_target(surface)
|
||||
local position
|
||||
local entities = surface.find_entities_filtered {type = target_entities}
|
||||
if entities and #entities > 0 then
|
||||
position = entities[random(#entities)].position
|
||||
end
|
||||
|
||||
local chunk = surface.get_random_chunk()
|
||||
local random_position = {x = (chunk.x + random()) * 32, y = (chunk.y + random()) * 32}
|
||||
|
||||
return position, random_position
|
||||
end
|
||||
|
||||
--- Increments the given position
|
||||
---@param p1 table
|
||||
---@param p2 table
|
||||
---@return table
|
||||
function Public.increment(p1, p2)
|
||||
return {x = p1.x + p2.x, y = p1.y + p2.y}
|
||||
end
|
||||
|
||||
--- Multiples a given position
|
||||
---@param a table|integer
|
||||
---@return number|table
|
||||
function Public.multiply(a)
|
||||
return sqrt(a.x * a.x + a.y * a.y)
|
||||
end
|
||||
|
||||
--- Subtracts the given positions
|
||||
---@param p1 table
|
||||
---@param p2 table
|
||||
---@return table|integer
|
||||
function Public.subtr(p1, p2)
|
||||
if not p1 and p2 then
|
||||
return 0
|
||||
end
|
||||
return {x = p2.x - p1.x, y = p2.y - p1.y}
|
||||
end
|
||||
|
||||
--- Sets the render scale.
|
||||
---@param target_id any
|
||||
function Public.set_render_scalar_size(target_id)
|
||||
if not target_id then
|
||||
return
|
||||
end
|
||||
|
||||
rendering.set_y_scale(target_id, 3.5) -- 1.5
|
||||
rendering.set_x_scale(target_id, 7) -- 2
|
||||
rendering.set_color(
|
||||
target_id,
|
||||
{
|
||||
r = 1,
|
||||
g = 0.7,
|
||||
b = 0.7
|
||||
}
|
||||
)
|
||||
end
|
||||
--- local render = Public.new_render(target, sprite, surface)
|
||||
--- render.target_position = random_position()
|
||||
--- Gets a random position.
|
||||
---@param position any
|
||||
---@return table
|
||||
function Public.random_position(position)
|
||||
return Public.increment(position, {x = (random() - 0.5) * 64, y = (random() - 0.5) * 64})
|
||||
end
|
||||
|
||||
--- Changes the position of a render.
|
||||
---@param position table
|
||||
---@param target_position table
|
||||
---@param max_abs number
|
||||
---@param value boolean
|
||||
---@return table|nil
|
||||
function Public.change_position(position, target_position, max_abs, value)
|
||||
if not position or not target_position then
|
||||
return
|
||||
end
|
||||
local scalar = 0.9
|
||||
local subtr = Public.subtr(position, target_position)
|
||||
if value then
|
||||
subtr.y = subtr.y / scalar
|
||||
end
|
||||
local multiply = Public.multiply(subtr)
|
||||
if (multiply > max_abs) then
|
||||
local close = max_abs / multiply
|
||||
subtr = {x = subtr.x * close, y = subtr.y * close}
|
||||
end
|
||||
if value then
|
||||
subtr.y = subtr.y * scalar
|
||||
end
|
||||
return {x = position.x + subtr.x, y = position.y + subtr.y}
|
||||
end
|
||||
|
||||
--- If a render is stuck, give it a new position.
|
||||
---@param render table
|
||||
function Public.switch_position(render)
|
||||
if random() < 0.4 then
|
||||
render.target_position = Public.random_position(render.target_position)
|
||||
else
|
||||
local surface = game.get_surface(render.surface_id)
|
||||
local chunk = surface.get_random_chunk()
|
||||
render.target_position = {x = (chunk.x + math.random()) * 32, y = (chunk.y + math.random()) * 32}
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets a new position for a render.
|
||||
---@param render table
|
||||
function Public.set_new_position(render)
|
||||
render.position = Public.change_position(render.position, render.target_position, speed, false)
|
||||
|
||||
if not render.random_pos_set then
|
||||
render.random_pos_set = true
|
||||
render.random_pos_tick = game.tick + 300
|
||||
end
|
||||
if render.position.x == render.target_position.x and render.position.y == render.target_position.y then
|
||||
Public.switch_position(render)
|
||||
end
|
||||
|
||||
if Public.validate(render) then
|
||||
rendering.set_target(render.render_id, render.position)
|
||||
Public.set_render_scalar_size(render.render_id)
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates fire flame.
|
||||
---@param render table
|
||||
function Public.render_fire_damage(render)
|
||||
if random(1, 15) == 1 then
|
||||
local surface = game.get_surface(render.surface_id)
|
||||
surface.create_entity({name = 'fire-flame', position = {x = render.position.x, y = render.position.y + 5}})
|
||||
if random(1, 5) == 1 then
|
||||
surface.create_entity({name = 'medium-scorchmark', position = {x = render.position.x, y = render.position.y + 5}, force = 'neutral'})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Damages entities nearby.
|
||||
---@param render table
|
||||
function Public.damage_entities_nearby(render)
|
||||
if random(1, 5) == 1 then
|
||||
local surface = game.get_surface(render.surface_id)
|
||||
local radius = 10
|
||||
local damage = random(10, 15)
|
||||
local entities = surface.find_entities_filtered({area = {{render.position.x - radius - 4, render.position.y - radius - 6}, {render.position.x + radius + 4, render.position.y + radius + 6}}})
|
||||
for _, entity in pairs(entities) do
|
||||
if entity.valid then
|
||||
if entity.health then
|
||||
if entity.force.name ~= 'enemy' then
|
||||
if entity.name == 'character' then
|
||||
entity.damage(damage, 'enemy')
|
||||
else
|
||||
entity.health = entity.health - damage
|
||||
if entity.health <= 0 then
|
||||
entity.die('enemy')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Validates if a render is valid.
|
||||
---@param render table
|
||||
---@return boolean
|
||||
function Public.validate(render)
|
||||
if rendering.is_valid(render.render_id) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Destroys a render.
|
||||
---@param render table
|
||||
function Public.destroy_render(render)
|
||||
if rendering.is_valid(render.render_id) then
|
||||
rendering.destroy(render.render_id)
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes a render.
|
||||
---@param render table
|
||||
---@param id integer
|
||||
function Public.remove_render(render, id)
|
||||
Public.destroy_render(render)
|
||||
|
||||
remove(this.renders, id)
|
||||
end
|
||||
|
||||
--- Creates a new render.
|
||||
---@param sprite string
|
||||
---@param surface userdata
|
||||
---@param ttl integer
|
||||
---@param scalar table
|
||||
---@return table
|
||||
function Public.new(sprite, surface, ttl, scalar)
|
||||
local render = {}
|
||||
local position, random_position = Public.new_target(surface)
|
||||
render.position = position
|
||||
render.surface_id = surface.index
|
||||
render.sprite = sprite
|
||||
render.target_position = random_position
|
||||
render.render_id = Public.new_render(render.position, sprite, surface)
|
||||
render.ttl = ttl or game.tick + 7200 -- 2 minutes duration
|
||||
if not scalar then
|
||||
Public.set_render_scalar_size(render.render_id)
|
||||
end
|
||||
|
||||
this.renders[#this.renders + 1] = render
|
||||
|
||||
return render
|
||||
end
|
||||
|
||||
Event.add(
|
||||
defines.events.on_tick,
|
||||
function()
|
||||
if #this.renders == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local tick = game.tick
|
||||
|
||||
for id, render in pairs(this.renders) do
|
||||
if render then
|
||||
if tick < render.ttl then
|
||||
Public.set_new_position(render)
|
||||
Public.render_fire_damage(render)
|
||||
Public.damage_entities_nearby(render)
|
||||
if render.random_pos_set and tick > render.random_pos_tick then
|
||||
Public.switch_position(render)
|
||||
render.random_pos_set = nil
|
||||
render.random_pos_tick = nil
|
||||
end
|
||||
else
|
||||
Public.remove_render(render, id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
BIN
utils/files/beam.png
Normal file
BIN
utils/files/beam.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Loading…
Reference in New Issue
Block a user