

pmb_combat.attack = {}


--[[
{
    -- multipliers is applied to this, then the max is used to actually reduce HP.
    base_damage = {
        sharp = 5
    },
    -- applied at the very end of an attack after everything else
    multiplier = {
        _crit = 2,
        sharp = 1,
    },
    knockback_mult = 1,
}
]]

local pl = {}

local function check_player(player)
    if not pl[player] then pl[player] = {
        armor = {},
    } end
end

local function fix_attack(atk)
    if not atk.multiplier then atk.multiplier = {} end
    if not atk.base_damage then atk.base_damage = {} end
    if not atk.knockback_mult then atk.knockback_mult = 1 end
    return atk
end

function pmb_combat.attack.send_attack(attacker, victim, atk)
    if (not attacker) or (not victim) then return end
    atk.attacker = attacker
    atk.victim = victim
    atk = fix_attack(atk)

    local v_armor
    if minetest.is_player(victim) then
        check_player(victim)
        v_armor = pl[victim].armor
    else
        v_armor = victim._pmb_combat_armor or {}
    end

    local a_armor
    if minetest.is_player(attacker) then
        check_player(attacker)
        a_armor = pl[attacker].armor
    else
        a_armor = attacker._pmb_combat_armor or {}
    end

    for i, armor in pairs(a_armor) do
        local def = minetest.registered_items[armor]
        if def and def.on_attacking then
            atk = def.on_attacking(atk) or atk
        end
    end
    for i, armor in pairs(v_armor) do
        local def = minetest.registered_items[armor]
        if def and def.on_attacked then
            atk = def.on_attacked(atk) or atk
        end
    end

    -- apply mults
    local maxdmg = 0
    for t, v in pairs(atk.base_damage) do
        if atk.multiplier[t] then
            atk.base_damage[t] = atk.multiplier[t] * atk.base_damage[t]
            if atk.base_damage[t] > maxdmg then maxdmg = atk.base_damage[t] end
        end
    end

    local hp = victim:get_hp()
    if hp - maxdmg <= 0 and victim._on_death then
        victim:set_hp(1, "combat")
        victim:_on_death(atk)
    else
        victim:set_hp(hp - maxdmg, "combat")
    end

    local apos = attacker:get_pos()
    local vpos = victim:get_pos()
    vpos.y = apos.y
    local dir = vector.direction(apos, vpos)
    victim:punch(attacker, 1, {
        full_punch_interval = 1,
        damage_groups = {sharp=0},
    }, dir)
    dir.y = 0.6
    victim:add_velocity(vector.multiply(dir, atk.knockback_mult))
end



