local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
local S = minetest.get_translator(mod_name)

aom_longship.has_aom_climate = minetest.get_modpath("aom_climate") ~= nil
aom_longship.enable_sail_wind = true

-- wind fallback
local _wind_dir = 1
local t = 0
minetest.register_globalstep(function(dtime)
    if t > 0 then t = t - dtime return else t = t + math.random(120, 600) end
    _wind_dir = math.random() * math.pi * 2
end)

-- get the wind direction, however that may be supplied
function aom_longship.get_wind_direction(self, ignore_gusts)
    local pos = self.object:get_pos()
    if aom_longship.has_aom_climate then
        return aom_climate.wind.get_wind_dir(pos, ignore_gusts)
    else
        return minetest.yaw_to_dir(_wind_dir)
    end
end

-- add pilot hud
function aom_longship.hud_add(self)
    local player = minetest.is_player(self._pilot) and self._pilot
    if not player then aom_longship.hud_remove(self); return end

    self._aomv_hud = {}
    local hud = self._aomv_hud

    local sail
    sail = math.floor(self._ctrl_sail or 0)
    if sail == -1 then sail = "rev" end

    hud.sail = COMPAT.hud_add(player, {
        type = "image",
        alignment = {x=1.0, y=1.0},
        position = {x=0.8, y=0.8},
        name = "aom_longship_gui_sail",
        text = "aom_longship_gui_sail_"..sail..".png",
        z_index = 1018,
        scale = {x = 4, y = 4},
        offset = {x = 0, y = 0},
    })
end

---Remove the hud for the pilot
function aom_longship.hud_remove(self)
    local player = minetest.is_player(self._pilot) and self._pilot
    if not player then self._aomv_hud = nil; return end

    for name, id in pairs(self._aomv_hud) do
        player:hud_remove(id)
    end
    self._aomv_hud = nil
end

---Show the controls on the hud
function aom_longship.hud_update(self)
    local player = minetest.is_player(self._pilot) and self._pilot
    if not player then aom_longship.hud_remove(self); return end
    local hud = self._aomv_hud
    if not hud then return end

    local sail
    sail = math.floor(self._ctrl_sail or 0)
    if sail == -1 then sail = "rev" end
    player:hud_change(hud.sail, "text", "aom_longship_gui_sail_"..sail..".png")
end

---Gets how much the sail should actually push the ship forward
function aom_longship.get_wind_sail_strenth(self)
    local factor = 0

    if self._ctrl_sail ==  1 then return 1 end
    if self._ctrl_sail == -1 then return 1 end

    local heading = aom_vehicleapi.get_actual_yaw(self)
    local wind_dir = aom_longship.get_wind_direction(self, true)
    local wind_heading = minetest.dir_to_yaw(wind_dir)
    local wind_strength = math.max(vector.length(wind_dir) * 2, 0.2)
    local anglediff = aom_vehicleapi.shortangledist(wind_heading, heading)
    factor = 1 - math.abs(anglediff / (math.pi)) % 1
        -- local pos = self.object:get_pos()
        -- pos.y = pos.y + 4
        -- aom_vehicleapi.debug_particle(pos - minetest.yaw_to_dir(wind_heading) * 10, "#f0f", 1, minetest.yaw_to_dir(wind_heading)*10)
        -- aom_vehicleapi.debug_particle(pos, "#ff0", 1, minetest.yaw_to_dir(heading)*10)

    if self._aomv_wind_pad == nil then self._aomv_wind_pad = 0 end
    if factor < 0.2 then
        factor = 0.0
    else
        factor = aom_vehicleapi.clamp(factor * wind_strength * (1 - self._aomv_wind_pad) + self._aomv_wind_pad, 0.0, 1)
    end
    -- minetest.log("wind factor: "..factor)
    return factor
end

---Turn the steering wheel according to the control setting
function aom_longship.do_helm_rotation(self, dtime)
    local anglerad = ((self._ctrl_steer or 0) / 4) * math.pi
    anglerad = anglerad * 5
    self._helm_angle = aom_vehicleapi.anglelerp(self._helm_angle or anglerad, anglerad, 0.1)
    COMPAT.set_bone_override(self.object, "helm_override", {
        rotation = {vec = vector.new(0, self._helm_angle, 0), interpolation = dtime + 0.05, absolute = true}
    })
