--[[------------------------------------------------------------------------------------------------------------------
Original by: Tunduk Vladimir aka Sidorovich
Updated: 20121018
Edited by: Daemonion for LURK 1.2
Credits: Daemonion, Malindrinus
Thanks: NatVac, Malindrinus, Artos, AMK forums, GSC Forums
Changes: Pseudo-stereo audio now works properly!
--------------------------------------------------------------------------------------------------------------------]]
class "action_sound2d"
----------------------
function action_sound2d:__init (obj, storage)
self.object = obj
self.st = storage
self.snd_obj_l = nil
self.snd_obj_r = nil
self.time = 0
self.playing = false
self.current = 0
end
----------------------
function action_sound2d:reset_scheme()
self:recreate_sounds ()
self.st.signals = {}
self.time = time_global ()
self.playing = false
end
----------------------
function action_sound2d:recreate_sounds ()
self.snd_obj_l = nil
self.snd_obj_r = nil
local name_left, name_right = self:get_sound_name ()
if name_left ~= nil then
printf ("RECREATE_SOUNDS. LEFT CHANNEL = %s", name_left)
end
if name_right ~= nil then
printf ("RECREATE_SOUNDS. RIGHT CHANNEL = %s", name_right)
end
self.snd_obj_l = xr_sound.get_safe_sound_object (name_left)
if name_right ~= nil then
self.snd_obj_r = xr_sound.get_safe_sound_object (name_right)
else
self.snd_obj_r = nil
end
end
----------------------
function action_sound2d:get_next_sound_index ()
local idx = self.current
local tsize = table.getn (sound_theme.ph_snd_themes[self.st.snd_theme])
if tsize == 1 then
idx = 1
else
while idx == self.current do
idx = math.random (1, tsize)
end
end
self.current = idx
return idx
end
----------------------
function action_sound2d:get_sound_name ()
local name
if self.st.snd_name ~= nil then
name = self.st.snd_name
else
name = sound_theme.ph_snd_themes[self.st.snd_theme][self:get_next_sound_index ()]
if type(name) == "table" then
name = name[1]
end
end
if self.st.stereo == false then
return name, nil
end
return string.format ("%s_l", name), string.format ("%s_r", name)
end
----------------------
function action_sound2d:update (delta)
if self.snd_obj_l == nil then
return
end
local actor = db.actor
if self.playing == false then
self:play_sounds ()
self.playing = true
return
end
--[[if self.st.stereo == true then
local pos_l, pos_r = self:get_source_positions ()
if self.snd_obj_l ~= nil and self.snd_obj_l:playing () == true then
self.snd_obj_l:set_position (pos_l)
end
if self.snd_obj_r ~= nil and self.snd_obj_r:playing () == true then
self.snd_obj_r:set_position (pos_r)
end
end ]]
if self.snd_obj_l:playing () == false then
self.st.signals["sound_end"] = true
if self.st.snd_theme ~= nil then
self:recreate_sounds ()
self.time = time_global ()
self.playing = false
end
end
xr_logic.try_switch_to_another_section (self.object, self.st, actor)
end
----------------------
function action_sound2d:play_sounds ()
--ðàññ÷åò çàäåðæêè
local d
if self.st.delay == self.st.delay_max then
d = self.st.delay
else
d = math.random (self.st.delay, self.st.delay_max)
end
local actor = db.actor
-- åñëè çâóê ìîíî, òî èãðàåì òîëüêî ñ ëåâîãî êàíàëà è òîëüêî â æáàíå àêòåðà
if self.st.stereo == false then
if self.snd_obj_l ~= nil then
self.snd_obj_l:play_at_pos (actor, vector ():set (0, 0, 0), d / 1000.0, sound_object.s2d)
end
else
--åñëè îäèí èç êàíàëîâ îòñóòñâóåò, òî ïèíàòü æåñòîêî çâóêîâèêà
if self.snd_obj_l == nil or self.snd_obj_r == nil then
abort ("Can't play stereo sound because sound file for left or right channel not loaded")
end
--ðàññ÷èòàåì íàïðàâëåíèÿ íà èñòî÷íèêè çâóêà äëÿ ëåâîãî è ïðàâîãî ëîïóõà
--local pos_l, pos_r = self:get_source_positions ()
--self.snd_obj_l:play_at_pos (actor, pos_l, d / 1000.0, sound_object.s3d)
--self.snd_obj_r:play_at_pos (actor, pos_r, d / 1000.0, sound_object.s3d)
---------------------------------------------------------
-- This change here allows for stereo audio - Daemonion
---------------------------------------------------------
self.snd_obj_l:play_at_pos (actor, vector():set(-0.5,0.0,-0.3), d / 1000.0, sound_object.s2d)
self.snd_obj_r:play_at_pos (actor, vector():set( 0.5,0.0,0.3), d / 1000.0, sound_object.s2d)
end
end
----------------------
function action_sound2d:get_source_positions ()
local actor = db.actor
local dir = actor:direction ()
dir.y = 0.0
local dir_left = vector_rotate_y (dir, 45)
local dir_right = vector_rotate_y (dir, -45)
dir_left:normalize ()
dir_right:normalize ()
--ðàññ÷èòàåì âûñîòó
local pos = actor:position ()
pos.y = pos.y + 1.5 --íó íèçêîðîñëûé ó íàñ àêòåð...
local pos_l = pos;
return pos_l:add (dir_left:mul (1.5)), pos:add (dir_right:mul (1.5))
end
----------------------
function action_sound2d:deactivate ()
if self.snd_obj_l ~= nil then
if self.snd_obj_l:playing () == true then
self.snd_obj_l:stop ()
end
self.snd_obj_l = nil
end
if self.snd_obj_r ~= nil then
if self.snd_obj_r:playing () == true then
self.snd_obj_r:stop ()
end
self.snd_obj_r = nil
end
end
----------------------
function add_to_binder( npc, ini, scheme, section, storage )
-- local new_action =
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
xr_logic.subscribe_action_for_events (npc, storage, action_sound2d (npc, storage))
end
----------------------
function set_scheme (obj, ini, scheme, section, gulag_name)
local st = xr_logic.assign_storage_and_bind (obj, ini, scheme, section)
st.logic = xr_logic.cfg_get_switch_conditions (ini, section, obj)
st.snd_name = utils.cfg_get_string (ini, section, "snd", obj, false, "", nil)
st.snd_theme = utils.cfg_get_string (ini, section, "theme", obj, false, "", nil)
if st.snd_theme ~= nil and st.snd_name then
abort ("SR_SOUND2D : can't definition sound file name and sound theme at the one time");
end
st.delay = utils.cfg_get_number (ini, section, "delay", obj, false, 0)
st.delay_max = utils.cfg_get_number (ini, section, "delay_max", obj, false, 0)
st.stereo = utils.cfg_get_bool (ini, section, "stereo", obj, false, false)
if st.delay_max < st.delay then
st.delay_max = st.delay
end
if st.snd_name ~= nil then
if st.snd_name == "" then
abort ("SR_SOUND2D : invalid sound name")
end
else
if st.snd_theme == nil or st.snd_theme == "" then
abort ("SR_SOUND2D : invalid sound theme")
end
end
end
----------------------
----------------------
----------------------
----------------------