local Badge = require "widgets/badge"
local easing = require "easing"
local MakePlayerCharacter = require "prefabs/player_common"


local assets = {

        Asset( "ANIM", "anim/player_basic.zip" ),
        Asset( "ANIM", "anim/player_idles_shiver.zip" ),
        Asset( "ANIM", "anim/player_actions.zip" ),
        Asset( "ANIM", "anim/player_actions_axe.zip" ),
        Asset( "ANIM", "anim/player_actions_pickaxe.zip" ),
        Asset( "ANIM", "anim/player_actions_shovel.zip" ),
        Asset( "ANIM", "anim/player_actions_blowdart.zip" ),
        Asset( "ANIM", "anim/player_actions_eat.zip" ),
        Asset( "ANIM", "anim/player_actions_item.zip" ),
        Asset( "ANIM", "anim/player_actions_uniqueitem.zip" ),
        Asset( "ANIM", "anim/player_actions_bugnet.zip" ),
        Asset( "ANIM", "anim/player_actions_fishing.zip" ),
        Asset( "ANIM", "anim/player_actions_boomerang.zip" ),
        Asset( "ANIM", "anim/player_bush_hat.zip" ),
        Asset( "ANIM", "anim/player_attacks.zip" ),
        Asset( "ANIM", "anim/player_idles.zip" ),
        Asset( "ANIM", "anim/player_rebirth.zip" ),
        Asset( "ANIM", "anim/player_jump.zip" ),
        Asset( "ANIM", "anim/player_warfarin.zip" ),
        Asset( "ANIM", "anim/player_amulet_resurrect.zip" ),
        Asset( "ANIM", "anim/player_teleport.zip" ),
        Asset( "ANIM", "anim/wilson_fx.zip" ),
        Asset( "ANIM", "anim/player_one_man_band.zip" ),
        Asset( "ANIM", "anim/shadow_hands.zip" ),
        Asset( "SOUND", "sound/sfx.fsb" ),
        Asset( "SOUND", "sound/maxwell.fsb" ),
        Asset( "ANIM", "anim/beard.zip" ), 
	Asset("ANIM", "anim/player_woodie.zip"),     
		-- Don't forget to include your character's custom assets!
        Asset( "ANIM", "anim/warfarin_sneak.zip" ),
        Asset( "ANIM", "anim/warfarin_pirate.zip" ),
        Asset( "ANIM", "anim/warfarinroll.zip" ),
        Asset( "ANIM", "anim/warfarinrollhood.zip" ),
	Asset("ANIM", "anim/warfarinblooddrop.zip"),
	Asset("ANIM", "anim/armor_sanity_warf.zip"),
        Asset( "ANIM", "anim/player_emotesxl.zip" ),
    Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
}
local prefabs = 
{
}

local start_inv = 
{
}	

--The hood is set as the hair symbol. Make it not be taken off when wearing hats!

local function givehoodback(inst)
	inst:DoTaskInTime(0, function()
local hat = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD)
	if not (hat and hat:HasTag("warfarinhood")) then
	        inst.AnimState:Show("HAIR")
		end

--Also patching Warfarin's habit of pulling out the most recently equipped item when climbing trees.

local hat = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
	if not hat then
        inst.AnimState:ClearOverrideSymbol("swap_object")
		end
local body = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY)
		if body and not (body:HasTag("sanity") or body:HasTag("amulet") or body.components.container or body:HasTag("amulet")) then 
	        inst.AnimState:Hide("HAIR")
	        inst.AnimState:Hide("HAIR_HAT")
		if body and (body.components.container or body:HasTag("amulet")) then 
	        inst.AnimState:Show("HAIR")
	        inst.AnimState:Show("HAIR_HAT")
		end
		elseif body and (body.components.container or body:HasTag("amulet") or body:HasTag("sanity")) then 
	        inst.AnimState:Show("HAIR")
	        inst.AnimState:Show("HAIR_HAT")
		if body:HasTag("sanity") then 
   		inst.AnimState:OverrideSymbol("swap_body", "armor_sanity_warf", "swap_body")
			end
		else
	        inst.AnimState:Show("HAIR")
	        inst.AnimState:Show("HAIR_HAT")
		end
	end)
