--[[ This file is part of Ice Lua Components. Ice Lua Components is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Ice Lua Components is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Ice Lua Components. If not, see . ]] particles = {head = 1, tail = 0} function particles_add(particle) particles.tail = particles.tail + 1 particles[particles.tail] = particle end function particles_prune(sec_current) local i --print("sharticles", particles.head, particles.tail) for i=particles.head,particles.tail do if particles[i] and particles[i].dead then particles[i] = nil end if not particles[i] then if i == particles.head then particles.head = particles.head + 1 end end end if particles.head > particles.tail then particles.head = 1 particles.tail = 0 end end function new_particle_model(r, g, b, size) local mdl_particle = common.model_new(1) local mdl_particle_bone , mdl_particle_tab = 0, nil mdl_particle, mdl_particle_bone = common.model_bone_new(mdl_particle, 1), 0 mdl_particle_tab = {{ x = 0, y = 0, z = 0, radius = size or 1, r = r, g = g, b = b, }} common.model_bone_set(mdl_particle, mdl_particle_bone, "particle", mdl_particle_tab) return mdl_particle end function new_particle(settings) local this = { x = settings.x or 0, y = settings.y or 0, z = settings.z or 0, x0 = settings.x or 0, y0 = settings.y or 0, z0 = settings.z or 0, x1 = settings.x or 0, y1 = settings.y or 0, z1 = settings.z or 0, vx = settings.vx or 0, vy = settings.vy or 0, vz = settings.vz or 0, r = settings.r or 255, g = settings.g or 255, b = settings.b or 255, size = settings.size or 32, lifetime = settings.lifetime or 5, trem = 0, dead = false, step = settings.step or 0.1, adamp = settings.adamp or 0.5, bdamp = settings.bdamp or 1, model = settings.model or nil, free_model = settings.free_model or false, ry = settings.ry or 0, rx = settings.rx or 0, ry2 = settings.ry2 or 0, vry = settings.vry or 0, vrx = settings.vrx or 0, vry2 = settings.vry2 or 0, noclip = settings.noclip } this.this = this local mdl_particle = this.model or common.model_new(1) local mdl_particle_bone , mdl_particle_tab = 0, nil if not this.model then mdl_particle, mdl_particle_bone = common.model_bone_new(mdl_particle, 1), 0 mdl_particle_tab = {{ x = 0, y = 0, z = 0, radius = this.size, r = this.r, g = this.g, b = this.b }} common.model_bone_set(mdl_particle, mdl_particle_bone, "particle", mdl_particle_tab) end local function prv_advance() local d,x1,y1,z1,x2,y2,z2 this.x0 = this.x1 this.y0 = this.y1 this.z0 = this.z1 local db = math.sqrt(this.vx*this.vx+this.vy*this.vy+this.vz*this.vz) --print("a",this.x0,this.y0,this.z0,this.vx,this.vy,this.vz) --print("db",db) if not this.noclip then d,x1,y1,z1,x2,y2,z2 = trace_map_ray_dist( this.x0,this.y0,this.z0, this.vx/db,this.vy/db,this.vz/db, db) end local df = 1.0 if d and not this.noclip then df = math.max(0,d/db-0.001) --print("df",df,d,db) end this.x1 = this.x0 + this.vx*df this.y1 = this.y0 + this.vy*df this.z1 = this.z0 + this.vz*df if x1 then if not this.noclip then if x1 ~= x2 then this.vx = -this.vx*this.bdamp end if y1 ~= y2 then this.vy = -this.vy*this.bdamp end if z1 ~= z2 then this.vz = -this.vz*this.bdamp end end this.vx = this.vx * this.adamp this.vy = this.vy * this.adamp this.vz = this.vz * this.adamp end this.vy = this.vy + 5*MODE_GRAVITY*this.step*this.step end function this.tick(sec_current, sec_delta) if this.dead then return end this.trem = this.trem - sec_delta local i = 10 while this.trem < 0 do prv_advance() this.trem = this.trem + this.step i = i - 1 if i <= 0 then break end end this.ry = this.ry + sec_delta*this.vry this.rx = this.rx + sec_delta*this.vrx this.ry2 = this.ry2 + sec_delta*this.vry2 local lerp = 1 - this.trem/this.step this.x = this.x1*lerp+this.x0*(1-lerp) this.y = this.y1*lerp+this.y0*(1-lerp) this.z = this.z1*lerp+this.z0*(1-lerp) this.lifetime = this.lifetime - sec_delta if this.lifetime <= 0 then if not this.model then common.model_free(mdl_particle) elseif this.free_model then common.model_free(this.model) end this.model = nil this.dead = true end end function this.render() if this.dead then return end local msize = 1 if this.model then msize = this.size end client.model_render_bone_global( mdl_particle, mdl_particle_bone, this.x, this.y, this.z, this.ry, this.rx, this.ry2, msize ) end return this end