1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-01-18 03:21:47 +02:00

Merge pull request #504 from iltar/particle=control

Added particle limits and scales
This commit is contained in:
Matthew 2018-12-06 13:16:57 -05:00 committed by GitHub
commit d3a3c4726e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 124 additions and 5 deletions

View File

@ -1,9 +1,117 @@
local Task = require 'utils.Task'
local Global = require 'utils.global'
local Token = require 'utils.token'
local Command = require 'utils.command'
local Event = require 'utils.event'
local random = math.random
local ceil = math.ceil
local floor = math.floor
local format = string.format
local CreateParticles = {}
local settings = {
faction = 1.0,
particles_spawned_buffer = 0,
max_particles_per_second = 4000,
}
Global.register({
settings = settings,
}, function (tbl)
settings = tbl.settings
end)
---sets the scale of particles. 1.0 means 100%, 0.5 would mean spawn only 50% of the particles.
---@param fraction number
function CreateParticles.set_fraction(fraction)
if fraction < 0 or fraction > 1 then
error(format('Fraction must range from 0 to 1'))
end
settings.faction = fraction
end
---Returns the current scale
function CreateParticles.get_fraction()
return settings.faction
end
local function get_particle_cap()
return settings.max_particles_per_second * (settings.faction + 0.1)
end
---Returns whether or not more particles may be spawned, scale minimum is 0.1
local function may_spawn_particles()
return settings.particles_spawned_buffer < get_particle_cap()
end
--- resets the amount of particles in the past second so new ones may spawn
Event.on_nth_tick(63, function ()
settings.particles_spawned_buffer = 0
end)
Command.add('particle-scale', {
description = 'Provide a fraction between 0 and 1 to lower or increase the amount of (max) particles. Leave empty to view the current values.',
arguments = {'fraction'},
default_values = {fraction = false},
admin_only = true,
allowed_by_server = true,
}, function (arguments, player)
local p = player and player.print or print
local fraction = arguments.fraction
if fraction ~= false then
local scale = tonumber(fraction)
if scale == nil or scale < 0 or scale > 1 then
p('Scale must be a valid number ranging from 0 to 1')
return
end
CreateParticles.set_fraction(scale)
end
p(format('Particle fraction: %.2f', CreateParticles.get_fraction()))
p(format('Particles per second: %d', get_particle_cap()))
end)
---Scales the count to round the fraction up. Always returns at least 1 unless the particle limit is reached.
---Useful for particle spawning that influences gameplay for visual indications.
---@param count number
local function scale_ceil(count)
if not may_spawn_particles() then
return 0
end
local scale = settings.faction
if scale == 0 then
return 1
end
if scale < 1 and count > 1 then
count = ceil(count * scale)
end
return count
end
---Scales the count to round the fraction down.
---Useful for particle spawning that doesn't influence gameplay.
---@param count number
local function scale_floor(count)
local scale = settings.faction
if scale == 0 then
return 0
end
if not may_spawn_particles() then
return 0
end
if scale < 1 then
count = floor(count * scale)
end
return count
end
local on_play_particle = Token.register(function (params)
params.surface.create_entity(params.prototype)
end)
@ -25,7 +133,8 @@ end
---@param particle_count number particle count to spawn
---@param position Position
function CreateParticles.destroy_rock(create_entity, particle_count, position)
for _ = particle_count, 1, -1 do
for _ = scale_floor(particle_count), 1, -1 do
settings.particles_spawned_buffer = settings.particles_spawned_buffer + 1
create_entity({
position = position,
name = 'stone-particle',
@ -57,7 +166,8 @@ end
---@param particle_count number particle count to spawn
---@param position Position
function CreateParticles.mine_rock(create_entity, particle_count, position)
for _ = particle_count, 1, -1 do
for _ = scale_floor(particle_count), 1, -1 do
settings.particles_spawned_buffer = settings.particles_spawned_buffer + 1
create_entity({
position = position,
name = 'stone-particle',
@ -92,14 +202,23 @@ function CreateParticles.ceiling_crumble(surface, position)
local sequences = {}
local x = position.x
local y = position.y
local smoke_scale = scale_ceil(2)
local stone_scale = scale_floor(4)
for i = 1, 2 do
-- pre-calculate how many particles will be spawned. Prevents spawning too many particles over ticks.
local particles = settings.particles_spawned_buffer
for i = 1, smoke_scale do
particles = particles + 1
sequences[i] = {frame = i*random(1,15), prototype = create_ceiling_prototype('explosion-remnants-particle', x, y)}
end
for i = 3, 6 do
for i = smoke_scale + 1, smoke_scale + stone_scale do
particles = particles + 1
sequences[i] = {frame = i*random(1,15), prototype = create_ceiling_prototype('stone-particle', x, y)}
end
settings.particles_spawned_buffer = particles
play_particle_sequence(surface, sequences)
end

View File

@ -163,7 +163,7 @@ function Command.add(command_name, options, callback)
end
end
if not parameter then
if parameter == nil then
insert(errors, format('Argument %s from command %s is missing.', argument, command_name))
else
named_arguments[argument] = parameter