Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,382 @@
----------------------------------------------------------------------------------------------------
--
-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-- its licensors.
--
-- For complete copyright and license terms please see the LICENSE at the root of this
-- distribution (the "License"). All use of this software is governed by the License,
-- or, if provided, by the license below or the license accompanying this file. Do not
-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--
--
----------------------------------------------------------------------------------------------------
-- audio area ambience entity - to be attached to an area
-- used for convenient implementation of area based audio ambiences
AudioAreaAmbience = {
type = "AudioAreaAmbience",
Editor = {
Model = "Editor/Objects/Sound.cgf",
Icon = "AudioAreaAmbience.bmp",
},
Properties = {
bEnabled = true,
audioTriggerPlayTrigger = "",
audioTriggerStopTrigger = "",
audioRTPCRtpc = "",
audioEnvironmentEnvironment = "",
eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE,
fRtpcDistance = 5.0,
fEnvironmentDistance = 5.0,
},
fFadeValue = 0.0,
nState = 0, -- 0 = far, 1 = near, 2 = inside
fFadeOnUnregister = 1.0,
hOnTriggerID = nil,
hOffTriggerID = nil,
hCurrentOnTriggerID = nil,
hCurrentOffTriggerID = nil, -- only used in OnPropertyChange()
hRtpcID = nil,
hEnvironmentID = nil,
tObstructionType = {},
bIsHidden = false,
bIsPlaying = false,
bOriginalEnabled = true,
}
----------------------------------------------------------------------------------------
function AudioAreaAmbience:_LookupControlIDs()
self.hOnTriggerID = AudioUtils.LookupTriggerID(self.Properties.audioTriggerPlayTrigger);
self.hOffTriggerID = AudioUtils.LookupTriggerID(self.Properties.audioTriggerStopTrigger);
self.hRtpcID = AudioUtils.LookupRtpcID(self.Properties.audioRTPCRtpc);
self.hEnvironmentID = AudioUtils.LookupAudioEnvironmentID(self.Properties.audioEnvironmentEnvironment);
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:_LookupObstructionSwitchIDs()
-- cache the obstruction switch and state IDs
self.tObstructionType = AudioUtils.LookupObstructionSwitchAndStates();
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:_SetObstruction()
local nStateIdx = self.Properties.eiSoundObstructionType + 1;
self:SetAudioObstructionCalcType(self.Properties.eiSoundObstructionType, self:GetDefaultAuxAudioProxyID());
if ((self.tObstructionType.hSwitchID ~= nil) and (self.tObstructionType.tStateIDs[nStateIdx] ~= nil)) then
self:SetAudioSwitchState(self.tObstructionType.hSwitchID, self.tObstructionType.tStateIDs[nStateIdx], self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:_DisableObstruction()
-- Ignore is at index 1 (because Lua uses 1-based indexing)
local nStateIdx = 1;
self:SetAudioObstructionCalcType(AUDIO_OBSTRUCTION_TYPE_IGNORE, self:GetDefaultAuxAudioProxyID());
if ((self.tObstructionType.hSwitchID ~= nil) and (self.tObstructionType.tStateIDs[nStateIdx] ~= nil)) then
self:SetAudioSwitchState(self.tObstructionType.hSwitchID, self.tObstructionType.tStateIDs[nStateIdx], self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:_UpdateParameters()
-- Set the distances as the very first thing!
self:SetFadeDistance(self.Properties.fRtpcDistance);
self:SetEnvironmentFadeDistance(self.Properties.fEnvironmentDistance);
if (self.Properties.bEnabled) then
if (self.hEnvironmentID ~= nil) then
self:SetAudioEnvironmentID(self.hEnvironmentID);
end
else
self:SetAudioEnvironmentID(INVALID_AUDIO_ENVIRONMENT_ID);
end
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:_UpdateRtpc()
if (self.hRtpcID ~= nil) then
self:SetAudioRtpcValue(self.hRtpcID, self.fFadeValue, self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:OnSpawn()
self:SetFlags(ENTITY_FLAG_CLIENT_ONLY, 0);
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:OnLoad(load)
self.Properties = load.Properties;
self.fFadeValue = load.fFadeValue;
self.fFadeOnUnregister = load.fFadeOnUnregister;
self.nState = 0; -- We start out being far, in a subsequent update we will determine our actual state!
self:_SetObstruction();
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:OnPostLoad()
self:_UpdateParameters();
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:OnSave(save)
save.Properties = self.Properties;
save.fFadeValue = self.fFadeValue;
save.fFadeOnUnregister = self.fFadeOnUnregister;
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:OnPropertyChange()
if (self.Properties.eiSoundObstructionType < AUDIO_OBSTRUCTION_TYPE_IGNORE) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE;
elseif (self.Properties.eiSoundObstructionType > AUDIO_OBSTRUCTION_TYPE_MULTI) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_MULTI;
end
self:_LookupControlIDs();
self:_UpdateParameters();
self:ResetAudioRtpcValues(self:GetDefaultAuxAudioProxyID());
self:SetCurrentAudioEnvironments();
self:SetAudioProxyOffset(g_Vectors.v000, self:GetDefaultAuxAudioProxyID());
if (self.nState == 1) then -- near
self:_SetObstruction();
elseif (self.nState == 2) then -- inside
self:_DisableObstruction();
end
if ((self.bIsPlaying) and (self.hCurrentOnTriggerID ~= self.hOnTriggerID)) then
-- Stop a possibly playing instance if the on-trigger changed!
self:StopAudioTrigger(self.hCurrentOnTriggerID, self:GetDefaultAuxAudioProxyID());
self.hCurrentOnTriggerID = self.hOnTriggerID;
self.bIsPlaying = false;
self.bHasMoved = false;
end
if (not self.bIsPlaying) then
-- Try to play, if disabled, hidden or invalid on-trigger Play() will fail!
self:Play();
end
if (not self.Properties.bEnabled and ((self.bOriginalEnabled) or (self.hCurrentOffTriggerID ~= self.hOffTriggerID))) then
self.hCurrentOffTriggerID = self.hOffTriggerID;
self:Stop(); -- stop if disabled, either stops running StartTrigger or executes StopTrigger!
end
self.bOriginalEnabled = self.Properties.bEnabled;
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:OnReset(bToGame)
if (bToGame) then
-- store the entity's "bEnabled" property's value so we can adjust back to it if changed over the course of the game
self.bOriginalEnabled = self.Properties.bEnabled;
-- re-execute this AAA once upon entering game mode
self:Stop();
self:Play();
else
self.Properties.bEnabled = self.bOriginalEnabled;
end
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:Play()
if ((self.Properties.bEnabled) and (not self.bIsHidden) and ((self.nState == 1) or (self.nState == 2))) then
if (self.hOnTriggerID ~= nil) then
self:SetCurrentAudioEnvironments();
self:ExecuteAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
self.bIsPlaying = true;
self.hCurrentOnTriggerID = self.hOnTriggerID;
end
end
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:Stop()
if ((self.Properties.bEnabled) and (not self.bIsHidden) and ((self.nState == 1) or (self.nState == 2))) then
-- cannot check against "self.bIsPlaying" otherwise we won't execute the StopTrigger if there's no StartTrigger set!
if (self.hOffTriggerID ~= nil) then
self:ExecuteAudioTrigger(self.hOffTriggerID, self:GetDefaultAuxAudioProxyID());
elseif (self.hOnTriggerID ~= nil) then
self:StopAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
end
end
self.bIsPlaying = false;
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:StopAll()
if (self.hOnTriggerID ~= nil) then
self:StopAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
end
if (self.hOffTriggerID ~= nil) then
self:StopAudioTrigger(self.hOffTriggerID, self:GetDefaultAuxAudioProxyID());
end
self.bIsPlaying = false;
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:CliSrv_OnInit()
self.nState = 0;
self.fFadeValue = 0.0;
self.fFadeOnUnregister = 1.0;
self:SetFlags(ENTITY_FLAG_VOLUME_SOUND, 0);
self:_UpdateParameters();
self.bIsPlaying = false;
self:NetPresent(0);
end
----------------------------------------------------------------------------------------
function AudioAreaAmbience:UpdateFadeValue(player, fFade, fDistSq)
if (not(self.Properties.bEnabled) or (fFade == 0.0 and fDistSq == 0.0)) then
self.fFadeValue = 0.0;
self:_UpdateRtpc();
do return end;
end
if (self.Properties.fRtpcDistance > 0.0) then
if (self.nState == 2) then
if (self.fFadeValue ~= fFade) then
self.fFadeValue = math.abs(fFade);
self:_UpdateRtpc();
end
else
local fLocalFade = 1.0 - (math.sqrt(fDistSq) / self.Properties.fRtpcDistance);
self.fFadeValue = math.max(0, fLocalFade);
self:_UpdateRtpc();
end
end
end
----------------------------------------------------------------------------------------
AudioAreaAmbience.Server = {
OnInit = function(self)
self:CliSrv_OnInit();
end,
OnShutDown = function(self)
end,
}
----------------------------------------------------------------------------------------
AudioAreaAmbience.Client = {
OnInit = function(self)
self:RegisterForAreaEvents(1);
self:_LookupControlIDs();
self:_LookupObstructionSwitchIDs();
self:_SetObstruction();
self:CliSrv_OnInit();
end,
OnShutDown = function(self)
self:StopAll();
self.nState = 0;
self:RegisterForAreaEvents(0);
end,
OnHidden = function(self)
self:StopAll();
self.bIsHidden = true;
end,
OnUnHidden = function(self)
self.bIsHidden = false;
self:Play();
end,
OnAudioListenerEnterNearArea = function(self, player, nAreaID, fFade)
if (self.nState == 0) then
self.nState = 1;
self:Play();
self.fFadeValue = 0.0;
self:_UpdateRtpc();
end
end,
OnAudioListenerMoveNearArea = function(self, player, areaId, fFade, fDistsq)
self.nState = 1;
self:UpdateFadeValue(player, fFade, fDistsq);
end,
OnAudioListenerEnterArea = function(self, player, areaId, fFade)
if (self.nState == 0) then
-- possible if the listener is teleported or gets spawned inside the area
-- technically, the listener enters the Near Area and the Inside Area at the same time
self.nState = 2;
self:Play();
else
self.nState = 2;
end
self.fFadeValue = 1.0;
self:_UpdateRtpc();
self:_DisableObstruction();
end,
OnAudioListenerProceedFadeArea = function(self, player, areaId, fExternalFade)
-- fExternalFade holds the fade value which was calculated by an inner, higher priority area
-- in the AreaManager to fade out the outer sound dependent on the largest fade distance of all attached entities
if (fExternalFade > 0.0) then
self.nState = 2;
self:UpdateFadeValue(player, fExternalFade, 0.0);
else
self:UpdateFadeValue(player, 0.0, 0.0);
end
end,
OnAudioListenerLeaveArea = function(self, player, nAreaID, fFade)
self.nState = 1;
self:_SetObstruction();
end,
OnAudioListenerLeaveNearArea = function(self, player, nAreaID, fFade)
self:Stop();
self.nState = 0;
self.fFadeValue = 0.0;
self:_UpdateRtpc();
end,
OnUnBindThis = function(self)
self.nState = 0;
end,
OnSoundDone = function(self, hTriggerID)
if (self.hOnTriggerID == hTriggerID) then
self:ActivateOutput("Done", true);
end
end,
}
----------------------------------------------------------------------------------------
-- Event Handlers
----------------------------------------------------------------------------------------
function AudioAreaAmbience:Event_Enable(sender)
self.Properties.bEnabled = true;
self:OnPropertyChange();
end
function AudioAreaAmbience:Event_Disable(sender)
self.Properties.bEnabled = false;
self:OnPropertyChange();
end
AudioAreaAmbience.FlowEvents =
{
Inputs =
{
Enable = { AudioAreaAmbience.Event_Enable, "bool" },
Disable = { AudioAreaAmbience.Event_Disable, "bool" },
},
Outputs =
{
Done = "bool",
},
}
@@ -0,0 +1,265 @@
----------------------------------------------------------------------------------------------------
--
-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-- its licensors.
--
-- For complete copyright and license terms please see the LICENSE at the root of this
-- distribution (the "License"). All use of this software is governed by the License,
-- or, if provided, by the license below or the license accompanying this file. Do not
-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--
--
----------------------------------------------------------------------------------------------------
-- audio area entity - to be attached to an area
-- reports a normalized (0-1) fade value depending on the listener's distance to the area
AudioAreaEntity = {
type = "AudioAreaEntity",
Editor = {
Model = "Editor/Objects/Sound.cgf",
Icon = "AudioAreaEntity.bmp",
},
Properties = {
bEnabled = true,
audioEnvironmentEnvironment = "",
eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE,
fFadeDistance = 5.0,
fEnvironmentDistance = 5.0,
},
fFadeValue = 0.0,
nState = 0, -- 0 = far, 1 = near, 2 = inside
fFadeOnUnregister = 1.0,
hEnvironmentID = nil,
tObstructionType = {},
}
----------------------------------------------------------------------------------------
function AudioAreaEntity:_ActivateOutput(sPortName, value)
if (self.Properties.bEnabled) then
self:ActivateOutput(sPortName, value);
end
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:_UpdateParameters()
-- Set the distances as the very first thing!
self:SetFadeDistance(self.Properties.fFadeDistance);
self:SetEnvironmentFadeDistance(self.Properties.fEnvironmentDistance);
if (self.Properties.bEnabled) then
self.hEnvironmentID = AudioUtils.LookupAudioEnvironmentID(self.Properties.audioEnvironmentEnvironment);
if (self.hEnvironmentID ~= nil) then
self:SetAudioEnvironmentID(self.hEnvironmentID);
end
else
self:SetAudioEnvironmentID(INVALID_AUDIO_ENVIRONMENT_ID);
end
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:_LookupObstructionSwitchIDs()
-- cache the obstruction switch and state IDs
self.tObstructionType = AudioUtils.LookupObstructionSwitchAndStates();
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:_SetObstruction()
local nStateIdx = self.Properties.eiSoundObstructionType + 1;
self:SetAudioObstructionCalcType(self.Properties.eiSoundObstructionType, self:GetDefaultAuxAudioProxyID());
if ((self.tObstructionType.hSwitchID ~= nil) and (self.tObstructionType.tStateIDs[nStateIdx] ~= nil)) then
self:SetAudioSwitchState(self.tObstructionType.hSwitchID, self.tObstructionType.tStateIDs[nStateIdx], self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:OnSpawn()
self:SetFlags(ENTITY_FLAG_CLIENT_ONLY, 0);
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:OnLoad(load)
self.Properties = load.Properties;
self.fFadeOnUnregister = load.fFadeOnUnregister;
self:_SetObstruction();
self.nState = 0;
self.fFadeValue = 0.0;
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:OnPostLoad()
self:_UpdateParameters();
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:OnSave(save)
save.Properties = self.Properties;
save.fFadeOnUnregister = self.fFadeOnUnregister;
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:OnPropertyChange()
self:_UpdateParameters();
if (self.Properties.eiSoundObstructionType < AUDIO_OBSTRUCTION_TYPE_IGNORE) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE;
elseif (self.Properties.eiSoundObstructionType > AUDIO_OBSTRUCTION_TYPE_MULTI) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_MULTI;
end
self:ResetAudioRtpcValues(self:GetDefaultAuxAudioProxyID());
self:_SetObstruction();
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:CliSrv_OnInit()
self.nState = 0;
self.fFadeValue = 0.0;
self.fFadeOnUnregister = 1.0;
self:SetFlags(ENTITY_FLAG_VOLUME_SOUND, 0);
self:_UpdateParameters();
end
----------------------------------------------------------------------------------------
function AudioAreaEntity:UpdateFadeValue(player, fFade, fDistSq)
if (not(self.Properties.bEnabled) or (fFade == 0.0 and fDistSq == 0.0)) then
if (self.fFadeValue ~= 0.0) then
self:_ActivateOutput("FadeValue", 0.0);
end
self.fFadeValue = 0.0;
do return end;
end
if (self.Properties.fFadeDistance > 0.0) then
if (self.nState == 2) then
if (self.fFadeValue ~= fFade) then
self.fFadeValue = math.abs(fFade);
self:_ActivateOutput("FadeValue", self.fFadeValue);
end
else
local fLocalFade = 1.0 - (math.sqrt(fDistSq) / self.Properties.fFadeDistance);
self.fFadeValue = math.max(0, fLocalFade);
self:_ActivateOutput("FadeValue", self.fFadeValue);
end
end
end
----------------------------------------------------------------------------------------
AudioAreaEntity.Server = {
OnInit = function(self)
self:CliSrv_OnInit();
end,
OnShutDown = function(self)
end,
}
----------------------------------------------------------------------------------------
AudioAreaEntity.Client = {
OnInit = function(self)
self:RegisterForAreaEvents(1);
self:_LookupObstructionSwitchIDs();
self:_SetObstruction();
self:CliSrv_OnInit();
end,
OnShutDown = function(self)
self.nState = 0;
self:RegisterForAreaEvents(0);
end,
OnAudioListenerEnterNearArea = function(self, player, nAreaID, fFade)
if (self.nState == 0) then
self:_SetObstruction();
self:_ActivateOutput("OnFarToNear", true);
elseif (self.nState == 2) then
self:_ActivateOutput("OnInsideToNear", true);
end
self.nState = 1;
self.fFadeValue = 0.0;
self:_ActivateOutput("FadeValue", self.fFadeValue);
end,
OnAudioListenerMoveNearArea = function(self, player, areaId, fFade, fDistsq)
self.nState = 1;
self:UpdateFadeValue(player, fFade, fDistsq);
end,
OnAudioListenerEnterArea = function(self, player, areaId, fFade)
if (self.nState == 0) then
-- possible if the listener is teleported or gets spawned inside the area
-- technically, the listener enters the Near Area and the Inside Area at the same time
-- however, in this case the AreaManager is responsible to first call OnEnterNear and then OnEnter so this is technically circumventing a possible bug :)
self:_SetObstruction();
self:_ActivateOutput("OnFarToNear", true);
end
self.nState = 2;
self.fFadeValue = 1.0;
self:_ActivateOutput("OnNearToInside", true);
self:_ActivateOutput("FadeValue", self.fFadeValue);
end,
OnAudioListenerProceedFadeArea = function(self, player, areaId, fExternalFade)
-- fExternalFade holds the fade value which was calculated by an inner, higher priority area
-- in the AreaManager to fade out the outer sound dependent on the largest fade distance of all attached entities
if (fExternalFade > 0.0) then
self.nState = 2;
self:UpdateFadeValue(player, fExternalFade, 0.0);
else
self:UpdateFadeValue(player, 0.0, 0.0);
end
end,
OnAudioListenerLeaveArea = function(self, player, nAreaID, fFade)
self.nState = 1;
self:_ActivateOutput("OnInsideToNear", true);
end,
OnAudioListenerLeaveNearArea = function(self, player, nAreaID, fFade)
self.nState = 0;
self.fFadeValue = 0.0;
self:_ActivateOutput("OnNearToFar", true);
self:_ActivateOutput("FadeValue", self.fFadeValue);
end,
OnUnBindThis = function(self)
self.nState = 0;
end,
}
----------------------------------------------------------------------------------------
-- Event Handlers
----------------------------------------------------------------------------------------
function AudioAreaEntity:Event_Enable(sender)
self.Properties.bEnabled = true;
self:OnPropertyChange();
end
function AudioAreaEntity:Event_Disable(sender)
self.Properties.bEnabled = false;
self:OnPropertyChange();
end
AudioAreaEntity.FlowEvents =
{
Inputs =
{
Enable = { AudioAreaEntity.Event_Enable, "bool" },
Disable = { AudioAreaEntity.Event_Disable, "bool" },
},
Outputs =
{
FadeValue = "float",
OnFarToNear = "bool",
OnNearToInside = "bool",
OnInsideToNear = "bool",
OnNearToFar = "bool",
},
}
@@ -0,0 +1,386 @@
----------------------------------------------------------------------------------------------------
--
-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-- its licensors.
--
-- For complete copyright and license terms please see the LICENSE at the root of this
-- distribution (the "License"). All use of this software is governed by the License,
-- or, if provided, by the license below or the license accompanying this file. Do not
-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--
--
----------------------------------------------------------------------------------------------------
-- audio area ambience entity - to be attached to an area
-- used for convenient implementation of area based audio ambiences
AudioAreaRandom = {
type = "AudioAreaRandom",
Editor = {
Model = "Editor/Objects/Sound.cgf",
Icon = "AudioAreaRandom.bmp",
},
Properties = {
bEnabled = true,
bMoveWithEntity = false,
audioTriggerPlayTrigger = "",
audioTriggerStopTrigger = "",
audioRTPCRtpc = "",
eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE,
fRtpcDistance = 5.0,
fRadiusRandom = 10.0,
fMinDelay = 1,
fMaxDelay = 2,
},
fFadeValue = 0.0,
nState = 0, -- 0 = far, 1 = near, 2 = inside
hOnTriggerID = nil,
hOffTriggerID = nil,
hCurrentOnTriggerID = nil,
hCurrentOffTriggerID = nil, -- only used in OnPropertyChange()
hRtpcID = nil,
tObstructionType = {},
bIsHidden = false,
bIsPlaying = false,
bHasMoved = false,
bOriginalEnabled = true,
}
----------------------------------------------------------------------------------------
function AudioAreaRandom:_LookupControlIDs()
self.hOnTriggerID = AudioUtils.LookupTriggerID(self.Properties.audioTriggerPlayTrigger);
self.hOffTriggerID = AudioUtils.LookupTriggerID(self.Properties.audioTriggerStopTrigger);
self.hRtpcID = AudioUtils.LookupRtpcID(self.Properties.audioRTPCRtpc);
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:_LookupObstructionSwitchIDs()
-- cache the obstruction switch and state IDs
self.tObstructionType = AudioUtils.LookupObstructionSwitchAndStates();
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:_SetObstruction()
local nStateIdx = self.Properties.eiSoundObstructionType + 1;
self:SetAudioObstructionCalcType(self.Properties.eiSoundObstructionType, self:GetDefaultAuxAudioProxyID());
if ((self.tObstructionType.hSwitchID ~= nil) and (self.tObstructionType.tStateIDs[nStateIdx] ~= nil)) then
self:SetAudioSwitchState(self.tObstructionType.hSwitchID, self.tObstructionType.tStateIDs[nStateIdx], self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:_UpdateParameters()
self:SetFadeDistance(self.Properties.fRtpcDistance);
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:_UpdateRtpc()
if (self.hRtpcID ~= nil) then
self:SetAudioRtpcValue(self.hRtpcID, self.fFadeValue, self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:_GenerateOffset()
local offset = {x = 0, y = 0, z = 0}
offset.x = randomF(-1, 1);
offset.y = randomF(-1, 1);
NormalizeVector(offset);
ScaleVectorInPlace(offset, randomF(0, self.Properties.fRadiusRandom));
return offset;
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:OnSpawn()
self:SetFlags(ENTITY_FLAG_CLIENT_ONLY, 0);
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:OnLoad(load)
self.Properties = load.Properties;
self.fFadeValue = load.fFadeValue;
self.nState = 0; -- We start out being far, in a subsequent update we will determine our actual state!
self:_SetObstruction();
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:OnPostLoad()
self:_UpdateParameters();
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:OnSave(save)
save.Properties = self.Properties;
save.fFadeValue = self.fFadeValue;
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:OnPropertyChange()
if (self.Properties.eiSoundObstructionType < AUDIO_OBSTRUCTION_TYPE_IGNORE) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE;
elseif (self.Properties.eiSoundObstructionType > AUDIO_OBSTRUCTION_TYPE_MULTI) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_MULTI;
end
self:_LookupControlIDs();
self:_UpdateParameters();
self:_SetObstruction();
self:ResetAudioRtpcValues(self:GetDefaultAuxAudioProxyID());
self:SetCurrentAudioEnvironments();
self:SetAudioProxyOffset(g_Vectors.v000, self:GetDefaultAuxAudioProxyID());
self:AuxAudioProxiesMoveWithEntity(self.Properties.bMoveWithEntity);
if ((self.bIsPlaying) and (self.hCurrentOnTriggerID ~= self.hOnTriggerID)) then
-- Stop a possibly playing instance if the on-trigger changed!
self:StopAudioTrigger(self.hCurrentOnTriggerID, self:GetDefaultAuxAudioProxyID());
self.hCurrentOnTriggerID = self.hOnTriggerID;
self.bIsPlaying = false;
self.bHasMoved = false;
self:KillTimer(0);
end
if (not self.bIsPlaying) then
-- Try to play, if disabled, hidden or invalid on-trigger Play() will fail!
self:Play();
end
if (not self.Properties.bEnabled and ((self.bOriginalEnabled) or (self.hCurrentOffTriggerID ~= self.hOffTriggerID))) then
self.hCurrentOffTriggerID = self.hOffTriggerID;
self:Stop(); -- stop if disabled, either stops running StartTrigger or executes StopTrigger!
end
self.bOriginalEnabled = self.Properties.bEnabled;
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:OnReset(bToGame)
if (bToGame) then
-- store the entity's "bEnabled" property's value so we can adjust back to it if changed over the course of the game
self.bOriginalEnabled = self.Properties.bEnabled;
-- re-execute this AAR once upon entering game mode
self:Stop();
self:Play();
else
self.Properties.bEnabled = self.bOriginalEnabled;
end
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:Play()
if ((self.Properties.bEnabled) and (not self.bIsHidden) and ((self.nState == 1) or (self.nState == 2))) then
if (self.hOnTriggerID ~= nil) then
local offset = self:_GenerateOffset();
if (LengthSqVector(offset) > 0.00001) then-- offset is longer than 1cm
self:SetAudioProxyOffset(offset, self:GetDefaultAuxAudioProxyID());
self:SetCurrentAudioEnvironments();
elseif (self.bHasMoved) then
self:SetCurrentAudioEnvironments();
end
self:ExecuteAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
self.bIsPlaying = true;
self.bHasMoved = false;
self.hCurrentOnTriggerID = self.hOnTriggerID;
self:SetTimer(0, 1000 * randomF(self.Properties.fMinDelay, self.Properties.fMaxDelay));
end
end
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:Stop()
if ((self.Properties.bEnabled) and (not self.bIsHidden) and ((self.nState == 1) or (self.nState == 2))) then
-- Cannot check against "self.bIsPlaying" otherwise we won't execute the StopTrigger if there's no StartTrigger set!
if (self.hOffTriggerID ~= nil) then
local offset = self:_GenerateOffset();
if (LengthSqVector(offset) > 0.00001) then-- offset is longer than 1cm
self:SetAudioProxyOffset(offset, self:GetDefaultAuxAudioProxyID());
self:SetCurrentAudioEnvironments();
elseif (self.bHasMoved) then
self:SetCurrentAudioEnvironments();
end
self:ExecuteAudioTrigger(self.hOffTriggerID, self:GetDefaultAuxAudioProxyID());
elseif (self.hOnTriggerID ~= nil) then
self:StopAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
end
end
self.bIsPlaying = false;
self.bHasMoved = false;
self:KillTimer(0);
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:StopAll()
if (self.hOnTriggerID ~= nil) then
self:StopAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
end
if (self.hOffTriggerID ~= nil) then
self:StopAudioTrigger(self.hOffTriggerID, self:GetDefaultAuxAudioProxyID());
end
self.bIsPlaying = false;
self:KillTimer(0);
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:CliSrv_OnInit()
self.nState = 0;
self.fFadeValue = 0.0;
self:SetFlags(ENTITY_FLAG_VOLUME_SOUND, 0);
self:_UpdateParameters();
self.bIsPlaying = false;
self:NetPresent(0);
self:AuxAudioProxiesMoveWithEntity(self.Properties.bMoveWithEntity);
end
----------------------------------------------------------------------------------------
function AudioAreaRandom:UpdateFadeValue(player, fFade, fDistSq)
if (not(self.Properties.bEnabled) or (fFade == 0.0 and fDistSq == 0.0)) then
self.fFadeValue = 0.0;
self:_UpdateRtpc();
do return end;
end
if (self.Properties.fRtpcDistance > 0.0) then
if (self.nState == 2) then
if (self.fFadeValue ~= fFade) then
self.fFadeValue = math.abs(fFade);
self:_UpdateRtpc();
end
else
local fLocalFade = 1.0 - (math.sqrt(fDistSq) / self.Properties.fRtpcDistance);
self.fFadeValue = math.max(0, fLocalFade);
self:_UpdateRtpc();
end
end
end
----------------------------------------------------------------------------------------
AudioAreaRandom.Server = {
OnInit = function(self)
self:CliSrv_OnInit();
end,
OnShutDown = function(self)
end,
}
----------------------------------------------------------------------------------------
AudioAreaRandom.Client = {
OnInit = function(self)
self:RegisterForAreaEvents(1);
self:_LookupControlIDs();
self:_LookupObstructionSwitchIDs();
self:_SetObstruction();
self:CliSrv_OnInit();
end,
OnShutDown = function(self)
self:StopAll();
self.nState = 0;
self:RegisterForAreaEvents(0);
end,
OnHidden = function(self)
self:StopAll();
self.bIsHidden = true;
end,
OnUnHidden = function(self)
self.bIsHidden = false;
self:Play();
end,
OnAudioListenerEnterNearArea = function(self, player, nAreaID, fFade)
if (self.nState == 0) then
self.nState = 1;
self:Play();
self.fFadeValue = 0.0;
self:_UpdateRtpc();
end
end,
OnAudioListenerMoveNearArea = function(self, player, areaId, fFade, fDistsq)
self.nState = 1;
self:UpdateFadeValue(player, fFade, fDistsq);
end,
OnAudioListenerEnterArea = function(self, player, areaId, fFade)
if (self.nState == 0) then
-- possible if the listener is teleported or gets spawned inside the area
-- technically, the listener enters the Near Area and the Inside Area at the same time
self.nState = 2;
self:Play();
else
self.nState = 2;
end
self.fFadeValue = 1.0;
self:_UpdateRtpc();
end,
OnAudioListenerProceedFadeArea = function(self, player, areaId, fExternalFade)
-- fExternalFade holds the fade value which was calculated by an inner, higher priority area
-- in the AreaManager to fade out the outer sound dependent on the largest fade distance of all attached entities
if (fExternalFade > 0.0) then
self.nState = 2;
self:UpdateFadeValue(player, fExternalFade, 0.0);
else
self:UpdateFadeValue(player, 0.0, 0.0);
end
end,
OnAudioListenerLeaveArea = function(self, player, nAreaID, fFade)
self.nState = 1;
end,
OnAudioListenerLeaveNearArea = function(self, player, nAreaID, fFade)
self:Stop();
self.nState = 0;
self.fFadeValue = 0.0;
self:_UpdateRtpc();
end,
OnUnBindThis = function(self)
self.nState = 0;
end,
OnTimer = function(self, timerid, msec)
if (timerid == 0) then
self:Play();
end
end,
OnMove = function(self)
self.bHasMoved = true;
end,
}
----------------------------------------------------------------------------------------
-- Event Handlers
----------------------------------------------------------------------------------------
function AudioAreaRandom:Event_Enable(sender)
self.Properties.bEnabled = true;
self:OnPropertyChange();
end
function AudioAreaRandom:Event_Disable(sender)
self.Properties.bEnabled = false;
self:OnPropertyChange();
end
AudioAreaRandom.FlowEvents =
{
Inputs =
{
Enable = { AudioAreaRandom.Event_Enable, "bool" },
Disable = { AudioAreaRandom.Event_Disable, "bool" },
},
}
@@ -0,0 +1,334 @@
----------------------------------------------------------------------------------------------------
--
-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-- its licensors.
--
-- For complete copyright and license terms please see the LICENSE at the root of this
-- distribution (the "License"). All use of this software is governed by the License,
-- or, if provided, by the license below or the license accompanying this file. Do not
-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--
--
----------------------------------------------------------------------------------------------------
Script.ReloadScript("scripts/Entities/Sound/Shared/AudioUtils.lua");
AudioTriggerSpot = {
type = "AudioTriggerSpot",
Editor = {
Model = "Editor/Objects/Sound.cgf",
Icon = "Sound.bmp",
},
Properties = {
bEnabled = true,
audioTriggerPlayTriggerName = "",
audioTriggerStopTriggerName = "",
bSerializePlayState = true, -- Determines if execution after de-serialization is needed.
eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE,
bPlayOnX = false,
bPlayOnY = false,
bPlayOnZ = false,
fRadiusRandom = 10.0,
bPlayRandom = false,
fMinDelay = 1,
fMaxDelay = 2,
},
hOnTriggerID = nil,
hOffTriggerID = nil,
hCurrentOnTriggerID = nil,
hCurrentOffTriggerID = nil, -- only used in OnPropertyChange()
tObstructionType = {},
bIsHidden = false,
bIsPlaying = false,
bHasMoved = false,
bOriginalEnabled = true,
}
----------------------------------------------------------------------------------------
function AudioTriggerSpot:_LookupTriggerIDs()
self.hOnTriggerID = AudioUtils.LookupTriggerID(self.Properties.audioTriggerPlayTriggerName);
self.hOffTriggerID = AudioUtils.LookupTriggerID(self.Properties.audioTriggerStopTriggerName);
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:_LookupObstructionSwitchIDs()
-- cache the obstruction switch and state IDs
self.tObstructionType = AudioUtils.LookupObstructionSwitchAndStates();
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:_SetObstruction()
local nStateIdx = self.Properties.eiSoundObstructionType + 1;
self:SetAudioObstructionCalcType(self.Properties.eiSoundObstructionType, self:GetDefaultAuxAudioProxyID());
if ((self.tObstructionType.hSwitchID ~= nil) and (self.tObstructionType.tStateIDs[nStateIdx] ~= nil)) then
self:SetAudioSwitchState(self.tObstructionType.hSwitchID, self.tObstructionType.tStateIDs[nStateIdx], self:GetDefaultAuxAudioProxyID());
end
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:_GenerateOffset()
local offset = {x=0,y=0,z=0}
local len = 0
if (self.Properties.bPlayOnX) then
offset.x=randomF(-1,1);
end
if (self.Properties.bPlayOnY) then
offset.y=randomF(-1,1);
end
if (self.Properties.bPlayOnZ) then
offset.z=randomF(-1,1);
end
NormalizeVector(offset);
ScaleVectorInPlace(offset, randomF(0,self.Properties.fRadiusRandom));
return offset;
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnSpawn()
self:SetFlags(ENTITY_FLAG_CLIENT_ONLY, 0);
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnSave(save)
save.Properties = self.Properties;
save.bIsPlaying = self.bIsPlaying;
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnLoad(load)
self.Properties = load.Properties;
self.bIsPlaying = load.bIsPlaying;
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnPostLoad()
self:_SetObstruction();
self:SetCurrentAudioEnvironments();
if (self.bIsPlaying and self.Properties.bSerializePlayState) then
self.bIsPlaying = false;
self:Play();
else
self.bIsPlaying = false;
end
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:_Init()
self.bIsPlaying = false;
self:SetAudioProxyOffset(g_Vectors.v000, self:GetDefaultAuxAudioProxyID());
self:NetPresent(0);
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnPropertyChange()
if (self.Properties.eiSoundObstructionType < AUDIO_OBSTRUCTION_TYPE_IGNORE) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_IGNORE;
elseif (self.Properties.eiSoundObstructionType > AUDIO_OBSTRUCTION_TYPE_MULTI) then
self.Properties.eiSoundObstructionType = AUDIO_OBSTRUCTION_TYPE_MULTI;
end
self:_LookupTriggerIDs();
self:_SetObstruction();
self:SetCurrentAudioEnvironments();
self:SetAudioProxyOffset(g_Vectors.v000, self:GetDefaultAuxAudioProxyID());
if ((self.bIsPlaying) and (self.hCurrentOnTriggerID ~= self.hOnTriggerID)) then
-- Stop a possibly playing instance if the on-trigger changed!
self:StopAudioTrigger(self.hCurrentOnTriggerID, self:GetDefaultAuxAudioProxyID());
self.hCurrentOnTriggerID = self.hOnTriggerID;
self.bIsPlaying = false;
self.bHasMoved = false;
self:KillTimer(0);
end
if (not self.bIsPlaying) then
-- Try to play, if disabled, hidden or invalid on-trigger Play() will fail!
self:Play();
end
if (not self.Properties.bEnabled and ((self.bOriginalEnabled) or (self.hCurrentOffTriggerID ~= self.hOffTriggerID))) then
self.hCurrentOffTriggerID = self.hOffTriggerID;
self:Stop(); -- stop if disabled, either stops running StartTrigger or executes StopTrigger!
end
self.bOriginalEnabled = self.Properties.bEnabled;
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnReset(bToGame)
if (bToGame) then
-- store the entity's "bEnabled" property's value so we can adjust back to it if changed over the course of the game
self.bOriginalEnabled = self.Properties.bEnabled;
-- re-execute this ATS once upon entering game mode
self:Stop();
self:Play();
else
self.Properties.bEnabled = self.bOriginalEnabled;
end
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:OnTransformFromEditorDone()
self:SetCurrentAudioEnvironments();
end
----------------------------------------------------------------------------------------
AudioTriggerSpot["Server"] = {
OnInit = function (self)
self:_Init();
end,
OnShutDown = function (self)
end,
}
----------------------------------------------------------------------------------------
AudioTriggerSpot["Client"] = {
----------------------------------------------------------------------------------------
OnInit = function(self)
self:_Init();
self:_LookupTriggerIDs();
self:_LookupObstructionSwitchIDs();
self:_SetObstruction();
self:SetCurrentAudioEnvironments();
self:Play();
end,
----------------------------------------------------------------------------------------
OnShutDown = function(self)
self:StopAll();
end,
----------------------------------------------------------------------------------------
OnSoundDone = function(self, hTriggerID)
if (self.hOnTriggerID == hTriggerID) then
self:ActivateOutput("Done", true);
end
end,
----------------------------------------------------------------------------------------
OnTimer = function(self, timerid, msec)
if (timerid == 0) then
self:Play();
end
end,
----------------------------------------------------------------------------------------
OnHidden = function(self)
self:StopAll();
self.bIsHidden = true;
end,
----------------------------------------------------------------------------------------
OnUnHidden = function(self)
self.bIsHidden = false;
self:Play();
end,
----------------------------------------------------------------------------------------
OnMove = function(self)
self.bHasMoved = true;
end,
}
----------------------------------------------------------------------------------------
function AudioTriggerSpot:Play()
if ((self.hOnTriggerID ~= nil) and (self.Properties.bEnabled) and (not self.bIsHidden)) then
local offset = self:_GenerateOffset();
if (LengthSqVector(offset) > 0.00001) then -- offset is longer than 1cm
self:SetAudioProxyOffset(offset, self:GetDefaultAuxAudioProxyID());
self:SetCurrentAudioEnvironments();
elseif (self.bHasMoved) then
self:SetCurrentAudioEnvironments();
end
self:ExecuteAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
self.bIsPlaying = true;
self.bHasMoved = false;
self.hCurrentOnTriggerID = self.hOnTriggerID;
if (self.Properties.bPlayRandom) then
self:SetTimer(0, 1000 * randomF(self.Properties.fMinDelay, self.Properties.fMaxDelay));
end
end
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:Stop()
if (not self.bIsHidden) then
-- Cannot check against "self.bIsPlaying" otherwise we won't execute the StopTrigger if there's no StartTrigger set!
if (self.hOffTriggerID ~= nil) then
local offset = self:_GenerateOffset();
if (LengthSqVector(offset) > 0.00001) then-- offset is longer than 1cm
self:SetAudioProxyOffset(offset, self:GetDefaultAuxAudioProxyID());
self:SetCurrentAudioEnvironments();
elseif (self.bHasMoved) then
self:SetCurrentAudioEnvironments();
end
self:ExecuteAudioTrigger(self.hOffTriggerID, self:GetDefaultAuxAudioProxyID());
elseif (self.hOnTriggerID ~= nil) then
self:StopAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
end
end
self.bIsPlaying = false;
self.bHasMoved = false;
self:KillTimer(0);
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:StopAll()
if (self.hOnTriggerID ~= nil) then
self:StopAudioTrigger(self.hOnTriggerID, self:GetDefaultAuxAudioProxyID());
end
if (self.hOffTriggerID ~= nil) then
self:StopAudioTrigger(self.hOffTriggerID, self:GetDefaultAuxAudioProxyID());
end
self.bIsPlaying = false;
self:KillTimer(0);
end
------------------------------------------------------------------------------------------------------
-- Event Handlers
------------------------------------------------------------------------------------------------------
function AudioTriggerSpot:Event_Enable(sender)
if (not self.Properties.bEnabled) then
self.Properties.bEnabled = true;
self:Play();
end
--BroadcastEvent(self, "Enable");
end
----------------------------------------------------------------------------------------
function AudioTriggerSpot:Event_Disable(sender)
self:Stop();
self.Properties.bEnabled = false;
--BroadcastEvent(self, "Disable");
end
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
AudioTriggerSpot.FlowEvents =
{
Inputs =
{
Enable = { AudioTriggerSpot.Event_Enable, "bool" },
Disable = { AudioTriggerSpot.Event_Disable, "bool" },
},
Outputs =
{
Done = "bool",
},
}
@@ -0,0 +1,83 @@
----------------------------------------------------------------------------------------------------
--
-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-- its licensors.
--
-- For complete copyright and license terms please see the LICENSE at the root of this
-- distribution (the "License"). All use of this software is governed by the License,
-- or, if provided, by the license below or the license accompanying this file. Do not
-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--
--
----------------------------------------------------------------------------------------------------
AudioUtils = {
-- these names should exactly match those defined in ATLEntities.cpp and in libs/gameaudio/wwise/default_controls.xml
sObstructionCalcSwitchName = "ObstructionOcclusionCalculationType",
sObstructionStateNames = {"Ignore", "SingleRay", "MultiRay"},
}
----------------------------------------------------------------------------------------
function AudioUtils.LookupTriggerID(sTriggerName)
local hTriggerID = nil;
if ((sTriggerName ~= nil) and (sTriggerName ~= "")) then
hTriggerID = Sound.GetAudioTriggerID(sTriggerName);
end
return hTriggerID;
end
----------------------------------------------------------------------------------------
function AudioUtils.LookupRtpcID(sRtpcName)
local hRtpcID = nil;
if ((sRtpcName ~= nil) and (sRtpcName ~= "")) then
hRtpcID = Sound.GetAudioRtpcID(sRtpcName);
end
return hRtpcID;
end
----------------------------------------------------------------------------------------
function AudioUtils.LookupSwitchID(sSwitchName)
local hSwitchID = nil;
if ((sSwitchName ~= nil) and (sSwitchName ~= "")) then
hSwitchID = Sound.GetAudioSwitchID(sSwitchName);
end
return hSwitchID;
end
----------------------------------------------------------------------------------------
function AudioUtils.LookupSwitchStateIDs(hSwitchID, tStateNames)
local tStateIDs = {};
if ((hSwitchID ~= nil) and (tStateNames ~= nil)) then
for i, name in ipairs(tStateNames) do
tStateIDs[i] = Sound.GetAudioSwitchStateID(hSwitchID, name);
end
end
return tStateIDs;
end
----------------------------------------------------------------------------------------
function AudioUtils.LookupAudioEnvironmentID(sEnvironmentName)
local hEnvironmentID = nil;
if ((sEnvironmentName ~= nil) and (sEnvironmentName ~= "")) then
hEnvironmentID = Sound.GetAudioEnvironmentID(sEnvironmentName);
end
return hEnvironmentID;
end
----------------------------------------------------------------------------------------
function AudioUtils.LookupObstructionSwitchAndStates()
local nSwitch = AudioUtils.LookupSwitchID(AudioUtils.sObstructionCalcSwitchName);
local tStates = AudioUtils.LookupSwitchStateIDs(nSwitch, AudioUtils.sObstructionStateNames);
return {hSwitchID = nSwitch, tStateIDs = tStates};
end