Liberty Unleashed

Scripting => Script Snippets => Topic started by: sasha19323 on August 31, 2014, 03:06:03 pm

Title: Pseudo 3D sound
Post by: sasha19323 on August 31, 2014, 03:06:03 pm
This script would be good for Survival/RP gamemodes. You can create it via server(e.g CallClientFunc(plr, null, "PosSound", "track.mp3", Vector(0,0,0), 50); ) or via client(onScriptLoad event or commands). Don't forget to add the sounds in your script.xml file.
Code: ("Client-side script") [Select]
pSounds <- [];

const MAX_RADIUS = 127; //maximal volume
class PosSound
{
  constructor(name, pos, r)
  {
    Pos = pos;
    Name = name;
    Radius = r;
    Sound = ::FindSound(name);
    if (Sound)
    {
      Sound.Open();
      ::pSounds.push(this);
    }
    else
      this.clear();
  }

  function Play()
  {
    if (Sound)
    {
      if (IsPlaying == false)
      {
        Sound.Play();
        IsPlaying = true;
      }
    }
  }
  function Stop()
  {
    if (Sound)
    {
      if (IsPlaying == true)
      {
        Sound.Stop();
        IsPlaying = false;
      }
    }
  }
  function Pause()
  {
    if (Sound)
    {
      if (IsPlaying == true)
      {
        Sound.Pause();
        IsPlaying = false;
      }
    }
  }

  Name = "";
  Pos = Vector(0,0,0);
  Radius = 127;
  Sound = null;
  IsPlaying = false;
}

pPlayer <- FindLocalPlayer();
function onClientRender()
{
  for (local i = 0; i < pSounds.len(); i++)
  {
    local dist = GetDistance(pPlayer.Pos, pSounds[i].Pos).tointeger();
    if (dist <= pSounds[i].Radius)
    {
      pSounds[i].Sound.SetVolume(MAX_RADIUS/pSounds[i].Radius*(pSounds[i].Radius-dist));
      if (!pSounds[i].IsPlaying)
        pSounds[i].Play();
    }
    else
    {
      if (pSounds[i].IsPlaying)
        pSounds[i].Sound.SetVolume(0); //Pause doesn't work properly, so just setting volume to 0
    }
  }

  return 1;
}
PS: Video later today  ;)
Title: Re: Pseudo 3D sound
Post by: Ankris on August 11, 2016, 07:02:49 pm
*bump*

Code: [Select]
pSounds <- [];

const MAX_RADIUS = 127; //maximal volume
class PosSound
{
  constructor(name, pos, r, ...)
  {
    Pos = pos;
    Name = name;
    Radius = r;
    Sound = ::FindSound(name);

    if (vargv.len() >= 2) {
      Loop = vargv[0];
      Duration = vargv[1];
    }

    if (Sound)
    {
      Sound.Open();
      ::pSounds.push(this);
    }
    else
      this.clear();
  }

  function Play()
  {
    if (Sound)
    {
      Ticks = ::GetTickCount();

      if (IsPlaying == false)
      {
        Sound.Play();
        IsPlaying = true;
      }
    }
  }

  function Reset()
  {
    if (Sound)
    {
      Sound.Close();
      Sound.Open();

      IsPlaying = false;
    }
  }

  function Stop()
  {
    if (Sound)
    {
      if (IsPlaying == true)
      {
        Sound.Stop();
        IsPlaying = false;
      }
    }
  }
  function Pause()
  {
    if (Sound)
    {
      if (IsPlaying == true)
      {
        Sound.Pause();
        IsPlaying = false;
      }
    }
  }

  Name = "";
  Pos = Vector(0,0,0);
  Radius = 127;
  Sound = null;
  IsPlaying = false;
  Loop = false;
  Ticks = 0;
  Duration = 0;
}

pPlayer <- FindLocalPlayer();
function onClientRender()
{
  for (local i = 0; i < pSounds.len(); i++)
  {
    local dist = GetDistance(pPlayer.Pos, pSounds[i].Pos).tointeger();
    if (dist <= pSounds[i].Radius)
    {
      pSounds[i].Sound.SetVolume(MAX_RADIUS/pSounds[i].Radius*(pSounds[i].Radius-dist));
      if (!pSounds[i].IsPlaying)
        pSounds[i].Play();
      else {
        if ((GetTickCount()-pSounds[i].Ticks) >= (pSounds[i].Duration*1000) && pSounds[i].Loop) {
          pSounds[i].Reset();
          pSounds[i].Play();
        }
      }
    }
    else
    {
      if (pSounds[i].IsPlaying)
        pSounds[i].Sound.SetVolume(0); //Pause doesn't work properly, so just setting volume to 0
    }
  }

  return 1;
}

Just a little new parameter: sound infinite looping.

Usage: PosSound(char* "sound.wav", Vector3 Vector(0, 0, 0), float radius, bool loop, int duration);