end

---Get the wind direction and apply this to the sail
function aom_longship.do_wind_direction(self, dtime, override)
    -- do return end
    local heading = aom_vehicleapi.get_actual_yaw(self)
    local wind_dir = aom_longship.get_wind_direction(self, true)
    local wind_heading = minetest.dir_to_yaw(wind_dir)
    -- local wind_relative = -(wind_heading - heading) % (math.pi*2)

    local wind_relative = aom_vehicleapi.anglelerp(wind_heading, heading, 0.4)
    wind_relative = (wind_relative - heading) % (math.pi*2)
    self._last_sail_rot = override or (wind_relative)
    -- core.log(self._last_sail_rot)
    COMPAT.set_bone_override(self.object, "sail_override", {
        rotation = {
            vec = vector.new(0, -self._last_sail_rot, 0),
            interpolation = (not self._force_sail_rotation and (dtime + 0.05)) or nil,
            absolute = true
        }
    })
end

---Gravity when above water, else float up
function aom_longship.float_on_water(self, dtime)
    local vel = self.object:get_velocity()
    local add_vel = vel * -0.01
    local in_node = aom_vehicleapi.is_in_node(self, -0.2)
    if in_node or aom_vehicleapi.is_in_water(self, 0.2) then
        add_vel.y = add_vel.y + dtime * 2
    elseif not aom_vehicleapi.is_in_water(self, -0.2) then
        add_vel.y = add_vel.y - dtime * 2
    end
    self.object:add_velocity(add_vel)
end

---Completely removes and replaces the entity
function aom_longship.on_refresh_entity(self)
    local pos = self.object:get_pos()
    local staticdata = self.get_staticdata(self)
    local newobj = minetest.add_entity(pos, "aom_longship:longship_ENTITY", staticdata)
    local newent = newobj and newobj:get_luaentity()
    if not newent then return end
    local pilot = self._pilot
    if pilot then
        self._set_detach(self, pilot)
        newent._set_attach(newent, pilot)
    end
    newobj:set_velocity(self.object:get_velocity())
    newent._aomv_pl = self._aomv_pl
    aom_longship.do_animation(newent, 0)
    self.object:remove()
    return true
end

---Get the animation based on the sail control setting and the wind strength
function aom_longship.get_animation(self)
    -- if not self._pilot then return "idle" end
    local wind = aom_longship.get_wind_sail_strenth(self)

    local sail = (self._ctrl_sail or 0)
    if wind > 0.1 and sail > 1 then
        if sail == 2 then sail = 1
        elseif sail == 3 then sail = 2
        else sail = 0 end
    else
        return "idle"
    end

    if wind > 0.8 then wind = 3
    elseif wind > 0.5 then wind = 2
    else wind = 1 end

    return "sail" .. sail .. "wind" .. wind
end

---Handle all animation and apply this animation
function aom_longship.do_animation(self, blend)
    local anim_name = aom_longship.get_animation(self)
    -- blend = 0
    if self._anim_name ~= anim_name then
        local anim = self._animations[anim_name]
        self.object:set_animation(anim.frames, anim.speed or 24, blend or anim.blend or nil, anim.loop)
        self._anim_name = anim_name
        self._force_sail_rotation = true
    end
end

