PrefabFiles = {
	"rakky",
	"rakkyboomerang",
}

Assets = {
    Asset( "IMAGE", "images/saveslot_portraits/rakky.tex" ),
    Asset( "ATLAS", "images/saveslot_portraits/rakky.xml" ),

    Asset( "IMAGE", "images/selectscreen_portraits/rakky.tex" ),
    Asset( "ATLAS", "images/selectscreen_portraits/rakky.xml" ),
	
    Asset( "IMAGE", "images/selectscreen_portraits/rakky_silho.tex" ),
    Asset( "ATLAS", "images/selectscreen_portraits/rakky_silho.xml" ),

    Asset( "IMAGE", "bigportraits/rakky.tex" ),
    Asset( "ATLAS", "bigportraits/rakky.xml" ),
	
	Asset( "IMAGE", "images/map_icons/rakky.tex" ),
	Asset( "ATLAS", "images/map_icons/rakky.xml" ),
	
	Asset( "IMAGE", "images/avatars/avatar_rakky.tex" ),
    Asset( "ATLAS", "images/avatars/avatar_rakky.xml" ),
	
	Asset( "IMAGE", "images/avatars/avatar_ghost_rakky.tex" ),
    Asset( "ATLAS", "images/avatars/avatar_ghost_rakky.xml" ),
	
	Asset("ANIM", "anim/rakky_spoiled_meter.zip"),
	
    Asset( "ATLAS", "images/hud/boomerangtab.xml" ),
	
	Asset("SOUNDPACKAGE", "sound/rakky.fev"),
    Asset("SOUND", "sound/rakky.fsb"),
}

RemapSoundEvent( "dontstarve/characters/rakky/death_voice", "rakky/characters/rakky/death_voice" )
RemapSoundEvent( "dontstarve/characters/rakky/hurt", "rakky/characters/rakky/hurt" )
RemapSoundEvent( "dontstarve/characters/rakky/talk_LP", "rakky/characters/rakky/talk_LP" )
RemapSoundEvent( "dontstarve/characters/rakky/emote", "rakky/characters/rakky/emote" )
RemapSoundEvent( "dontstarve/characters/rakky/ghost_LP", "rakky/characters/rakky/ghost_LP" )

local alt_spoilage_meter = (GetModConfigData("alt_spoilage_meter")=="default")
GLOBAL.rakky_voice = "default" --GetModConfigData("rakky_voice")

GetPlayer = GLOBAL.GetPlayer
ACTIONS = GLOBAL.ACTIONS

local require = GLOBAL.require
local STRINGS = GLOBAL.STRINGS

-- The character select screen lines
STRINGS.CHARACTER_TITLES.rakky = "The Kangarcoon"
STRINGS.CHARACTER_NAMES.rakky = "Rakky"
STRINGS.CHARACTER_DESCRIPTIONS.rakky = "*Good with boomerangs\n*Prefers food stale\n*Does not notice everything"
STRINGS.CHARACTER_QUOTES.rakky = "\"There's always adventure to be found!\""

-- Custom speech strings
STRINGS.CHARACTERS.RAKKY = require "speech_rakky"

-- Custom adjectives
STRINGS.UI.HUD.UNRIPE = "Unripe"

-- Custom items
STRINGS.NAMES.RAKKYBOOMERANG = "Adventurang"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKYBOOMERANG = "I feel more adventurous with this."
STRINGS.RECIPE_DESC.RAKKYBOOMERANG = "A decent combat boomerang."

STRINGS.NAMES.RAKKYBOOMERANG_CARROT = "Carrotrang"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKYBOOMERANG_CARROT = "At least I don't have to eat it."
STRINGS.RECIPE_DESC.RAKKYBOOMERANG_CARROT = "Nutritious and dangerous!"

STRINGS.NAMES.RAKKYBOOMERANG_FEATHER = "Featherang"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKYBOOMERANG_FEATHER = "Feathery!"
STRINGS.RECIPE_DESC.RAKKYBOOMERANG_FEATHER = "The feathers make it faster."

STRINGS.NAMES.RAKKYBOOMERANG_BAT = "Batarang"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKYBOOMERANG_BAT = "I'm Batman!"
STRINGS.RECIPE_DESC.RAKKYBOOMERANG_BAT = "A life-sucking boomerang."

STRINGS.NAMES.RAKKYBOOMERANG_SLEEP = "Slumberang"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKYBOOMERANG_SLEEP = "Just touching it makes me sleepy."
STRINGS.RECIPE_DESC.RAKKYBOOMERANG_SLEEP = "Soft as a pillow."

