--[[------------------------------------------------------------------------------------------------------------------ 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 ---------------------- ---------------------- ---------------------- ----------------------