2023-09-12 18:58:10 +00:00
|
|
|
#include "..\script_component.hpp"
|
2015-02-17 06:51:51 +00:00
|
|
|
/*
|
|
|
|
* Author: Glowbal
|
|
|
|
* Plays synchronized ambiance sounds while the module is alive.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* 0: Logic <LOGIC>
|
|
|
|
* 1: Units <ARRAY>
|
|
|
|
* 2: Activated <BOOL>
|
|
|
|
*
|
|
|
|
* Return Value:
|
2017-06-08 13:31:51 +00:00
|
|
|
* None
|
2015-02-17 06:51:51 +00:00
|
|
|
*
|
|
|
|
* Example:
|
2017-06-08 13:31:51 +00:00
|
|
|
* [LOGIC, [bob, kevin], true] call ace_missionmodules_fnc_moduleAmbianceSound
|
2015-02-17 06:51:51 +00:00
|
|
|
*
|
|
|
|
* Public: No
|
|
|
|
*/
|
|
|
|
|
2015-11-16 18:00:02 +00:00
|
|
|
params ["_logic", "_units", "_activated"];
|
2015-02-17 06:51:51 +00:00
|
|
|
|
|
|
|
// We only play this on the locality of the logic, since the sounds are broadcasted across the network
|
2017-10-10 14:39:59 +00:00
|
|
|
if (!_activated || !local _logic) exitWith {0};
|
|
|
|
|
|
|
|
private _ambianceSounds = [];
|
|
|
|
private _unparsedSounds = _logic getVariable ["soundFiles", ""];
|
|
|
|
private _minimalDistance = (_logic getVariable ["minimalDistance", 400]) max 1;
|
|
|
|
private _maximalDistance = (_logic getVariable ["maximalDistance", 10]) max _minimalDistance;
|
|
|
|
private _minDelayBetweensounds = (_logic getVariable ["minimalDelay", 10]) max 1;
|
|
|
|
private _maxDelayBetweenSounds = (_logic getVariable ["maximalDelay", 170]) max _minDelayBetweensounds;
|
|
|
|
private _volume = (_logic getVariable ["soundVolume", 30]) max 1;
|
|
|
|
private _followPlayers = _logic getVariable ["followPlayers", false];
|
|
|
|
|
|
|
|
private _splittedList = _unparsedSounds splitString ",";
|
|
|
|
private _missionRoot = str missionConfigFile select [0, count str missionConfigFile - 15];
|
|
|
|
|
|
|
|
{
|
|
|
|
_x = [_x] call CBA_fnc_removeWhitespace;
|
|
|
|
|
|
|
|
if (isClass (missionConfigFile >> "CfgSounds" >> _x)) then {
|
|
|
|
// CfgSounds accepts a leading backslash, but a double backslash
|
|
|
|
// is not accepted in the path, so we have to filter that.
|
|
|
|
private _soundPath = getArray (missionConfigFile >> "CfgSounds" >> _x >> "sound") select 0;
|
|
|
|
if (_soundPath select [0,1] == "\") then {
|
|
|
|
_ambianceSounds pushBack (_missionRoot + (_soundPath select [1]));
|
2015-04-06 16:22:43 +00:00
|
|
|
} else {
|
2017-10-10 14:39:59 +00:00
|
|
|
_ambianceSounds pushBack (_missionRoot + _soundPath);
|
2015-04-06 16:22:43 +00:00
|
|
|
};
|
2017-10-10 14:39:59 +00:00
|
|
|
} else {
|
|
|
|
if (isClass (configFile >> "CfgSounds" >> _x)) then {
|
|
|
|
_soundPath = (getArray(configFile >> "CfgSounds" >> _x >> "sound")) param [0, ""];
|
|
|
|
if ((_soundPath select [0, 1]) == "\") then {_soundPath = _soundPath select [1];};
|
|
|
|
_ambianceSounds pushBack _soundPath;
|
|
|
|
} else {
|
|
|
|
ERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x);
|
|
|
|
};
|
|
|
|
};
|
2015-11-16 18:00:02 +00:00
|
|
|
|
2017-10-10 14:39:59 +00:00
|
|
|
false
|
|
|
|
} count _splittedList;
|
2015-04-06 16:22:43 +00:00
|
|
|
|
2017-10-10 14:39:59 +00:00
|
|
|
if (count _ambianceSounds == 0) exitWith {};
|
|
|
|
{
|
|
|
|
if ((_x find ".") == -1) then {
|
|
|
|
_ambianceSounds set [_forEachIndex, _x + ".wss"];
|
|
|
|
};
|
|
|
|
} forEach _ambianceSounds;
|
2015-04-06 16:22:43 +00:00
|
|
|
|
2017-10-10 14:39:59 +00:00
|
|
|
TRACE_1("",_ambianceSounds);
|
2016-10-01 08:27:00 +00:00
|
|
|
|
2017-10-10 14:39:59 +00:00
|
|
|
[{
|
|
|
|
params ["_args", "_pfhHandle"];
|
|
|
|
_args params ["_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers", "_lastTimePlayed"];
|
2015-04-06 16:22:43 +00:00
|
|
|
|
2017-10-10 14:39:59 +00:00
|
|
|
if (!alive _logic) exitWith {
|
|
|
|
[_pfhHandle] call CBA_fnc_removePerFrameHandler;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (CBA_missionTime - _lastTimePlayed >= ((_minDelayBetweensounds + random(_maxDelayBetweenSounds)) min _maxDelayBetweenSounds)) then {
|
2015-04-06 16:22:43 +00:00
|
|
|
|
2017-10-10 14:39:59 +00:00
|
|
|
// Find all players in session.
|
|
|
|
private _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]};
|
|
|
|
|
|
|
|
// Check if there are enough players to even start playing this sound.
|
|
|
|
if (count _allUnits > 0) then {
|
|
|
|
// find the position from which we are going to play this sound from.
|
|
|
|
private _newPosASL = if (_followPlayers) then {
|
|
|
|
// Select a target unit at random.
|
|
|
|
private _targetUnit = selectRandom _allUnits;
|
|
|
|
AGLtoASL (_targetUnit getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]);
|
|
|
|
} else {
|
|
|
|
AGLtoASL (_logic getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]);
|
|
|
|
};
|
|
|
|
|
|
|
|
TRACE_1("",_newPosASL);
|
|
|
|
// If no unit is to close to this position, we will play the sound.
|
|
|
|
if ({(_newPosASL distance _x < (_minimalDistance / 2))}count _allUnits == 0) then {
|
|
|
|
private _soundFile = selectRandom _ambianceSounds;
|
|
|
|
TRACE_2("playing file",_soundFile,_newPosASL);
|
|
|
|
playSound3D [_soundFile, objNull, false, _newPosASL, _volume, 1, 1000];
|
|
|
|
_args set [8, CBA_missionTime];
|
|
|
|
} else {
|
|
|
|
TRACE_1("pos is too close to a player",_newPosASL);
|
2015-04-06 16:22:43 +00:00
|
|
|
};
|
|
|
|
};
|
2017-10-10 14:39:59 +00:00
|
|
|
};
|
|
|
|
}, 0.1, [_logic, _ambianceSounds, _minimalDistance, _maximalDistance, _minDelayBetweensounds, _maxDelayBetweenSounds, _volume, _followPlayers, CBA_missionTime] ] call CBA_fnc_addPerFrameHandler;
|
2015-02-17 06:51:51 +00:00
|
|
|
|
|
|
|
true;
|