STRINGS.NAMES.RAKKYBOOMERANG_RUINS = "Catastrorang"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKYBOOMERANG_RUINS =
		{
		CALM = "It's not very powerful right now.",
		WARN = "I feel it becoming stronger.",
		CLIMAX = "The boomerang's power is at its peak!",
		COOL = "It's starting to cool down.",
		SUBCLIMAX = "It seems a bit angry.",
		}
STRINGS.RECIPE_DESC.RAKKYBOOMERANG_RUINS = "Predicts the end of the world."

-- DST 
STRINGS.NAMES.RAKKY = "Rakky"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAKKY = 
{
	GENERIC = "It's Rakky!",
	ATTACKER = "That Rakky looks shifty...",
	MURDERER = "Murderer!",
	REVIVER = "Rakky, friend of ghosts.",
	GHOST = "Rakky could use a heart.",
}


-- Boomerangs tab
local resolvefilepath = GLOBAL.resolvefilepath
local TECH = GLOBAL.TECH
local CUSTOM_RECIPETABS = GLOBAL.CUSTOM_RECIPETABS
CUSTOM_RECIPETABS.BOOMERANGS = { str = "BOOMERANGS", sort = 998, icon = "boomerangtab.tex", icon_atlas = resolvefilepath("images/hud/boomerangtab.xml") }
STRINGS.TABS.BOOMERANGS = "Boomerangs"

-- Add recipes. This must be in modmain.lua, not the character's prefab.
local rakkyboomerang_recipe = Recipe("rakkyboomerang", { Ingredient("houndstooth", 2), Ingredient("log", 3) }, CUSTOM_RECIPETABS.BOOMERANGS, TECH.NONE, nil, nil, nil, nil, "boomerangbuilder")
local rakkyboomerang_feather_recipe = Recipe("rakkyboomerang_feather", { Ingredient("stinger", 4), Ingredient("feather_robin", 4), Ingredient("feather_crow", 4) }, CUSTOM_RECIPETABS.BOOMERANGS, TECH.SCIENCE_ONE, nil, nil, nil, nil, "boomerangbuilder")
local rakkyboomerang_carrot_recipe = Recipe("rakkyboomerang_carrot", { Ingredient("carrot", 4), Ingredient("rope", 1), Ingredient("honey", 4) }, CUSTOM_RECIPETABS.BOOMERANGS, TECH.SCIENCE_TWO, nil, nil, nil, nil, "boomerangbuilder")
local rakkyboomerang_sleep_recipe = Recipe("rakkyboomerang_sleep", { Ingredient("feather_robin_winter", 4), Ingredient("silk", 6), Ingredient("goldnugget", 3) }, CUSTOM_RECIPETABS.BOOMERANGS, TECH.MAGIC_TWO, nil, nil, nil, nil, "boomerangbuilder") 
local rakkyboomerang_bat_recipe = Recipe("rakkyboomerang_bat", { Ingredient("monstermeat_dried", 4), Ingredient("livinglog", 2), Ingredient("tentaclespots", 1) }, CUSTOM_RECIPETABS.BOOMERANGS, TECH.MAGIC_THREE, nil, nil, nil, nil, "boomerangbuilder") -- TODO: Change "monstermeat_dried" to "batwing" when batilisks are re-implemented
local rakkyboomerang_ruins_recipe = Recipe("rakkyboomerang_ruins", { Ingredient("nightmare_timepiece", 1), Ingredient("walrus_tusk", 2), Ingredient("nightmarefuel", 4) }, CUSTOM_RECIPETABS.BOOMERANGS, TECH.ANCIENT_FOUR, nil, nil, true, nil, "boomerangbuilder")

rakkyboomerang_recipe.atlas = resolvefilepath("images/inventoryimages/rakkyboomerang.xml")
rakkyboomerang_feather_recipe.atlas = resolvefilepath("images/inventoryimages/rakkyboomerang_feather.xml")
rakkyboomerang_carrot_recipe.atlas = resolvefilepath("images/inventoryimages/rakkyboomerang_carrot.xml")
rakkyboomerang_sleep_recipe.atlas = resolvefilepath("images/inventoryimages/rakkyboomerang_sleep.xml")
rakkyboomerang_bat_recipe.atlas = resolvefilepath("images/inventoryimages/rakkyboomerang_bat.xml")
rakkyboomerang_ruins_recipe.atlas = resolvefilepath("images/inventoryimages/rakkyboomerang_ruins.xml")

