-- LUA Script - precede every function and global member with lowercase name of script + '_main' local U = require "scriptbank\\utillib" local Q = require "scriptbank\\quatlib" local rad = math.rad local deg = math.deg local abs = math.abs local atan = math.atan2 local modf = math.modf local sqrt = math.sqrt local notes = {} local namedEmitter = { notes = { animSpd = 0, SR = 0, freq = -1, lifeMin = 0, lifeMax = 0, -- minX minY minZ maxX maxY maxZ offset = { 0, 0, 0, 0, 0, 0 }, speed = { 0, 0, 0, 0, 0, 0 }, rotate = { 0, 0 }, -- currently only Z rotate processed -- startMin startMax endMin endMax scale = { 10, 10, 10, 10 }, alpha = { 100, 100, 100, 100 } } } -- caller must load image local function PE_CreateNamedEmitter( name, image, frames, object ) image = image or 1 -- default to smoke frames = frames or 64 local et = namedEmitter[ name ] if et == nil then return end local emitter = ParticlesGetFreeEmitter() if emitter == -1 then return end local pos, spd, scl = et.offset, et.speed, et.scale if object == nil then ParticlesAddEmitterEx( emitter, et.animSpd, et.SR, pos[1], pos[2], pos[3], pos[4], pos[5], pos[6], scl[1], scl[2], scl[3], scl[4], spd[1], spd[2], spd[3], spd[4], spd[5], spd[6], et.rotate[1], et.rotate[2], et.lifeMin, et.lifeMax, et.alpha[1], et.alpha[2], et.alpha[3], et.alpha[4], et.freq, 0, 0, image, frames ) else ParticlesAddEmitterEx( emitter, et.animSpd, et.SR, pos[1], pos[2], pos[3], pos[4], pos[5], pos[6], scl[1], scl[2], scl[3], scl[4], spd[1], spd[2], spd[3], spd[4], spd[5], spd[6], et.rotate[1], et.rotate[2], et.lifeMin, et.lifeMax, et.alpha[1], et.alpha[2], et.alpha[3], et.alpha[4], et.freq, object, 0, image, frames ) end return emitter end function notes_with_particles_init( e ) Include( "utillib.lua" ) Include( "quatlib.lua" ) local Ent = g_Entity[ e ] notes[ e ] = { state = 'notseen', number = Ent.health, obj = Ent.obj } SetEntityHealth( e, 1000000 ) end local noteFile = noteFile or ParticlesLoadImage( "effectbank\\particles\\notes.png", 10 ) local emitter = emitter or nil local q90x = Q.FromEuler( rad( 90 ), 0, 0 ) function notes_with_particles_main(e) if emitter == nil then emitter = { state = 'idle' } return end if emitter.state == 'idle' then if emitter.id ~= nil then ParticlesDeleteEmitter( emitter.id ) emitter.id = nil end emitter.state = 'init' elseif emitter.state == 'init' then emitter.id = PE_CreateNamedEmitter( 'notes', noteFile, 16 ) ParticlesSetLife( emitter.id, -1, 300000, 300000, 100, 0, 1 ) emitter.state = 'ready' end if emitter.state ~= 'ready' then return end -- emitter is ready so now we can process the note itself local note = notes[ e ] if note == nil then return end --PromptLocal( e, emitter.state .. "," .. note.state ) if note.state == 'notseen' then if U.PlayerLookingNear( e, 40, 20 ) then Prompt( "Press E to read note" ) if g_KeyPressE == 0 then return end local x, y, z, xA, yA, zA = GetObjectPosAng( note.obj ) local frame = note.number - 1 ParticlesSetFrames( emitter.id, 1, frame, frame ) local quat = Q.FromEuler( rad( xA ), rad( yA ), rad( zA ) ) local nxa, nya, nza = Q.ToEuler( Q.Mul( quat, q90x ) ) ParticlesSetAngle( emitter.id, deg( nxa ), deg( nya ), deg( nza ) ) local xo, yo, zo = U.Rotate3D( 0, 0.2, 0, xA, yA, zA ) ParticlesSpawnParticle( emitter.id, x + xo, y + yo, z + zo ) note.state = 'seen' end end end