end

local SneakBadge = Class(Badge, function(self, owner)
	Badge._ctor(self, "beaver_meter", owner)
end)

--Smokebomb wore off!

local function visible(inst)
		SpawnPrefab("chester_transform_fx").Transform:SetPosition(inst:GetPosition():Get())
    inst:RemoveTag("notarget")
    inst:RemoveTag("smokebombed")
local equippedHat = inst.components.inventory and inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD)
 if equippedHat and equippedHat:HasTag("warfarinhood") then
    inst:AddTag("notarget")
		end
end

--The smokebomb and its running code is remoed when eaten. Make Warfarin do the stuff!

local function smokebomb(inst, food)
        if inst.components.eater and food.components.edible.foodtype == "SMOKEBOMB" then
    local pt = inst:GetPosition()
    local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, 20)

    for k,v in pairs(ents) do
        if v.components.combat and v.components.combat.target and v.components.combat.target == inst then
            v.components.combat:SetTarget(nil)
		SpawnPrefab("sparklefx").Transform:SetPosition(v:GetPosition():Get())
        end
    end

    inst:AddTag("notarget")
    inst:AddTag("smokebombed")
	inst:DoTaskInTime(2, function() visible(inst) end)
               local smokeFX = SpawnPrefab("chester_transform_fx")
		SpawnPrefab("collapse_big").Transform:SetPosition(inst:GetPosition():Get())
                inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/pop")
	end
end

--What emote should Warfarin do.

local function ontalk(inst, data)
		if not inst:HasTag("isintree") then
		if inst:HasTag("warfarinsaybad") then
    local heart = SpawnPrefab("warfarinheart2")
	    local follower = heart.entity:AddFollower()
	    follower:FollowSymbol(inst.GUID, "HEAD", 0, -200, 0 )
        inst:RemoveTag("warfarinsaybad")
        if inst.sg:HasStateTag("idle") then
				inst.sg:GoToState("talkscared") 
	end
		elseif inst:HasTag("warfarinsaygood") then
    local heart = SpawnPrefab("warfarinheart")
	    local follower = heart.entity:AddFollower()
	    follower:FollowSymbol(inst.GUID, "HEAD", 0, -200, 0 )
        inst:RemoveTag("warfarinsaygood")
        if inst.sg:HasStateTag("idle") then
			inst.SoundEmitter:PlaySound("dontstarve/characters/warfarin/hurt")
				inst.sg:GoToState("talkwave") 
	end
		else
    local heart = SpawnPrefab("warfarinheart3")
	    local follower = heart.entity:AddFollower()
	    follower:FollowSymbol(inst.GUID, "HEAD", 0, -200, 0 )
        if inst.sg:HasStateTag("idle") then
				inst.sg:GoToState("talk") 
			end
		end
	end
end

local function killfaithe(inst)
    local faithe = TheSim:FindFirstEntityWithTag("faithe")
    if faithe then
		faithe.components.container:DestroyContents()
		faithe:Remove()
    inst:RemoveEventCallback("resurrect", killfaithe, inst)
	end
end

--Make enemies not be alerted by an ally being backstabbed

local function deaddontsee(inst, data)
	if data.cause == inst.prefab 
and data.inst.components.combat and data.inst.components.combat.target and data.inst.components.combat.target == inst then
            data.inst.components.combat:SetTarget(nil)
	end
end

local fn = function(inst)

	--speech sound and map icon
	inst.soundsname = "warfarin"
    inst.MiniMapEntity:SetIcon("warfarin.tex")

	inst.AnimState:SetBuild("warfarin")
	--Stats
        inst.components.health:SetMaxHealth(45)
	inst.components.hunger:SetMax(100)
	inst.components.sanity:SetMax(100)
	inst.components.combat.damagemultiplier = 0.75
	inst.components.locomotor.walkspeed = (TUNING.WILSON_WALK_SPEED * 1.1)
	inst.components.locomotor.runspeed = (TUNING.WILSON_RUN_SPEED * 1.1)
	inst.components.sanity.neg_aura_mult = 1.2	
    inst.components.sanity.night_drain_mult = 0.2
    inst.components.talker.special_speech = true
    inst.components.talker.ontalk = ontalk
	inst.components.combat.attackrange = 2
	inst.components.combat.hitrange = 3
	inst.components.combat.min_attack_period = 0.1

	--Warfarin is smaller than the others
	inst.Transform:SetScale(0.95, 0.95, 0.95)

	inst:AddComponent("colourtweener")
        inst.components.eater:SetOnEatFn(smokebomb)

	table.insert(inst.components.eater.foodprefs, "SMOKEBOMB")


		--Put the stealth into a separate component. It's crude, but works
		inst:AddComponent("warfarinsneak")