---Handle the steering and sail of the ship according to last set, or player controls
function aom_longship.do_ship_controls(self, player, dtime)
    -- if the player left the ship, stop
    local pi = self._aomv_pl and self._last_pilot and self._aomv_pl[self._last_pilot:get_player_name()]
    local in_poly = (pi and pi.is_in_poly)
    local has_pilot = (player or (minetest.is_player(self._pilot)))
    if (not in_poly) and (not has_pilot) and (self._ctrl_sail ~= 0 or self._ctrl_steer ~= 0) then
        if (self._lose_pilot_time == nil) then
            self._lose_pilot_time = 2
        end
    else
        self._lose_pilot_time = nil
    end

    -- local tmpplayer = player or self._last_pilot or core.get_player_by_name("singleplayer")
    -- aom_hud.debug(tmpplayer, "_lose_pilot_time: " .. dump(self._lose_pilot_time), "#fff")
    -- aom_hud.debug(tmpplayer, "_last_pilot: " .. tostring(self._last_pilot), "#fff")

    if self._lose_pilot_time then
        if (self._lose_pilot_time > 0) then
            self._lose_pilot_time = self._lose_pilot_time - dtime
        else
            self._last_pilot = nil
            self._ctrl_sail = 0
            self._ctrl_steer = 0
            self._lose_pilot_time = nil
        end
    end

    if minetest.is_player(player) then
        -- show sail icon etc
        aom_longship.hud_update(self)
        aom_vehicleapi.do_ship_controls(self, player, dtime)
    end
    -- each setting of speed has a distinct value
    local speeds = {
        [1] = 0.1,
        [2] = 0.5,
        [3] = 1,
    }
    self._sail = (speeds[math.abs(self._ctrl_sail)] or 0) * math.sign(self._ctrl_sail)
    self._steer = aom_vehicleapi.lerp(self._steer, self._ctrl_steer, 0.03)
    -- when leaving ship, continue to do collisions for a few seconds to avoid passing through walls
    self._collision_continue_time = 3
end

---Control the ship and apply velocity and rotation
function aom_longship.do_pilot(self, player, dtime)
    local wind_factor = 1
    if aom_longship.enable_sail_wind then
        aom_longship.do_wind_direction(self, dtime)
        wind_factor = aom_longship.get_wind_sail_strenth(self)
    end

    aom_longship.do_ship_controls(self, player, dtime)

    if self._sail < 0 then wind_factor = 1 end

    local yaw = aom_vehicleapi.get_actual_yaw(self)
    local dir = minetest.yaw_to_dir(yaw)
    local max_speed = wind_factor * (self._max_speed or 0) * aom_longship.get_setting(nil, "longship_max_speed_multiplier", 1)
    max_speed = math.max(max_speed * self._sail, (self._min_speed or 0) * aom_longship.get_setting(nil, "longship_min_speed_multiplier", 1))
    max_speed = max_speed * math.sign(self._ctrl_sail)
    local new_vel = dir * max_speed * dtime

    local vel = self.object:get_velocity()
    new_vel = aom_vehicleapi.do_anti_drift(self, new_vel, dtime) or (new_vel + vel * 0.91)

    local pos = self.object:get_pos()
    pos.y = pos.y + 2
    aom_vehicleapi.debug_particle(pos + new_vel - vel, "#f0f", 0.2, vel)

    local steer_factor = aom_vehicleapi.clamp(vector.length(new_vel) * 0.4, 0.0, 1)
    local steer_dir = math.sign(vector.dot(dir, vector.normalize(new_vel)))
    if steer_factor < 0.3 then steer_factor = steer_factor + (steer_factor) * 0.5 end
    if steer_factor < 0.1 and self._ctrl_sail == 0 then
        steer_dir = 1
        steer_factor = 0.2
    end
    steer_factor = steer_factor * steer_dir

    local rot = self._steer * (self._max_steer or 0) * steer_factor
    -- don't set props constantly; only when needed
    local props = self.object:get_properties()
    if math.abs(props.automatic_rotate - rot) > 0.01 then
        self.object:set_properties({automatic_rotate = rot})
    elseif math.abs(props.automatic_rotate) < 0.01 and props.automatic_rotate ~= 0 then
        self.object:set_properties({automatic_rotate = 0})
    end

    self.object:set_velocity(new_vel)
end


function aom_longship.finish_build(self)
    self._active = true
    self.object:set_properties({
        visual_size = vector.new(1, 1, 1)
    })
end

function aom_longship.finish_destroy(self)
    self._active = false
    self.object:set_hp(0, "destroyed")
end


-----------------------
--  SHIP DEFINITION  --
-----------------------