-- Set the sort key in a range unique to this mod to fix mod compatibility issues. Other mods should avoid using this same range.
rakkyboomerang_recipe.sortkey = 8101
rakkyboomerang_feather_recipe.sortkey = 8102
rakkyboomerang_carrot_recipe.sortkey = 8103
rakkyboomerang_sleep_recipe.sortkey = 8104
rakkyboomerang_bat_recipe.sortkey = 8105
rakkyboomerang_ruins_recipe.sortkey = 8106

-- Add new tab
AddClassPostConstruct("widgets/crafttabs", function(class)
	if class.owner:HasTag("boomerangbuilder") then
		local v = CUSTOM_RECIPETABS.BOOMERANGS
		local k = #class.tab_order + 1
		local tab_bg = 
		{
			normal = "tab_normal.tex",
			selected = "tab_selected.tex",
			highlight = "tab_highlight.tex",
			bufferedhighlight = "tab_place.tex",
			overlay = "tab_researchable.tex",
		}
		
		class.tabs.spacing = 750/k
		local tab = class.tabs:AddTab(STRINGS.TABS[v.str], resolvefilepath("images/hud.xml"), v.icon_atlas or resolvefilepath("images/hud.xml"), v.icon, tab_bg.normal, tab_bg.selected, tab_bg.highlight, tab_bg.bufferedhighlight, tab_bg.overlay,
            
            function() --select fn
                if not class.controllercraftingopen then
                    
                    if class.craft_idx_by_tab[k] then
                        class.crafting.idx = class.craft_idx_by_tab[k]
                    end

                    class.crafting:SetFilter( 
                        function(recipe)
							local rec = GLOBAL.AllRecipes[recipe]
                            local builder = class.owner.replica.builder
                            return rec and rec.tab == v and (builder == nil or builder:CanLearn(recipe))
                        end)
                
                                                                            
                    class.crafting:Open()
                end
            end, 

            function() --deselect fn
                class.craft_idx_by_tab[k] = class.crafting.idx
                class.crafting:Close()
            end)
        tab.filter = v
        tab.icon = v.icon
        tab.icon_atlas = v.icon_atlas or resolvefilepath("images/hud.xml")
        tab.tabname = STRINGS.TABS[v.str]
        class.tabbyfilter[v] = tab
		
        table.insert(class.tab_order, tab)
	end
end)

-- Quick check if host
local IsMasterSim = function()
	if not GLOBAL.TheWorld.ismastersim then
		return false
	end
	return true
end

-- Quick check if RoG is enabled
local rogEnabled = function()
	return GLOBAL.IsDLCEnabled(GLOBAL.REIGN_OF_GIANTS)
end


-- Change the way food affects Rakky
AddComponentPostInit("edible", function(Edible, inst)
	Edible.unripe_hunger = GLOBAL.TUNING.STALE_FOOD_HUNGER
	Edible.unripe_health = GLOBAL.TUNING.STALE_FOOD_HEALTH
	
	Edible.GetSanity_rakky_redirect = Edible.GetSanity
	Edible.GetHunger_rakky_redirect = Edible.GetHunger
	Edible.GetHealth_rakky_redirect = Edible.GetHealth
	
	function Edible:GetSanity(eater)
		if eater and eater:HasTag("stalefoodeater") then
			local ignore_spoilage = (eater and eater.components.eater and eater.components.eater.ignoresspoilage) or self.sanityvalue < 0
			if self.inst.components.perishable and not ignore_spoilage then
				if self.inst.components.perishable:IsFresh() then
				-- IsFresh actually checks if unripe.
					if self.sanityvalue > 0 then
						return -TUNING.SANITY_TINY
					end
				end
			end
			
			return self.sanityvalue
		end
		return Edible:GetSanity_rakky_redirect(eater)
	end

	function Edible:GetHunger(eater)
		if eater and eater:HasTag("stalefoodeater") then
			local multiplier = 1
			
			local ignore_spoilage = (eater and eater.components.eater and eater.components.eater.ignoresspoilage) or self.hungervalue < 0
			
			if self.inst.components.perishable and not ignore_spoilage then
				if self.inst.components.perishable:IsFresh() then
					multiplier = self.unripe_hunger
				elseif self.inst.components.perishable:IsSpoiled() then
					multiplier = 1
				end
			end
			
			return multiplier*(self.hungervalue)
		end
		return Edible:GetHunger_rakky_redirect(eater)
	end

	function Edible:GetHealth(eater)
		if eater and eater:HasTag("stalefoodeater") then
			local multiplier = 1
			local healthvalue = self.gethealthfn and self.gethealthfn(self.inst, eater) or self.healthvalue

			local ignore_spoilage = (eater and eater.components.eater and eater.components.eater.ignoresspoilage) or healthvalue < 0
			
			if self.inst.components.perishable and not ignore_spoilage then
				if self.inst.components.perishable:IsFresh() then
					multiplier = self.unripe_health
				elseif self.inst.components.perishable:IsSpoiled() then
					multiplier = 1
				end
			end
			return multiplier*(healthvalue)
		end
		return Edible:GetHealth_rakky_redirect(eater)
	end
end)

