Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions gamedata/scripts/callbacks_gameobject.script
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,43 @@ _G.COnBeforePlayHudSound = function(alias, parent)
end
end

--[[
on_before_play_ambient_bed callback, scale or veto the per-weather ambient background bed.
Fired from CGamePersistent::WeathersUpdate (GamePersistent.cpp) at each bed play site.
Return via result.volume_mult: 0 vetoes the play, <1 attenuates, nil leaves vanilla.

Arguments
section: weather ambient section the bed loads from
file: resolved sound file name, "" when the handle is not ready yet
pos: Fvector world position the bed plays at
--]]
AddScriptCallback("on_before_play_ambient_bed")
_G.COnAmbientBed = function(section, file, pos)
local result = { volume_mult = nil }
SendScriptCallback("on_before_play_ambient_bed", section, file, pos, result)
if result.volume_mult then
return result
end
end

--[[
on_before_play_level_music callback, scale or silence the level music track.
Fired from SMusicTrack::Play (level_sounds.cpp). Volume-only: a skip would make the
manager re-select every frame, so 0 silences rather than stops the track.
Return via result.volume_mult: 0 silences, <1 attenuates, nil leaves vanilla.

Arguments
file: resolved music track file name, "" when the handle is not ready yet
--]]
AddScriptCallback("on_before_play_level_music")
_G.COnLevelMusic = function(file)
local result = { volume_mult = nil }
SendScriptCallback("on_before_play_level_music", file, result)
if result.volume_mult then
return result
end
end

-- NLTP_ASHES & demonized : Actor on death callback
AddScriptCallback("actor_on_death")
function actor_on_first_update()
Expand Down
29 changes: 28 additions & 1 deletion src/xrGame/GamePersistent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ void CGamePersistent::OnGameEnd()
xr_delete(g_stalker_velocity_holder);
}

// { volume_mult = number } from a sound hook's return; 1.0 (vanilla) when nil, not a table, or not a number
static float ambient_hook_volume_mult(const ::luabind::object& output)
{
if (output && output.type() == LUA_TTABLE)
{
auto volume_mult_obj = output["volume_mult"];
if (volume_mult_obj.type() == LUA_TNUMBER)
return ::luabind::object_cast<float>(volume_mult_obj);
}
return 1.0f;
}

void CGamePersistent::WeathersUpdate()
{
if (g_pGameLevel && !g_dedicated_server)
Expand Down Expand Up @@ -315,7 +327,22 @@ void CGamePersistent::WeathersUpdate()
pos.z = _sin(angle);
pos.normalize().mul(ch.get_rnd_sound_dist()).add(Device.vCameraPosition);
pos.y += 10.f;
snd.play_at_pos(0, pos);

// Ambient bed hook, mirrors COnBeforePlayHudSound: Lua may veto (0) or attenuate; absent global = exact vanilla
float bed_volume_mult = 1.0f;
::luabind::functor<::luabind::object> bed_funct;
if (ai().script_engine().functor("_G.COnAmbientBed", bed_funct))
{
LPCSTR bed_file = snd._handle() ? snd._handle()->file_name() : "";
bed_volume_mult = ambient_hook_volume_mult(bed_funct(ch.m_load_section.c_str(), bed_file, pos));
}

if (bed_volume_mult > EPS_S)
{
snd.play_at_pos(0, pos);
if (bed_volume_mult < 1.0f)
snd.set_volume(bed_volume_mult);
}

#ifdef DEBUG
if (!snd._handle() && strstr(Core.Params, "-nosound"))
Expand Down
25 changes: 24 additions & 1 deletion src/xrGame/level_sounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@

#include "level.h"
#include "level_sounds.h"
#include "ai_space.h"
#include "../xrServerEntities/script_engine.h"

// { volume_mult = number } from a sound hook's return; 1.0 (vanilla) when nil, not a table, or not a number
static float ambient_hook_volume_mult(const ::luabind::object& output)
{
if (output && output.type() == LUA_TTABLE)
{
auto volume_mult_obj = output["volume_mult"];
if (volume_mult_obj.type() == LUA_TNUMBER)
return ::luabind::object_cast<float>(volume_mult_obj);
}
return 1.0f;
}

//-----------------------------------------------------------------------------
// static level sounds
Expand Down Expand Up @@ -129,7 +143,16 @@ BOOL SMusicTrack::in(u32 game_time)
void SMusicTrack::Play()
{
m_SourceStereo.play_at_pos(0, Fvector().set(0.0f, 0.0f, 0.0f), sm_Intro);
SetVolume(1.0f);

// Level-music hook: volume-only (a skip would make the manager re-select every frame); absent global = vanilla
float music_volume_mult = 1.0f;
::luabind::functor<::luabind::object> music_funct;
if (ai().script_engine().functor("_G.COnLevelMusic", music_funct))
{
LPCSTR music_file = m_SourceStereo._handle() ? m_SourceStereo._handle()->file_name() : "";
music_volume_mult = ambient_hook_volume_mult(music_funct(music_file));
}
SetVolume(music_volume_mult);
}

BOOL SMusicTrack::IsPlaying()
Expand Down
Loading