aom_longship.ship = {
    initial_properties = {
        visual = "mesh",
        mesh = "aom_longship.b3d",
        textures = {"aom_longship.png"},
        backface_culling = false,
        use_texture_alpha = true,
        selectionbox = {-2, -0.5, -2, 2, 6/16, 2},
        stepheight = 0,
        hp_max = 60,
        physical = false,
        pointable = true,
        damage_texture_modifier = "^[colorize:#ff9999:50",
        -- static_save = false,
        automatic_rotate = 0,
    },
    -- Minetest limitation causes desync after some time even in singleplayer, so it must completely replace the entity occasionally
    -- this causes a very noticeable jolt
    _aomv_sync_refresh_interval = 300,
    -- whether to attach the player to a fake controller when ship is moving
    _aomv_friction_fix = true,
    -- called 1s before refresh happens
    _on_refresh_start = function(self)
    end,
    _ctrl_sail = 0,
    _ctrl_steer = 0,
    _active = false,
    -- called when refresh happens
    _on_refresh_entity = aom_longship.on_refresh_entity,
    on_step = function(self, dtime, moveresult)
        local pos = self.object:get_pos()
        if not pos then return end
        self._age = (self._age or 0) + dtime
        if (self._build_time or 0) > 0 then
            self._active = false
            local fd = 1 - math.min(1, self._build_time * 2)
            self.object:set_properties({
                visual_size = vector.new(fd, fd, fd)
            })
            self._build_time = (self._build_time or 0) - dtime
            if self._build_time < 0 then
                aom_longship.finish_build(self)
            end
            return
        elseif (self._destroy_time or 0) > 0 then
            self._active = false
            local fd = math.min(1, self._destroy_time * 2)
            self.object:set_properties({
                visual_size = vector.new(fd, fd, fd)
            })
            self._destroy_time = (self._destroy_time or 0) - dtime
            if self._destroy_time < 0 then
                aom_longship.finish_destroy(self)
            end
            return
        end

        if minetest.is_player(self._pilot) and (self._pilot:get_attach() ~= self.object) then
            self._set_detach(self, self._pilot)
        end

        if aom_vehicleapi.on_step(self, dtime, moveresult) then
            return -- removed
        end

        aom_vehicleapi.do_collision_push(self, dtime)
        aom_longship.do_helm_rotation(self, dtime)
        aom_longship.float_on_water(self, dtime)
        if self._active then
            aom_longship.do_pilot(self, self._pilot, dtime)
        end
        aom_longship.do_animation(self)
    end,
    _on_collision_push_sleep = function(self)
        self._sail = 0
        self._steer = 0
    end,
    _on_collision_push = function(self, push, dtime)
        self._sail = self._sail * 0.95
        self._steer = self._steer * 0.95
    end,
    on_death = function(self, killer)
        if self._removed then return end
        self._removed = true
        minetest.add_item(self.object:get_pos(), ItemStack("aom_longship:longship"))
    end,
    on_activate = function(self, staticdata, dtime_s)
        aom_vehicleapi.on_activate(self, staticdata, dtime_s)
        aom_vehicleapi.add_sound_player(self, vector.new(0, 0, 9), {bow_waves = aom_longship.sounds.bow_waves})
        aom_vehicleapi.add_sound_player(self, vector.new(0, 0, 3),
            {creaking_low = aom_longship.sounds.creaking_low, creaking = aom_longship.sounds.creaking})
        self.object:set_animation({x=200,y=280}, 24, 0.1, true)
        COMPAT.set_bone_override(self.object, "shields", {
            position = {vec = vector.new(0,9999999999,0)}
        }) -- to hide the shields
        if self._active then self._build_time = -1 end
        if self._hp then
            self.object:set_hp(self._hp, "spawn")
        end
        self.object:set_armor_groups({
            pierce=30,
            slash=10,
            blunt=10,
            magic=50,
            poison=0,
        })
    end,
    get_staticdata = function(self)
        self._hp = self.object:get_hp()
        return aom_vehicleapi.get_staticdata(self)
    end,
    on_deactivate = function(self, removal)
        if removal then
            self._set_detach(self, self._pilot)
            aom_longship.hud_remove(self)
            aom_vehicleapi.fade_all_sounds(self, 0.2)
        end
    end,
    on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
        local val = self._on_damage_received(self, puncher, damage)
        if val and val <= 0 then return true end
    end,
    _on_attack_received = function(self, itemstack, atk)
        atk.knockback_mult = (atk.knockback_mult or 0) * 0.1
    end,
    _on_damage_received = function(self, attacker_entity, maxdmg)
        if self._destroy_time then return 0 end
        if maxdmg < 0.2 then return 0 end
        if maxdmg < 1 and maxdmg > 0.1 then
            maxdmg = 1
        end
        minetest.sound_play("aom_wood_dig", {
            position = self.object:get_pos(),
            gain = 1, pitch = 0.5,
        })
        if self.object:get_hp() <= maxdmg then
            self._destroy_time = 1
            self.object:set_armor_groups({})
            return 0
        end
        return maxdmg
    end,
    _set_attach = function(self, player)
        if not minetest.is_player(player) then return end
        if player:get_attach() ~= nil then
            local obj = player:get_attach()
            local ent = obj and obj:get_luaentity()
            if ent and ent.name ~= "aom_vehicleapi:friction_fix_ENTITY" then
                return
            end
            player:set_detach()
        end
        self._pilot = player
        aom_longship.hud_add(self)
        player:set_attach(self.object, nil, vector.new(0,4,0), vector.new(0,0,0))
    end,
    _set_detach = function(self, player)
        if minetest.is_player(player) then
            aom_longship.hud_remove(self)
            self._last_pilot = player
            self._pilot = nil
            -- core.log("detached " .. tostring(self._last_pilot))
            player:set_detach()
            player:set_pos(vector.offset(player:get_pos(), 0, 1, 0))
        end
    end,
    on_rightclick = function(self, clicker)
        if self._build_time and self._build_time > 0 then return end
        if self._pilot == nil then
            self._set_attach(self, clicker)
        else
            if self._pilot == clicker then
                self._set_detach(self, clicker)
            end
        end
    end,
    _build_time = 1,
    _aom_statusfx_enable = false,
    _sail = 0,
    _steer = 0,
    _max_speed = 4, -- full running sail
    _min_speed = 0.8, -- paddle
    _max_steer = 0.3, -- radians per sec
    _aomv_anti_drift = 0.1,
    _aomv_wind_pad = 0.4, -- shifts wind factor up by this and squashes it between this and 1
    _aomv_sounds = {
        footstep = minetest.get_modpath("aom_sounds") and aom_sounds.default_wood().footstep,
    },
    _aomv_platform_y = 0.3,
    _aom_static_save = {
        "_sail", "_steer", "_ctrl_sail", "_ctrl_steer", "_collision_continue_time", "_age",
        "_active", "_hp",
    },
    _aomv_collides_with_other_vehicles = true,
}

