local STRINGS = GLOBAL.STRINGS
RECIPETABS = GLOBAL.RECIPETABS
Recipe = GLOBAL.Recipe
Ingredient = GLOBAL.Ingredient
TECH = GLOBAL.TECH
local TUNING = GLOBAL.TUNING
local ACTIONS = GLOBAL.ACTIONS
local Action = GLOBAL.Action
local require = GLOBAL.require

local AllRecipes = GLOBAL.AllRecipes

local GetValidRecipe = GLOBAL.GetValidRecipe
local RECIPETABS = GLOBAL.RECIPETABS

local TheInput = GLOBAL.TheInput
local ThePlayer = GLOBAL.ThePlayer
local IsServer = GLOBAL.TheNet:GetIsServer()

-- statue spot --
-- AddRecipe stuff --

local ExtraEquipSlot = GetModConfigData("ExtraEquipSlot") or "false"
local True = (GetModConfigData("Mode")=="true")

GLOBAL.EQUIPSLOTS.NECK = "neck"

function whiteamuletpostinit(inst)
	if ExtraEquipSlot=="true" then
    if IsServer then
        inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.NECK or GLOBAL.EQUIPSLOTS.BODY
    end
	elseif ExtraEquipSlot=="false" then
end
end

AddPrefabPostInit("whiteamulet", whiteamuletpostinit)

-- =============================================================================================================================================================
-- =============================================================================================================================================================
-- =============================================================================================================================================================

local FRAMES = GLOBAL.FRAMES
local ACTIONS = GLOBAL.ACTIONS
local State = GLOBAL.State
local EventHandler = GLOBAL.EventHandler
local ActionHandler = GLOBAL.ActionHandler
local TimeEvent = GLOBAL.TimeEvent
local EQUIPSLOTS = GLOBAL.EQUIPSLOTS
local require = GLOBAL.require

local function DoAMountSound(inst, mount, sound, ispredicted)
    if mount ~= nil and mount.sounds ~= nil then
        inst.SoundEmitter:PlaySound(mount.sounds[sound], nil, nil, ispredicted)
    end
end

local function DoAMountSoundForClient(inst, mount, sound)
    if mount ~= nil and mount.sounds ~= nil then
        inst.SoundEmitter:PlaySound(mount.sounds[sound], nil, nil, true)
    end
end

local overhead = State({
        name = "maceattack",
        tags = { "attack", "notalking", "abouttoattack", "autopredict" },

        onenter = function(inst)
            local buffaction = inst:GetBufferedAction()
            local target = buffaction ~= nil and buffaction.target or nil
            local equip = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
            inst.components.combat:SetTarget(target)
            inst.components.combat:StartAttack()
            inst.components.locomotor:Stop()
            local cooldown = inst.components.combat.min_attack_period + .5 * FRAMES
            if inst.components.rider ~= nil and inst.components.rider:IsRiding() then
                inst.AnimState:PlayAnimation("atk_pre")
                inst.AnimState:PushAnimation("atk", false)
                DoAMountSound(inst, inst.components.rider:GetMount(), "angry", true)
                cooldown = math.max(cooldown, 16 * FRAMES)
            elseif equip ~= nil and equip:HasTag("mace") then
                inst.AnimState:PlayAnimation("pickaxe_loop")
				inst.AnimState:PushAnimation("pickaxe_pst", false)
                inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_weapon")
                cooldown = math.max(cooldown, 16 * FRAMES)
            end

            inst.sg:SetTimeout(cooldown)

            if target ~= nil then
                inst.components.combat:BattleCry()
                if target:IsValid() then
                    inst:FacePoint(target:GetPosition())
                    inst.sg.statemem.attacktarget = target
                end
            end
        end,

        timeline =
        {
            TimeEvent(8 * FRAMES, function(inst)
                    inst:PerformBufferedAction()
                    inst.sg:RemoveStateTag("abouttoattack")
            end)
        },

        ontimeout = function(inst)
            inst.sg:RemoveStateTag("attack")
            inst.sg:AddStateTag("idle")
        end,

        events =
        {
            EventHandler("equip", function(inst) inst.sg:GoToState("idle") end),
            EventHandler("unequip", function(inst) inst.sg:GoToState("idle") end),
            EventHandler("animqueueover", function(inst)
                if inst.AnimState:AnimDone() then
                    inst.sg:GoToState("idle")
                end
            end),
        },

        onexit = function(inst)
            inst.components.combat:SetTarget(nil)
            if inst.sg:HasStateTag("abouttoattack") then
                inst.components.combat:CancelAttack()
            end
        end,
    }
)

