-
Notifications
You must be signed in to change notification settings - Fork 3
API
Playing audio clips is simple. All you need is your own AudioHandler
instance.
using LabExtended.API.Audio;
public void CreateHandler()
{
// Retrieves our AudioHandler (if we've already created one)
// OR creates a new one (in which case the delegate in the second parameter is called)
AudioHandler handler = AudioManager.GetOrAddHandler("ExampleHandler", handler =>
{
// Adds an AudioPlayer instance to your AudioHandler instance.
handler.AddPlayer();
// Adds a SpeakerToy instance to your AudioHandler instance.
// The first parameter is the name of the SpeakerToy, used only in the AudioHandler.
// The second parameter is the controller ID of the SpeakerToy, which is used when sending audio to players.
// - Assigning the same ID to multiple speakers results in the same audio playing from all speakers with this ID.
handler.EnsureSpeaker("ExampleSpeaker", 1);
});
// Lets also load the clip that we want to play.
// It's important to use the same name as the file in the method's first argument (this includes any extensions).
KeyValuePair<string, byte[]> clip = AudioManager.GetClip("ExampleClip");
}
// This is called every time a player sends a voice chat packet to the server.
public void OnSpeaking(PlayerSendingVoiceChatMessageEventArgs args)
{
// You should save your AudioHandler instance as a field or a property, this event is called A LOT
if (!AudioManager.TryGetHandler("ExampleHandler", out var handler))
return;
// Since this is a LabAPI events and not a custom LabExtended event, we need to cast the LabAPI player instance
// into our custom subtype ExPlayer instance.
if (args.Speaker is not ExPlayer speaker)
return;
// This will send the voice chat message through each speaker you defined in your AudioHandler.
handler.Transmit(args.Messsage.Data, args.Message.DataLength);
// This will send the voice chat message through each speaker to players that are within 20 meters of the speaking player.
handler.Transmit(args.Messsage.Data, args.Message.DataLength, player => player.Position.DistanceTo(speaker) <= 20f);
}
public void PlayClip()
{
// Will return false if no AudioHandler with name "ExampleHandler" is found.
if (!AudioManager.TryGetHandler("ExampleHandler", out var handler))
return;
// Will return false if no audio clip file with name "ExampleClip" is found.
if (!AudioManager.TryGetClip("ExampleClip", out var clip))
return;
// Will start playing the audio clip (or put it into the queue if something is playing)
// Audio of the clip will be sent through each speaker ID defined in your AudioHandler.
handler.Player.Play(clip, false);
// You can also start playback of an audio clip at a specific location.
handler.PlayAt(clip, Vector3.zero);
// OR you can start playback of an audio clip with a specific Transform!
handler.PlayOn(clip, ExPlayer.Players.RandomItem().CameraTransform);
}
LabExtended adds some custom collections, mostly for the purpose of optimization and convenience.
This is just a normal List<T>
from System.Collections.Generic
, the only difference is that ALL "safety" mechanisms have been removed, which means
- If you remove an item while enumerating the list, no exceptions will be thrown BUT you may skip some items.
This collection (a subtype of UnsafeList<T>
) calls an update method on each element every frame with a configurable delay.
Each element must be a subtype of the IUpdateableElement
interface.
The SwitchContainer
class is used to configure custom player functions, which range from changing Remote Admin visibility to to the ability to configure position synchronization.
- Commands can be used to change values of these switches.
- Custom Ammo is stored in a very simple way, as a developer you only need to respect ammo IDs of other plugins (ammo ID is stored as a 16-bit unsigned integer!)
- Commands can also be used to list and manage custom ammo.
public void AddAmmo(ExPlayer player)
{
// This will add 500 bullets of ammo with the ID 10
player.Inventory.CustomAmmo.Add(10, 500);
}
LabExtended provides a very basic API for Custom Effects.
- Custom Effects do not have a name nor an ID
- Instead, they are listed by their type name.
- Custom Effects are stored in the
EffectContainer
class. - Custom Effects are automatically registered by the loader (unless you specify a
LoaderIgnore
attribute).- To manually register a Custom Effect, just add the effect's type to the
CustomPlayerEffect.Effects
list.
- To manually register a Custom Effect, just add the effect's type to the
- Custom Effects have a separate instance for every player, hence why registration uses only the type.
- Custom Effects can also be managed by commands.
The structure of a Custom Effect class shoud look like this:
public class BoostEffect : CustomPlayerEffect
{
// You can also override methods like Start() to initialize your Custom Effect, but for the sake of simplicity we'll just apply it.
// This method is called once something calls the effect's Enable() method.
public override void ApplyEffects()
{
// This will set the intensity of the MovementBoost effect to 255.
Player.Effects.MovementBoost.Intensity = 255;
}
// This method is called once something calls the effect's Disable() method.
public override void RemoveEffects()
{
// This will set the intensity of the MovementBoost effect to 0.
Player.Effects.MovementBoost.Intensity = 0;
}
}
public void ActivateBoost(ExPlayer player)
{
// Attempts to find a previously registered Custom Effect by it's type, in this case BoostEffect.
if (player.Effects.TryGetCustomEffect<BoostEffect>(out var boostEffect))
{
// Enables our custom effect by calling it's ApplyEffects() method.
boostEffect.Enable();
}
}
// You can disable the effect in the same way.
public void DisableBoost(ExPlayer player)
{
// Attempts to find a previously registered Custom Effect by it's type, in this case BoostEffect.
if (player.Effects.TryGetCustomEffect<BoostEffect>(out var boostEffect))
{
// Disables our custom effect by calling it's RemoveEffects() method.
boostEffect.Disable();
}
}
If you need your Custom Effect to update every frame, you can use the CustomTickingEffect
subtype.
- This class provides an overridable
Tick()
method - You can also set a custom delay (in seconds) between each
Tick()
method call by overriding theDelay
property.
If you want a duration for your Custom Effect, you can use the CustomDurationEffect
subtype.
- This class provides an overridable
GetDuration()
method, in which you should calculate the effect's duration in seconds. -
CheckDuration()
method is called every time before the effect ends in case you need to add duration. -
RemainingDuration
can be used to check the effect's remaining duration (in seconds).
This wiki may be incomplete or outdated! Sorry for that, but this project is mostly a one-man show.