-----------------------
--   SHIP PHYSICS    --
-----------------------

aom_longship.ship._animations = {
    idle = {frames={x=0, y=199}, speed=24, blend=1},
    sail1wind1 = {frames={x=200, y=200+99}, blend=2, loop=true},
    sail1wind2 = {frames={x=300, y=300+99}, blend=2, loop=true},
    sail1wind3 = {frames={x=400, y=400+99}, blend=2, loop=true},
    sail2wind1 = {frames={x=500, y=500+99}, blend=2, loop=true},
    sail2wind2 = {frames={x=600, y=600+99}, blend=2, loop=true},
    sail2wind3 = {frames={x=700, y=700+99}, blend=2, loop=true},
}

aom_longship.ship._aomv_pointcloud_offset = vector.new(-10/16,0,0)

aom_longship.ship._aomv_polygon = {
    main_deck = {
        height = {-3, 3},
        get_platform_y = function(polydef, rpos)
            return 0.45
        end,
        walkable = true,
        collision = false,
        points = {
            {-1.4,-1.8},
            {-2.0, 1.7},
            {-2.0, 6.1},
            { 0.0, 11.5},
            { 2.0, 6.1},
            { 2.0, 1.7},
            { 1.4,-1.8},
        },
    },
    back = {
        height = {-3, 4},
        get_platform_y = function(polydef, rpos)
            return 1.3
        end,
        walkable = true,
        collision = false,
        points = {
            {-1.0,-3.4},
            {-1.4,-1.8},
            { 1.4,-1.8},
            { 1.0,-3.4},
        },
    },
    main_col = {
        height = {-1, 2},
        walkable = false,
        collision = true,
        points = {
            {-1.0,-3.4},
            {-1.5,-1.8},
            {-2.0, 1.7},
            {-2.0, 6.1},
            { 0.0, 11.5},
            { 2.0, 6.1},
            { 2.0, 1.7},
            { 1.5,-1.8},
            { 1.0,-3.4},
        },
    },
}
do local ox = aom_longship.ship._aomv_pointcloud_offset.x
for pname, pdef in pairs(aom_longship.ship._aomv_polygon) do
for i, point in ipairs(pdef.points) do
    point[1] = point[1] + ox