-- Add veggiehorrible as a food type. This is used to allow non-player vegetarians to eat the Carrotrang
GLOBAL.FOODTYPE.VEGGIEHORRIBLE = "VEGGIEHORRIBLE"
AddComponentPostInit("eater", function(Eater, inst)
	function Eater:SetCanEatVeggieHorrible()
		table.insert(self.foodprefs, GLOBAL.FOODTYPE.VEGGIEHORRIBLE)
		self.inst:AddTag(GLOBAL.FOODTYPE.VEGGIEHORRIBLE.."_eater")
	end
	Eater.SetVegetarian_rakky_redirect = Eater.SetVegetarian
	function Eater:SetVegetarian(human)
		Eater:SetVegetarian_rakky_redirect(human)
		if not human then
			Eater:SetCanEatVeggieHorrible()
		end
	end	
end)

-- Add boomerang reaction to Rakky's boomerang (applies to all characters)
AddComponentPostInit("wisecracker", function(Wisecracker, inst)
	inst:ListenForEvent("attacked", function(inst, data)
		if data.weapon and data.weapon:HasTag("rakkyboomerang") then
			inst.components.talker:Say(GLOBAL.GetString(inst.prefab, "ANNOUNCE_BOOMERANG"))
		end
	end)
end)

-- Disallow talking when saying an empty string for Rakky only
AddComponentPostInit("talker", function(Talker, inst)
	Talker.Say_rakky_redirect = Talker.Say
	function Talker:Say(script, time, noanim, force, nobroadcast, colour)
		if inst.prefab == "rakky" and script == "" then return end
		Talker:Say_rakky_redirect(script, time, noanim, force, nobroadcast, colour)
	end
end)

-- Apply Rakky spoiled meter
local function rakkySpoiledMeter(class)
	if alt_spoilage_meter and GLOBAL.ThePlayer and GLOBAL.ThePlayer:HasTag("stalefoodeater") then
		if class.spoilage and (class.item:HasTag("spoiled") or class.item:HasTag("stale") or class.item:HasTag("fresh")) and not class.item:HasTag("frozen") and not class.item:HasTag("show_basic_spoilage") then
			class.spoilage:GetAnimState():SetBuild("rakky_spoiled_meter")
		else
			class.spoilage:GetAnimState():SetBuild("spoiled_meter")
		end
	end
end

AddClassPostConstruct("widgets/itemtile", rakkySpoiledMeter)

-- Add prefab post init for all prefabs. I would do just perishables if it'd work for clients.
local function AddPerishablePostInit(fn)
	AddPrefabPostInitAny( function(inst)
		if inst then fn(inst) end
	end)
end

-- Give fresh food the UNRIPE adjective and remove STALE adjective
AddPerishablePostInit(function(inst)
	inst.GetAdjective_rakky_redirect = inst.GetAdjective
	function inst:GetAdjective()
		if GLOBAL.ThePlayer and GLOBAL.ThePlayer:HasTag("stalefoodeater") then
			if inst:HasTag("fresh") then
				for k, v in pairs(GLOBAL.FOODTYPE) do
					if inst:HasTag("edible_"..v) then
						return GLOBAL.STRINGS.UI.HUD.UNRIPE
					end
				end
			end
		else
			return inst:GetAdjective_rakky_redirect()
		end
	end
		
end)

-- Add tag to force normal spoilage meter, since Rakky can't eat them
local useBasicSpoilage = function(inst)
	inst:AddTag("show_basic_spoilage")
end

AddPrefabPostInit("flowerhat", useBasicSpoilage)
AddPrefabPostInit("hambat", useBasicSpoilage)
AddPrefabPostInit("watermelonhat", useBasicSpoilage)
AddPrefabPostInit("hawaiianshirt", useBasicSpoilage)
AddPrefabPostInit("grass_umbrella", useBasicSpoilage)
AddPrefabPostInit("icehat", useBasicSpoilage)
--


AddMinimapAtlas("images/map_icons/rakky.xml")
AddModCharacter("rakky", "MALE")

