-- LUA Script - precede every function and global member with lowercase name of script + '_main' -- Player Enters Sound Zone local U = require "scriptbank\\utillib" local sqrt = math.sqrt local drips = {} function dripwithecho_init_name( e, name ) Include( "utillib.lua" ) --Hide( e ) CollisionOff( e ) if name == 'main' then drips[ e ] = { typ = 'main', state = 'init' } else drips[ e ] = { typ = 'echo', state = 'init' } end end local soundDist = 1500 local echoDist = 3000 local maxSqDist = soundDist * soundDist local sndSpeed = 5 -- 13.5 local dripRate = 4000 local function getDist( pos1, pos2 ) local DX, DY, DZ = pos1.x - pos2.x, pos1.y - pos2.y, pos1.z - pos2.z return sqrt( DX*DX + DY*DY + DZ*DZ ) end local function getVolume( pos1, pos2 ) local DX, DY, DZ = pos1.x - pos2.x, pos1.y - pos2.y, pos1.z - pos2.z local sQdist = DX*DX + DY*DY + DZ*DZ return 60 + ( 40 * ( maxSqDist - sQdist ) / maxSqDist ) end local function calcEchoTime( dp, ep, pp ) local a, b, c = getDist( dp, ep ), getDist( ep, pp ), getDist( dp, pp ) return ( a + b - c ) / sndSpeed end local function makeEcho( t, pos, pp, dp ) for k, v in pairs( drips ) do if v.typ == 'echo' and v.state == 'idle' then PositionObject( v.obj, pos.x, pos.y, pos.z ) v.state = 'echo' v.timer = t + calcEchoTime( dp, pos, pp ) v.pos = pos break end end end local rayCast = IntersectAll local getColX = GetIntersectCollisionX local getColY = GetIntersectCollisionY local getColZ = GetIntersectCollisionZ local function getColPos() return { x = getColX(), y = getColY(), z = getColZ() } end local directionList = { { x = 0, z = 1 }, -- N { x = 1, z = 0 }, -- E { x = 0, z = -1 }, -- S { x = -1, z = 0 } -- W } local function checkForEchoPoints( pos, ignObj ) local echoList = {} for _, v in pairs( directionList ) do local ox, oy, oz = v.x * echoDist, 60, v.z * echoDist local ex, ey, ez = pos.x + ox, pos.y + oy, pos.z + oz local obj = rayCast( pos.x, pos.y, pos.z, ex, ey, ez, ignObj ) if obj and obj ~= 0 then echoList[ #echoList + 1 ] = getColPos() end end return echoList end function dripwithecho_main( e ) local drip = drips[ e ] if drip == nil then return end local timeNow = g_Time local Ent = g_Entity[ e ] if drip.state == 'init' then drip.state = 'idle' drip.pos = { x = Ent.x, y = Ent.y, z = Ent.z } drip.timer = 0 drip.obj = Ent.obj elseif drip.state == 'idle' then if drip.typ == 'main' then if U.PlayerCloserThan( e, soundDist ) then GetEntityPlayerVisibility( e ) if Ent.plrvisible == 1 then local pp = { x = g_PlayerPosX, y = g_PlayerPosY + 30, z = g_PlayerPosZ } if timeNow > drip.timer then PlaySound( e, 0 ) SetSound( e, 0 ) SetSoundVolume( getVolume( drip.pos, pp ) ) drip.timer = timeNow + dripRate local el = checkForEchoPoints( drip.pos, drip.obj ) for _, v in pairs( el ) do makeEcho( timeNow, v, pp, drip.pos ) end end end end end elseif drip.state == 'echo' then if timeNow > drip.timer then PlaySound( e, 0 ) SetSound( e, 0 ) SetSoundVolume( getVolume( drip.pos, { x = g_PlayerPosX, y = g_PlayerPosY + 30, z = g_PlayerPosZ } ) - 15 ) drip.state = 'idle' end end PromptLocal( e, drip.state .. "," .. Ent.plrvisible ) end