AddStategraphState("wilson", overhead)

local overhead_client = State({
	name = "maceattack",
        tags = { "attack", "notalking", "abouttoattack" },

        onenter = function(inst)
            local cooldown = 0
            if inst.replica.combat ~= nil then
                inst.replica.combat:StartAttack()
                cooldown = inst.replica.combat:MinAttackPeriod() + .5 * FRAMES
            end
            inst.components.locomotor:Stop()
            local equip = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
            local rider = inst.replica.rider
            if rider ~= nil and rider:IsRiding() then
                inst.AnimState:PlayAnimation("atk_pre")
                inst.AnimState:PushAnimation("atk", false)
                DoAMountSoundForClient(inst, rider:GetMount(), "angry")
                if cooldown > 0 then
                    cooldown = math.max(cooldown, 16 * FRAMES)
                end
            elseif equip ~= nil and equip:HasTag("mace") then
                inst.AnimState:PlayAnimation("pickaxe_loop")
				inst.AnimState:PushAnimation("pickaxe_pst", false)
                if cooldown > 0 then
                    cooldown = math.max(cooldown, 16 * FRAMES)
                end
            end

            local buffaction = inst:GetBufferedAction()
            if buffaction ~= nil then
                inst:PerformPreviewBufferedAction()

                if buffaction.target ~= nil and buffaction.target:IsValid() then
                    inst:FacePoint(buffaction.target:GetPosition())
                    inst.sg.statemem.attacktarget = buffaction.target
                end
            end

            if cooldown > 0 then
                inst.sg:SetTimeout(cooldown)
            end
        end,

        timeline =
		{
            TimeEvent(8 * FRAMES, function(inst)
                    inst:ClearBufferedAction()
                    inst.sg:RemoveStateTag("abouttoattack")
			end)
        },

        ontimeout = function(inst)
            inst.sg:RemoveStateTag("attack")
            inst.sg:AddStateTag("idle")
        end,

        events =
        {
            EventHandler("animqueueover", function(inst)
                if inst.AnimState:AnimDone() then
                    inst.sg:GoToState("idle")
                end
            end),
        },

        onexit = function(inst)
            if inst.sg:HasStateTag("abouttoattack") and inst.replica.combat ~= nil then
                inst.replica.combat:CancelAttack()
            end
        end,
	}
)

AddStategraphState("wilson_client", overhead_client)

--------------------------------------------WILSON SG ACTIONHANDLER FOR ATTACK OVERRIDE---------------------------------------------------------------------------


local SGWils = require "stategraphs/SGwilson"
local OriginalDestStateATTACK

for k1, v1 in pairs(SGWils.actionhandlers) do
	if SGWils.actionhandlers[k1]["action"]["id"] == "ATTACK" then
		OriginalDestStateATTACK = SGWils.actionhandlers[k1]["deststate"]
	end
end

local function NewDestStateATTACK(inst, action)
	inst.sg.mem.localchainattack = not action.forced or nil
	local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) or nil

	if weapon and weapon:HasTag("mace") and not inst.components.health:IsDead() and not inst.sg:HasStateTag("attack") and inst.components.combat ~= nil then
			return (weapon:HasTag("mace") and "maceattack")
	else
		return OriginalDestStateATTACK(inst, action)
	end
end

AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.ATTACK, NewDestStateATTACK))
GLOBAL.package.loaded["stategraphs/SGwilson"] = nil

--------------------------------------------WILSON_CLIENT SG ACTIONHANDLER FOR ATTACK OVERRIDE---------------------------------------------------------------------------

local SGWilsClient = require "stategraphs/SGwilson_client"
local OriginalClientDestStateATTACK

for k1, v1 in pairs(SGWilsClient.actionhandlers) do
	if SGWilsClient.actionhandlers[k1]["action"]["id"] == "ATTACK" then

		OriginalClientDestStateATTACK = SGWilsClient.actionhandlers[k1]["deststate"]
	end
end

local function NewClientDestStateATTACK(inst, action)
	local weapon = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) or nil
	if weapon and weapon:HasTag("mace") and not inst.sg:HasStateTag("attack") and inst.replica.combat then
		if inst.replica.combat then
			return (weapon:HasTag("mace") and "maceattack")
		end
	else
		return OriginalClientDestStateATTACK(inst, action)
	end
end

AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.ATTACK, NewClientDestStateATTACK))

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
GLOBAL.package.loaded["stategraphs/SGwilson_client"] = nil

AddPrefabPostInit("marblemace", function(inst)
    inst:AddTag("mace")
end)