-- Set up the sneak badge

	inst.task = inst:DoPeriodicTask(2/10, function()

	if inst.HUD and not inst.HUD.controls.sneakbadge then
   if inst.task then
        inst.task:Cancel()
        inst.task = nil
    end
			inst.HUD.controls.sneakbadge = GetPlayer().HUD.controls.sidepanel:AddChild(SneakBadge(inst))
			inst.HUD.controls.sneakbadge:SetPosition(-100,-200,0)
			inst.HUD.controls.sneakbadge.anim:GetAnimState():SetBuild("warfarinsneak")
		    inst.HUD.controls.sneakbadge:SetPercent(0)
			inst.HUD.controls.sneakbadge.inst:ListenForEvent("warfarinsneakdelta", function(_, data) 
				inst.HUD.controls.sneakbadge:SetPercent(inst.components.warfarinsneak:GetPercent(), inst.components.warfarinsneak.max)

					if data.newpercent > data.oldpercent then
						inst.HUD.controls.sneakbadge:PulseGreen()
					elseif data.newpercent < data.oldpercent then
						inst.HUD.controls.sneakbadge:PulseRed()
	local pt = Vector3(inst.Transform:GetWorldPosition())
if GetClock():IsNight() or GetWorld():IsCave() then
	local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 1, {"hostile"}, {"tree"})
						if #ents > 0 and not inst.components.combat.target then
		inst.SoundEmitter:PlaySound("dontstarve/common/chest_trap")
							end
elseif GetClock():IsDusk() and not GetWorld():IsCave() then
	local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 3, {"hostile"}, {"tree"})
						if #ents > 0 and not inst.components.combat.target then
		inst.SoundEmitter:PlaySound("dontstarve/common/chest_trap")
							end
elseif GetClock():IsDay() and not GetWorld():IsCave() then
	local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 4, {"hostile"}, {"tree"})
						if #ents > 0 and not inst.components.combat.target then
		inst.SoundEmitter:PlaySound("dontstarve/common/chest_trap")
							end
	end
					end
			end, inst)
		end
end) 

	--To trigger the function when getting a stealth kill
    inst:ListenForEvent("entity_death", function(wrld, data) deaddontsee(inst, data) end, GetWorld())

--Recipes

local marble4 = Ingredient( "marble", 4)
local marble6 = Ingredient( "marble", 6)
local marble7 = Ingredient( "marble", 7)

if IsDLCEnabled(CAPY_DLC) then
marble4 = Ingredient( "limestone", 4)
marble6 = Ingredient( "limestone", 6)
marble7 = Ingredient( "limestone", 7)
	else
marble4 = Ingredient( "marble", 4)
marble6 = Ingredient( "marble", 6)
marble7 = Ingredient( "marble", 7)
	end

local warfarinknife = Ingredient( "warfarinknife", 2)
warfarinknife.atlas = "images/inventoryimages/warfarinknife.xml"

local warfarinarrow_normal = Ingredient( "warfarinarrow_normal", 1)
warfarinarrow_normal.atlas = "images/inventoryimages/warfarinarrow_normal.xml"