end end end

aom_longship.ship._aomv_pointcloud = {
    {pos = vector.new( 0, 2.4, 12.0), dir = vector.new( 0, 0, 1)},
    {pos = vector.new( 0, 1.4, 11.0), dir = vector.new( 0, 0, 1)},
    {pos = vector.new( 0, 0.4, 10.7), dir = vector.new( 0, 0, 1)},
    {pos = vector.new( 0,-0.2, 10.1), dir = vector.new( 0, 0, 1)},

    {pos = vector.new( 0, 0.5, 8), dir = vector.new( 0, 0, 1)},
    {pos = vector.new( 0,-0.5, 8), dir = vector.new( 0, 0, 1)},

    {pos = vector.new( 0.9, 0.7, 10.5), dir = vector.new( 0.8, 0, 0.4)},
    {pos = vector.new(-0.9, 0.7, 10.5), dir = vector.new(-0.8, 0, 0.4)},

    {pos = vector.new( 1.5,-0.1, 8), dir = vector.new( 1, 0, 0)},
    {pos = vector.new(-1.5,-0.1, 8), dir = vector.new(-1, 0, 0)},

    {pos = vector.new( 1.7,-0.1, 6), dir = vector.new( 1, 0, 0)},
    {pos = vector.new(-1.7,-0.1, 6), dir = vector.new(-1, 0, 0)},

    {pos = vector.new( 1.5,-0.1, 3), dir = vector.new( 1, 0, 0)},
    {pos = vector.new(-1.5,-0.1, 3), dir = vector.new(-1, 0, 0)},

    {pos = vector.new( 1.4,-0.1, 0), dir = vector.new( 1, 0, 0)},
    {pos = vector.new(-1.4,-0.1, 0), dir = vector.new(-1, 0, 0)},

    {pos = vector.new( 1.4,-0.1,-2), dir = vector.new( 1, 0, 0)},
    {pos = vector.new(-1.4,-0.1,-2), dir = vector.new(-1, 0, 0)},

    {pos = vector.new( 0.0, 2.0,-4), dir = vector.new( 0, 0,-1)},
    {pos = vector.new( 0.0,-0.2,-3), dir = vector.new( 0, 0,-1)},
    --mast
    {pos = vector.new( 0, 9, 3.5), dir = vector.new( 0, 0, 1.1)},
    {pos = vector.new( 0, 9, 2.5), dir = vector.new( 0, 0, -1)},
}
do local offset = aom_longship.ship._aomv_pointcloud_offset
for i, pdef in ipairs(aom_longship.ship._aomv_pointcloud) do
    pdef.pos = pdef.pos + offset
end end

-----------------------
--    SHIP SOUNDS    --
-----------------------

