local function get_sound_type(sound_type) local s_type = "NIL" if bit_and(sound_type, snd_type.weapon) == snd_type.weapon then s_type = "WPN" if bit_and(sound_type, snd_type.weapon_shoot) == snd_type.weapon_shoot then s_type = "WPN_shoot" elseif bit_and(sound_type, snd_type.weapon_empty) == snd_type.weapon_empty then s_type = "WPN_empty" elseif bit_and(sound_type, snd_type.weapon_bullet_hit) == snd_type.weapon_bullet_hit then s_type = "WPN_hit" elseif bit_and(sound_type, snd_type.weapon_reload) == snd_type.weapon_reload then s_type = "WPN_reload" end elseif bit_and(sound_type, snd_type.item) == snd_type.item then s_type = "ITM" if bit_and(sound_type, snd_type.item_pick_up) == snd_type.item_pick_up then s_type = "ITM_pckup" elseif bit_and(sound_type, snd_type.item_drop) == snd_type.item_drop then s_type = "ITM_drop" elseif bit_and(sound_type, snd_type.item_hide) == snd_type.item_hide then s_type = "ITM_hide" elseif bit_and(sound_type, snd_type.item_take) == snd_type.item_take then s_type = "ITM_take" elseif bit_and(sound_type, snd_type.item_use) == snd_type.item_use then s_type = "ITM_use" end elseif bit_and(sound_type, snd_type.monster) == snd_type.monster then s_type = "MST" if bit_and(sound_type, snd_type.monster_die) == snd_type.monster_die then s_type = "MST_die" elseif bit_and(sound_type, snd_type.monster_injure) == snd_type.monster_injure then s_type = "MST_damage" elseif bit_and(sound_type, snd_type.monster_step) == snd_type.monster_step then s_type = "MST_step" elseif bit_and(sound_type, snd_type.monster_talk) == snd_type.monster_talk then s_type = "MST_talk" elseif bit_and(sound_type, snd_type.monster_attack) == snd_type.monster_attack then s_type = "MST_attack" elseif bit_and(sound_type, snd_type.monster_eat) == snd_type.monster_eat then s_type = "MST_eat" end end return s_type end function reset_hear_callback(st, section) local function is_on_sound_line(candidate) return string.find( candidate, "^on_sound%d*$" ) ~= nil end local function add_parsed_data_to_storage(value, st) local obj = st.object local parsed_params = utils.parse_params(value) st.hear_sounds[parsed_params[1]] = st.hear_sounds[parsed_params[1]] or {} st.hear_sounds[parsed_params[1]][parsed_params[2]] = { dist = tonumber(parsed_params[3]), power = tonumber(parsed_params[4]), condlist = xr_logic.parse_condlist(obj, "hear_callback", "hear_callback", parsed_params[5])} end local ini = st.ini if not ini:section_exist(section) then return end local n = ini:line_count(section) local id, value = "","" local category = "" st.hear_sounds = {} for i=0,n-1 do result, id, value = ini:r_line(section,i,"","") if is_on_sound_line(id) then add_parsed_data_to_storage(value, st) end end end function hear_callback(obj, who_id, sound_type, sound_position, sound_power) local st = db.storage[obj:id()] local s_type = get_sound_type(sound_type) local story_id = get_object_story_id(who_id) or "any" if st.hear_sounds == nil then return end if st.hear_sounds[story_id] and st.hear_sounds[story_id][s_type] then local hear_sound_params = st.hear_sounds[story_id][s_type] if hear_sound_params.dist >= sound_position:distance_to(obj:position()) and sound_power >= hear_sound_params.power then local new_section = xr_logic.pick_section_from_condlist(db.actor, obj, hear_sound_params.condlist) if new_section ~= nil and new_section ~= "" then xr_logic.switch_to_section(obj, st.ini, new_section) elseif new_section == "" then st.hear_sounds[story_id][s_type] = nil end end end end