local warfarinbowarm = Ingredient( "warfarinbowarm", 2)
warfarinbowarm.atlas = "images/inventoryimages/warfarinbowarm.xml"

        local warfarindaggerrecipe = Recipe( ("warfarindagger"), { Ingredient("flint", 1), Ingredient("cutgrass", 3), Ingredient("twigs", 1)}, RECIPETABS.WARFARIN,  {SCIENCE = 0})
      warfarindaggerrecipe.atlas = "images/inventoryimages/warfarindagger.xml"

        local warfarindagger_marblerecipe = Recipe( ("warfarindagger_marble"), { marble4, Ingredient("rope", 1), Ingredient("twigs", 4)}, RECIPETABS.WARFARIN,  {SCIENCE = 2})
      warfarindagger_marblerecipe.atlas = "images/inventoryimages/warfarindagger_marble.xml"

        local warfarindagger_liarrecipe = Recipe( ("warfarindagger_liar"), { marble6, Ingredient("purplegem", 3), Ingredient("nightmarefuel", 6)}, RECIPETABS.WARFARIN,  {MAGIC = 8})
      warfarindagger_liarrecipe.atlas = "images/inventoryimages/warfarindagger_liar.xml"

        local warfarinkniferecipe = Recipe( ("warfarinknife"), { Ingredient("flint", 1), Ingredient("rope", 1), Ingredient("twigs", 3)}, RECIPETABS.WARFARIN,  {SCIENCE = 1}, nil, nil, nil, 2 )
      warfarinkniferecipe.atlas = "images/inventoryimages/warfarinknife.xml"

        local warfarinknifeexrecipe = Recipe( ("warfarinknifeex"), { warfarinknife, Ingredient("gunpowder", 1), Ingredient("papyrus", 2)}, RECIPETABS.WARFARIN,  {SCIENCE = 2}, nil, nil, nil, 2 )
      warfarinknifeexrecipe.atlas = "images/inventoryimages/warfarinknifeex.xml"

        local warfarinsmokebomb = Recipe( ("warfarinsmokebomb"), { Ingredient("nitre", 1), Ingredient("honey", 6), Ingredient("tallbirdegg", 1)}, RECIPETABS.WARFARIN,  {SCIENCE = 2})
      warfarinsmokebomb.atlas = "images/inventoryimages/warfarinsmokebomb.xml"

        local warfarinarrow_normalrecipe = Recipe( ("warfarinarrow_normal"), { Ingredient("flint", 1), Ingredient("feather_crow", 1), Ingredient("twigs", 1)}, RECIPETABS.WARFARIN,  {SCIENCE = 1})
      warfarinarrow_normalrecipe.atlas = "images/inventoryimages/warfarinarrow_normal.xml"

        local warfarinarrow_rockrecipe = Recipe( ("warfarinarrow_rock"), { Ingredient("rocks", 1), Ingredient("feather_crow", 1), Ingredient("twigs", 2)}, RECIPETABS.WARFARIN,  {SCIENCE = 1}, nil, nil, nil, 2 )
      warfarinarrow_rockrecipe.atlas = "images/inventoryimages/warfarinarrow_rock.xml"

--Checking for Reign of Giants to set stategraph and add water arrow

if IsDLCEnabled(REIGN_OF_GIANTS) or IsDLCEnabled(CAPY_DLC) then
if IsDLCEnabled(REIGN_OF_GIANTS) then
print("Reign of Giants")
        inst:SetStateGraph("SGwarfarindlc")
	else
