--[[ Fillable canteens This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0). Author: HarukaSai (visit us at: https://discord.gg/efp) 2023-06-28 ]] local string_find = string.find local geometry_ray = demonized_geometry_ray.geometry_ray waters = { ["flask"] = true, ["dirty_water"] = true, ["boiled_water"] = true } local sound_objs = { boiling_water = sound_object("fillable_canteens\\boiling_water"), filling_water = sound_object("fillable_canteens\\filling_water") } function is_liquid(ray, result) if (not result.material_name) then return false end return (string.find(result.material_name, "water") or ray:isMaterialFlag("flLiquid")) end function check_water(material) local ray = geometry_ray({ ray_range = 4, flags = 1 + 2 + 4 + 8, ignore_object = db.actor }) local res = ray:get(device().cam_pos, device().cam_dir) return is_liquid(ray, res.result) end function actor_on_item_use(obj) local sec = obj:section() if (waters[sec]) and obj:get_remaining_uses() == 0 then alife_create_item("empty_canteen", db.actor) end end function find_object(t, sec) for i = 1, #t do local result = t[i]:section() == sec and t[i] if result then return result end end end function find_object_t(t, secs) for i = 1, #secs do local result = find_object(t, secs[i]) if result then return result end end end function on_item_drag_dropped(obj_1, obj_2, slot_from, slot_to) local p_1, p_2 = obj_1:parent(), obj_2:parent() if not ((p_1 and p_1:id() == AC_ID) and (p_2 and p_2:id() == AC_ID)) then return end local akvatab = find_object({obj_1, obj_2}, "purification_tablet") local dirty_water = find_object_t({obj_1, obj_2}, {"dirty_water","boiled_water"}) if not (akvatab and dirty_water) then return end alife_create_item("flask", db.actor, {["uses"] = dirty_water:get_remaining_uses()}) alife_release(dirty_water) utils_item.discharge(akvatab, 1) end function fill(obj, sec) alife_create_item("dirty_water", obj:parent()) sound_objs.filling_water:play(db.actor, 0, sound_object.s2d) alife_release(obj) end local function fill_condition_function(obj, bag, mode) local p = obj:parent() if not (p and p:id() == AC_ID) then return end local sec = obj:section() if (sec == "empty_canteen" or waters[sec]) and check_water() then return true end end local add_functor = custom_functor_autoinject.add_functor add_functor("haruka_fill", fill_condition_function, function() return game.translate_string("st_haruka_fill") end, nil, fill) function on_game_start() RegisterScriptCallback("ActorMenu_on_item_drag_drop", on_item_drag_dropped) RegisterScriptCallback("actor_on_item_use", actor_on_item_use) end