
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_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/wilson.fsb" ),
        Asset( "ANIM", "anim/beard.zip" ),

        Asset( "ANIM", "anim/rakky.zip" ),
		Asset( "ANIM", "anim/ghost_rakky_build.zip" ),
}
local prefabs = {
	"rakkyboomerang",
}

local start_inv = {
	-- Custom starting items
	"rakkyboomerang",
	-- Roasted berries are given to help out a starting player since they spoil quickly
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
	"berries_cooked",
}
local common_postinit = function(inst) 	
	-- Minimap icon
	inst.MiniMapEntity:SetIcon( "rakky.tex" )

    inst:AddTag("boomerangbuilder") -- This tag is used for Rakky's boomerang crafting tab
    inst:AddTag("stalefoodeater") -- This tag is used to tag this character as a stale food eater
	
end
local master_postinit = function(inst)		
	-- choose which sounds this character will play
	if rakky_voice ~= "default" then
		inst.soundsname = rakky_voice
	end
	
	-- Stats	
	inst.components.health:SetMaxHealth(150)
	inst.components.hunger:SetMax(150)
	inst.components.sanity:SetMax(200)
	
	
	local eater = inst.components.eater
	-- Adjust stale food multipliers 
	eater.stale_hunger = 1
    eater.stale_health = 1
	-- Adjust spoiled food multipliers
    eater.spoiled_hunger = 1
    eater.spoiled_health = 1
	
	
	-- Make catchables automatically caught as long as Rakky is not sleeping
	local catcher =  inst.components.catcher
    catcher.actiondistance = 3 -- Lowered to allow player to do other actions
    catcher.catchdistance = 3 -- Increased to prevent accidentally getting hit by boomerang
	--[[
	function catcher:ReadyToCatch()
		-- Rakky is ready to catch as long as he isn't sleeping or knocked out.
		return not inst.sg:HasStateTag("sleeping") and not inst.sg:HasStateTag("knockout")
	end
	]]
	function catcher:OnUpdate()
		if not catcher.inst:IsValid() then
			return
		end
		-- Rakky is ready to catch as long as he isn't sleeping or knocked out.
		local isreadytocatch = not inst.sg:HasStateTag("sleeping") and not inst.sg:HasStateTag("knockout")
		catcher.canact = false

		for k, v in pairs(catcher.watchlist) do
			if not k:IsValid() or k.components.projectile == nil or not k.components.projectile:IsThrown() then
				catcher:StopWatching(k)
			elseif isreadytocatch then
				local distsq = k:GetDistanceSqToInst(catcher.inst)
				if distsq <= catcher.catchdistance * catcher.catchdistance then
					catcher.inst:PushEvent("catch", { projectile = k })
					k:PushEvent("caught", { catcher = catcher.inst })
					k.components.projectile:Catch(catcher.inst)
					catcher:StopWatching(k)
				elseif not catcher.canact and distsq < catcher.actiondistance * catcher.actiondistance then
					catcher.canact = true
				end
			elseif not catcher.canact and k:IsNear(catcher.inst, catcher.actiondistance) then
				catcher.canact = true
			end
		end
	end
	
	-- Remove warning from Charlie
	local grue = inst.components.grue
	function grue:Start()
		self.inst:StartUpdatingComponent(self) 
		self.nextHitTime = 5+math.random()*5
		self.nextSoundTime = -1 -- This disables the warning sound
	end
	-- Since the warning sound time is reset when attacked by Charlie, I have to disable it again.
	inst:ListenForEvent("attackedbygrue", function(inst, data) 
		grue.nextSoundTime = -1 
	end)
	
	
	-- Disallow talking when saying an empty string
	-- (Moved to modmain.lua because talker is a client-sided component, but is added after commom_postinit is called. This means I can't do this in either common_postinit or master_postinit.)
	--[[
	local talker = inst.components.talker
	talker.Say_rakky_redirect = talker.Say
	function talker:Say(script, time, noanim, force, nobroadcast, colour)
		if script == "" then return end
		talker:Say_rakky_redirect(script, time, noanim, force, nobroadcast, colour)
	end
	]]
	
	-- Add new responses to eating things
	-- Note: The previous responses are actually still in effect, but I cleared the strings so Rakky actually says nothing for those.
	inst:ListenForEvent("oneatsomething", 
        function(inst, data) 
            if data.food and data.food.components.edible then				
				if data.food.prefab == "spoiled_food" then
					-- Add a response only for eating Rot, not spoiling food.
					inst.components.talker:Say(GetString(inst.prefab, "ANNOUNCE_EAT", "SPOILED2"))
				elseif data.food.components.edible:GetHealth(inst) < 0 and data.food.components.edible:GetSanity(inst) <= 0 then
					-- Add a response for eating fresh food, which is considered unripe to Rakky.
				elseif data.food.components.perishable and data.food.components.perishable:IsFresh() then
					inst.components.talker:Say(GetString(inst.prefab, "ANNOUNCE_EAT", "UNRIPE"))
				end
			end
        end)
end

return MakePlayerCharacter("rakky", prefabs, assets, common_postinit, master_postinit, start_inv)