print("Shipwrecked")
        inst:SetStateGraph("SGwarfarindlc2")
	inst.AnimState:SetBuild("warfarin_pirate")
	        inst.AnimState:Hide("SKIRT")
		inst.components.driver.landstategraph = "SGwarfarindlc2"
		inst.components.driver.boatingstategraph = "SGwarfarinboating"
	end
        local warfarinarrow_waterrecipe = Recipe( ("warfarinarrow_water"), { Ingredient("ice", 1), Ingredient("feather_robin_winter", 1), Ingredient("twigs", 1)}, RECIPETABS.WARFARIN,  {SCIENCE = 2})
      warfarinarrow_waterrecipe.atlas = "images/inventoryimages/warfarinarrow_water.xml"
	table.insert(inst.components.eater.ablefoods, "SMOKEBOMB")
		else
        inst:SetStateGraph("SGwarfarin")
	end

        local warfarinarrow_firerecipe = Recipe( ("warfarinarrow_fire"), { Ingredient("gunpowder", 1), Ingredient("feather_robin", 1), Ingredient("twigs", 1)}, RECIPETABS.WARFARIN,  {SCIENCE = 2})
      warfarinarrow_firerecipe.atlas = "images/inventoryimages/warfarinarrow_fire.xml"

        local warfarinbowarmrecipe = Recipe( ("warfarinbowarm"), { Ingredient("cutstone", 1), Ingredient("goldnugget", 2), Ingredient("log", 2)}, RECIPETABS.WARFARIN,  {SCIENCE = 2})
      warfarinbowarmrecipe.atlas = "images/inventoryimages/warfarinbowarm.xml"

        local warfarinbowrecipe = Recipe( ("warfarinbow"), { warfarinbowarm, Ingredient("rope", 6), Ingredient("boomerang", 1)}, RECIPETABS.WARFARIN,  {SCIENCE = 2})
      warfarinbowrecipe.atlas = "images/inventoryimages/warfarinbow.xml"

        local hat_warfarinhoodrecipe = Recipe( ("hat_warfarinhood"), { Ingredient("trunk_summer", 1), Ingredient("beefalowool", 4), Ingredient("petals_evil", 16)}, RECIPETABS.WARFARIN,  {MAGIC = 3})
      hat_warfarinhoodrecipe.atlas = "images/inventoryimages/hat_warfarinhood.xml"

        local hat_warfarinmaskrecipe = Recipe( ("hat_warfarinmask"), { marble7, Ingredient("nightmarefuel", 7), Ingredient("petals_evil", 16)}, RECIPETABS.WARFARIN,  {MAGIC = 8})
      hat_warfarinmaskrecipe.atlas = "images/inventoryimages/hat_warfarinmask.xml"

if IsDLCEnabled(CAPY_DLC) then
        local warfarincutlassrecipe = Recipe( ("warfarincutlass"), { Ingredient("coral", 6), Ingredient("venomgland", 2), Ingredient("purplegem", 3)}, RECIPETABS.WARFARIN,  {MAGIC = 3})
      warfarincutlassrecipe.atlas = "images/inventoryimages/warfarincutlass.xml"
end

 -- String overrides. Much simpler than adding whole new functions.

 function inst:ActionStringOverride(bufaction)
	if bufaction.action == ACTIONS.EAT and
	 bufaction.invobject and
	 bufaction.invobject.prefab and
	 bufaction.invobject.prefab:match("^warfarinsmokebom") then
		return "Toss"
	end
	if bufaction.action == ACTIONS.RUMMAGE and
	 bufaction.invobject and
	 bufaction.invobject.prefab and
	 bufaction.invobject.prefab:match("^warfarinbow") then
		return "Arrow Tab"
	end
	if bufaction.action == ACTIONS.ACTIVATE and
	 bufaction.target and
	 bufaction.target.prefab and
	 bufaction.target.prefab:match("kingoflies_intro") then
		return "Greet"
	end
	local hand = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) 
	if bufaction.action == ACTIONS.LOOKAT then
	 if bufaction.target and
	 bufaction.target.components.combat and
 hand and hand:HasTag("liardagger") and not TheInput:IsControlPressed(CONTROL_FORCE_INSPECT) then
		return "Attack"
		else
		return "Examine"
		end
	end
	if bufaction.action == ACTIONS.ADDFUEL and bufaction.invobject.prefab and bufaction.invobject.prefab:match("^warfarinammo") then
		return "Reload"
	end
end

	--Say when to fix the hood

	inst:ListenForEvent("equip", givehoodback)
	inst:ListenForEvent("unequip", givehoodback)

	--Quick pickin'!
	
	local handle = inst.sg.sg.actionhandlers[ACTIONS.HARVEST]
handle.deststate = function(inst) return "doshortaction" end
	local handle = inst.sg.sg.actionhandlers[ACTIONS.PICK]
handle.deststate = function(inst) return "doshortaction" end

-- Fix double Faithe when dying in caves

        inst:ListenForEvent( "death", function(it, data) 
		if GetWorld():IsCave() then
    inst:ListenForEvent("resurrect", killfaithe, inst)  
		end
            end)  

end

return MakePlayerCharacter("warfarin", prefabs, assets, fn , start_inv)