aom_longship.sounds = {
    bow_waves = {
        auto_loop = true,
        length = 5,
        name = "aom_longship_bow_waves",
        gain = 2, loop = true, fade = 0.1, max_hear_distance = 100,
        on_refresh = function(self, meta, DEF)
            if meta.id then
                local speed_factor = vector.length(self.object:get_velocity())
                speed_factor = aom_vehicleapi.clamp(speed_factor / 10, 0, 1)
                speed_factor = speed_factor ^ 2
                if speed_factor < 0.001 then speed_factor = 0.0001
                elseif speed_factor * 2 < 0.1 then speed_factor = speed_factor * 2
                end
                -- minetest.log(minetest.colorize("#090", "fading to " .. (speed_factor * (DEF.gain or 1))))
                minetest.sound_fade(meta.id, DEF.fade or 0.1, speed_factor * (DEF.gain or 1))
            end
        end,
    },
    creaking_low = {
        auto_loop = true,
        length = 30,
        name = "aom_longship_creaking",
        gain = 0.2, loop = true, pitch = 0.5,
        on_refresh = function(self, meta, DEF)
            if meta.id then
                local gain = DEF.gain
                if self._ctrl_sail ~= 0 then
                    gain = 0.000001
                end
                minetest.sound_fade(meta.id, 0.1, gain)
            end
        end,
    },
    creaking = {
        auto_loop = true,
        length = 30,
        name = "aom_longship_creaking",
        gain = 0.1, loop = true, pitch = 0.8,
        on_refresh = function(self, meta, DEF)
            if meta.id then
                local gain = DEF.gain
                if self._ctrl_sail ~= 0 then
                    gain = 0.000001
                end
                minetest.sound_fade(meta.id, 0.1, gain)
            end
        end,
    },
}

minetest.register_entity("aom_longship:longship_ENTITY", aom_longship.ship)

-----------------------
--  ITEMS AND CRAFT  --
-----------------------

minetest.register_craftitem("aom_longship:longship", {
    description = "Longship",
    liquids_pointable = true,
    inventory_image = "aom_longship_inv.png",
    groups = {vehicle = 1, tools = 1},
    on_place = function(itemstack, placer, pointed_thing)
        if not minetest.is_player(placer) then return end
        -- local node = minetest.get_node(pointed_thing.under)
        -- if minetest.get_item_group(node.name, "water") <= 0 then return end
        local pos = vector.offset(pointed_thing.under, 0, 1.3, 0)
        local yaw = placer:get_look_horizontal()
        local colpc = aom_longship.ship._aomv_pointcloud
        local is_colliding = aom_vehicleapi.get_pointcloud_collision(pos, yaw, colpc, nil, aom_longship.ship._aomv_pointcloud_offset)
        if is_colliding then return end

        local obj = minetest.add_entity(pos, "aom_longship:longship_ENTITY")
        if obj then
            if not minetest.is_creative_enabled(placer:get_player_name()) then
                itemstack:take_item()
            end
            obj:set_yaw(placer:get_look_horizontal())
            local ent = obj:get_luaentity()
            ent._collision_continue_time = 8
        end
        return itemstack
    end,
})

minetest.register_craftitem("aom_longship:hull_planks", {
    description = S("Hull Planks"),
    _tt_long_desc = S("Used to make ships."),
    liquids_pointable = true,
    inventory_image = "aom_longship_hull_planks.png",
    groups = {ingredients = 1, goods = 1},
})

aom_tcraft.register_group_craft({
    output = "aom_longship:hull_planks",
    items = {
        ["aom_longship:bronze_nails"] = 1,
    },
    group = "planks",
    group_count = 2
})

minetest.register_craftitem("aom_longship:bronze_nails", {
    description = S("Bronze Nails"),
    _tt_long_desc = S("Used to make ships."),
    liquids_pointable = true,
    inventory_image = "aom_longship_bronze_nails.png",
    groups = {ingredients = 1, goods = 1},
})

aom_tcraft.register_craft({
    output = "aom_longship:bronze_nails 8",
    items = {
        ["aom_items:bronze_bar"] = 1,
    }
})

--[[
    Totals:
- bronze = 30 --> (40/8) + (200/8)
- wood = 400
- iron = 12
- plant fibre = 160 flax plants worth
]]
aom_tcraft.register_craft({
    output = "aom_longship:longship",
    items = {
        ["aom_longship:bronze_nails"] = 40,
        ["aom_longship:hull_planks"] = 200,
        ["aom_items:plant_fibre"] = 160,
        ["aom_items:iron_bar"] = 12,
    },
    tags = {
      "tools"
    }
})
