require("stategraphs/commonstates")

function TableConcat(t1,t2)
    for i=1,#t2 do
        t1[#t1+1] = t2[i]
    end
    return t1
end

local function onattackedfn(inst, data)
	if inst.components.health and not inst.components.health:IsDead() and 
	(not inst.sg:HasStateTag("busy") or inst.sg:HasStateTag("frozen")) then
		inst.sg:GoToState("hit")
	end
end

local function ondeathfn(inst, data)
	if inst.sg:HasStateTag("frozen") or inst.sg:HasStateTag("thawing") then
		inst.sg:GoToState("thaw_break", data)
	else
		inst.sg:GoToState("death", data)
	end
end

local actionhandlers =
{
	ActionHandler(ACTIONS.GOHOME, "gohome"),
	ActionHandler(ACTIONS.EAT, "eat"),
	ActionHandler(ACTIONS.ATTACK, "attack"),
	ActionHandler(ACTIONS.NUZZLE, "nuzzle"),
	ActionHandler(ACTIONS.PICKUP, "pickup"),
	ActionHandler(ACTIONS.DROP, "pickup"),
	ActionHandler(ACTIONS.DEPLOY, "pickup"),
	ActionHandler(ACTIONS.GIVE, "pickup"),
	ActionHandler(ACTIONS.GIVEALLTOPLAYER, "pickup"),
	ActionHandler(ACTIONS.GIVETOPLAYER, "pickup"),
	ActionHandler(ACTIONS.JUMPIN, "pickup"),
	ActionHandler(ACTIONS.SLEEPIN, "home"),
	ActionHandler(ACTIONS.FAN, "wake"),
	ActionHandler(ACTIONS.FEED, "pickup"),
	ActionHandler(ACTIONS.MIGRATE, "pickup"),
	ActionHandler(ACTIONS.FEED, "pickup"),
	ActionHandler(ACTIONS.COMBINESTACK, "pickup"),
	ActionHandler(ACTIONS.UNWRAP, "pickup"),
	
}

local mobCraftActions =
{
ActionHandler(ACTIONS.GOHOME, "gohome"),
	ActionHandler(ACTIONS.ATTACK, "attack"),
	ActionHandler(ACTIONS.FEED, "pickup"),
	ActionHandler(ACTIONS.PICKUP, "pickup"),
	ActionHandler(ACTIONS.PICK, "pickup"),
	ActionHandler(ACTIONS.DROP, "pickup"),
	ActionHandler(ACTIONS.SLEEPIN, "home"),
	ActionHandler(ACTIONS.ACTIVATE, "pickup"),
	ActionHandler(ACTIONS.GIVEALLTOPLAYER, "pickup"),
	ActionHandler(ACTIONS.GIVETOPLAYER, "pickup"),
	ActionHandler(ACTIONS.EAT, "eat"),
	ActionHandler(ACTIONS.HEAL, "pickup"),
	ActionHandler(ACTIONS.FAN, "pickup"),
	ActionHandler(ACTIONS.DIG, "pickup"),
	ActionHandler(ACTIONS.CHOP, "pickup"),
	ActionHandler(ACTIONS.MINE, "pickup"),
	ActionHandler(ACTIONS.COOK, "pickup"),
	ActionHandler(ACTIONS.FILL, "pickup"),
	ActionHandler(ACTIONS.DRY, "pickup"),
	ActionHandler(ACTIONS.ADDFUEL, "pickup"),
	ActionHandler(ACTIONS.ADDWETFUEL, "pickup"),
	ActionHandler(ACTIONS.LIGHT, "pickup"),
	ActionHandler(ACTIONS.BAIT, "pickup"),
	ActionHandler(ACTIONS.BUILD, "pickup"),
	ActionHandler(ACTIONS.PLANT, "pickup"),
	ActionHandler(ACTIONS.REPAIR, "pickup"),
	ActionHandler(ACTIONS.HARVEST, "pickup"),
	ActionHandler(ACTIONS.STORE, "pickup"),
	ActionHandler(ACTIONS.RUMMAGE, "pickup"),
	ActionHandler(ACTIONS.DEPLOY, "pickup"),
	ActionHandler(ACTIONS.HAMMER, "attack"),
	ActionHandler(ACTIONS.FERTILIZE, "pickup"),
	ActionHandler(ACTIONS.MURDER, "pickup"),
	ActionHandler(ACTIONS.UNLOCK, "pickup"),
	ActionHandler(ACTIONS.TURNOFF, "pickup"),
	ActionHandler(ACTIONS.TURNON, "pickup"),
	ActionHandler(ACTIONS.SEW, "pickup"),
	ActionHandler(ACTIONS.COMBINESTACK, "pickup"),
	ActionHandler(ACTIONS.UPGRADE, "pickup"),
	ActionHandler(ACTIONS.WRITE, "pickup"),
	ActionHandler(ACTIONS.FEEDPLAYER, "pickup"),
	ActionHandler(ACTIONS.TERRAFORM, "pickup"),
	ActionHandler(ACTIONS.NET, "attack"),
	ActionHandler(ACTIONS.CHECKTRAP, "pickup"),
	ActionHandler(ACTIONS.SHAVE, "pickup"),
	ActionHandler(ACTIONS.FISH, "pickup"),
	ActionHandler(ACTIONS.REEL, "pickup"),
	ActionHandler(ACTIONS.CATCH, "pickup"),
	ActionHandler(ACTIONS.TEACH, "pickup"),
	ActionHandler(ACTIONS.MANUALEXTINGUISH, "pickup"),
	ActionHandler(ACTIONS.RESETMINE, "pickup"),
	ActionHandler(ACTIONS.BLINK, "pickup"),
	--ActionHandler(ACTIONS.CHANGEIN, "changeskin"),
	ActionHandler(ACTIONS.SMOTHER, "pickup"),
	ActionHandler(ACTIONS.CASTSPELL, "pickup"),
	ActionHandler(ACTIONS.WRAPBUNDLE, "pickup"),
	ActionHandler(ACTIONS.UNWRAP, "pickup"),
	ActionHandler(ACTIONS.UNLOCK, "pickup"),
	ActionHandler(ACTIONS.USEKLAUSSACKKEY, "pickup"),
	}

local extraActions = 
{
	--ActionHandler(ACTIONS.SLEEPIN, "sleep"),
	ActionHandler(ACTIONS.TRAVEL, "pickup"),
	ActionHandler(ACTIONS.LOOKAT, "pickup"),
}

if MOBCRAFT == "Enable" then
	extraActions = mobCraftActions
end

actionhandlers = TableConcat(actionhandlers, extraActions)

local function SetSleeperAwakeState(inst)
    if inst.components.grue ~= nil then
        inst.components.grue:RemoveImmunity("sleeping")
    end
    if inst.components.talker ~= nil then
        inst.components.talker:StopIgnoringAll("sleeping")
    end
    if inst.components.firebug ~= nil then
        inst.components.firebug:Enable()
    end
    if inst.components.playercontroller ~= nil then
        inst.components.playercontroller:EnableMapControls(true)
        inst.components.playercontroller:Enable(true)
    end
    inst:OnWakeUp()
    inst.components.inventory:Show()
    inst:ShowActions(true)
	--inst.sg:GoToState("taunt")
end

local function SetSleeperSleepState(inst)
    if inst.components.grue ~= nil then
        inst.components.grue:AddImmunity("sleeping")
    end
    if inst.components.talker ~= nil then
        inst.components.talker:IgnoreAll("sleeping")
    end
    if inst.components.firebug ~= nil then
        inst.components.firebug:Disable()
    end
    if inst.components.playercontroller ~= nil then
        inst.components.playercontroller:EnableMapControls(false)
        inst.components.playercontroller:Enable(false)
    end
    inst:OnSleepIn()
    inst.components.inventory:Hide()
    inst:PushEvent("ms_closepopups")
    inst:ShowActions(false)
end

local events =
{
    --CommonHandlers.OnLocomote(false, true),
	EventHandler("locomote", function(inst, data)
        if inst.sg:HasStateTag("busy") or inst.sg:HasStateTag("sleeping") and not inst.sg:HasStateTag("home") then
            return
        end
        local is_moving = inst.sg:HasStateTag("moving")
        local should_move = inst.components.locomotor:WantsToMoveForward()

        if inst.sg:HasStateTag("home") or inst.sg:HasStateTag("home_waking") then -- wakeup on locomote
            if inst.sleepingbag ~= nil and inst.sg:HasStateTag("sleeping") and inst.sg:HasStateTag("home") then
                inst.sleepingbag.components.sleepingbag:DoWakeUp()
                inst.sleepingbag = nil
				inst:Show()
				--inst.AnimState:PushAnimation("pig_pickup")
				SetSleeperAwakeState(inst)
				--inst.AnimState:PushAnimation("pig_pickup")
				inst.sg:GoToState("idle")
				
            
				
            end 
			elseif is_moving and not should_move then
            inst.sg:GoToState("walk_stop")
        elseif not is_moving and should_move then
            inst.sg:GoToState("walk_start")
        elseif data.force_idle_state and not (is_moving or should_move or inst.sg:HasStateTag("idle")) then
            inst.sg:GoToState("idle")
        end
    end),
    EventHandler("attacked", onattackedfn),
    EventHandler("death", ondeathfn),
    CommonHandlers.OnSleep(),
    CommonHandlers.OnFreeze(),
    CommonHandlers.OnAttack(),
	EventHandler("ms_opengift",
        function(inst)
            if not inst.sg:HasStateTag("busy") then
                inst.sg:GoToState("opengift")
            end
        end),
}

local NUM_FX_VARIATIONS = 7
local MAX_RECENT_FX = 4
local MOVE_FX_INTERVAL = 3 * FRAMES
local MIN_FX_SCALE = .5
local MAX_FX_SCALE = 1.3
local FX_RAND_SCALE = math.sqrt(MAX_FX_SCALE - MIN_FX_SCALE)

local function SpawnMoveFx(inst)
    if math.random() < .4 then
        local fx = SpawnPrefab("lavae_move_fx")
        if fx ~= nil then
            if inst.sg.mem.recentfx == nil then
                inst.sg.mem.recentfx = {}
            end
            local recentcount = #inst.sg.mem.recentfx
            local rand = math.random(NUM_FX_VARIATIONS - recentcount)
            if recentcount > 0 then
                while table.contains(inst.sg.mem.recentfx, rand) do
                    rand = rand + 1
                end
                if recentcount >= MAX_RECENT_FX then
                    table.remove(inst.sg.mem.recentfx, 1)
                end
            end
            table.insert(inst.sg.mem.recentfx, rand)
            local basescale = inst.Transform:GetScale()
            local randscale = math.random() * FX_RAND_SCALE
            fx:SetVariation(rand, basescale * (MAX_FX_SCALE - randscale * randscale))
            fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
        end
    end
    inst.sg.mem.lastspawnmovefx = GetTime()
end

local states =
{
	State{
		name = "idle",
		tags = {"idle", "canrotate"},

		onenter = function(inst)
			inst.Physics:Stop()
			inst.AnimState:PlayAnimation("idle", true)
			inst.sg:SetTimeout(math.random(2, 4))
		end,

		ontimeout = function(inst)
			local hunger = inst.components.hunger
			if hunger then
				local play_random = math.random() <= 0.2
				if play_random and hunger:GetPercent() <= 0.25 then
					inst.sg:GoToState("hungry")
				elseif play_random and hunger:GetPercent() >= 0.25 and hunger:GetPercent() < 0.5 then
					inst.sg:GoToState("peckish")
				elseif play_random and hunger:GetPercent() >= 0.75 then
					inst.sg:GoToState(math.random() < 0.5 and "idle_spin" or "idle_hop")
				else
					inst.sg:GoToState("idle")
				end
			else
				inst.sg:GoToState("idle")
			end
		end
	},

	State{
		name = "attack",
		tags = {"attack", "canrotate", "busy", "jumping"},

		onenter = function(inst, target)
			inst.components.locomotor:Stop()
			inst.components.locomotor:EnableGroundSpeedMultiplier(false)

			inst.components.combat:StartAttack()
			inst.AnimState:PlayAnimation("atk_pre")
			inst.AnimState:PushAnimation("atk")
			inst.AnimState:PushAnimation("atk_pst", false)
		end,

		onexit = function(inst)
			inst.components.locomotor:Stop()
			inst.components.locomotor:EnableGroundSpeedMultiplier(true)
		end,

		timeline =
		{
			TimeEvent(16*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump")
				inst.Physics:SetMotorVelOverride(20,0,0) 
			end),
			TimeEvent(21*FRAMES, function(inst)
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/attack")
				inst.components.combat:DoAttack()
				inst:PerformBufferedAction()

			end),
			TimeEvent(23*FRAMES, function(inst)                     
				inst.Physics:ClearMotorVelOverride()
				inst.components.locomotor:Stop() 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
				PlayFootstep(inst)
			end),
		},

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

	State{
		name = "growup",
        tags = {"busy"},

        onenter = function(inst)
            inst.Physics:Stop()
			inst.userfunctions.SetTeen(inst)
			inst.sg:GoToState("idle")			
        end,

		timeline=
        {
		
        },

        events=
        {
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
        },
    },
	
	State{
		name = "gohome",
		tags = {"busy"},

		onenter = function(inst)
			inst.components.locomotor:StopMoving()
			inst.Physics:Stop()
			inst.AnimState:PlayAnimation("taunt")
		end,

		timeline =
		{
			TimeEvent(6*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump")
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/taunt")
			end),
			TimeEvent(17*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
			end),
		},

		events = 
		{
			EventHandler("animover", function(inst) inst:PerformBufferedAction() end),
		},
	},

	State{
        name = "opengift",
        tags = { "busy", "pausepredict" },

        onenter = function(inst)
            inst.components.locomotor:Stop()
            inst.components.locomotor:Clear()
            inst:ClearBufferedAction()

            --if IsNearDanger(inst) then
                --inst.sg.statemem.isdanger = true
                --inst.sg:GoToState("idle")
                --if inst.components.talker ~= nil then
                   -- inst.components.talker:Say(GetString(inst, "ANNOUNCE_NODANGERGIFT"))
                --end
                --return
           -- end

            inst.SoundEmitter:PlaySound("dontstarve/common/player_receives_gift")
            inst.AnimState:PlayAnimation("Idle", true)
            --inst.AnimState:PushAnimation("taunt", true)
            -- NOTE: the previously used ripping paper anim is called "giift_loop"

            if inst.components.playercontroller ~= nil then
                inst.components.playercontroller:RemotePausePrediction()
                inst.components.playercontroller:EnableMapControls(false)
                inst.components.playercontroller:Enable(false)
            end
            inst.components.inventory:Hide()
            inst:PushEvent("ms_closepopups")
            inst:ShowActions(false)
            inst:ShowGiftItemPopUp(true)

            if inst.components.giftreceiver ~= nil then
                inst.components.giftreceiver:OnStartOpenGift()
            end
        end,

        timeline =
        {
            -- Timing of the gift box opening animation on giftitempopup.lua
            TimeEvent(155 * FRAMES, function(inst)
               -- inst.AnimState:PlayAnimation("gift_open_pre")
                --inst.AnimState:PushAnimation("taunt", true)
            end),
        },

        events =
        {
            EventHandler("firedamage", function(inst)
                --inst.AnimState:PlayAnimation("taunt")
                inst.sg:GoToState("idle", true)
                if inst.components.talker ~= nil then
                    inst.components.talker:Say(GetString(inst, "ANNOUNCE_NODANGERGIFT"))
                end
            end),
            EventHandler("ms_doneopengift", function(inst, data)
                inst.sg:GoToState("idle", true)
            end),
        },

        onexit = function(inst)
            if inst.sg.statemem.isdanger then
                return
            elseif not inst.sg.statemem.isopeningwardrobe then
                if inst.components.playercontroller ~= nil then
                    inst.components.playercontroller:EnableMapControls(true)
                    inst.components.playercontroller:Enable(true)
                end
                inst.components.inventory:Show()
                inst:ShowActions(true)
            end
            inst:ShowGiftItemPopUp(false)
        end,
    },
	
	State{
        name = "home",
        tags = {"busy", "silentmorph", "invisible" },

        onenter = function(inst)
            inst.components.locomotor:Stop()

            local target = inst:GetBufferedAction().target
            local failreason =
			   (target ~= nil and target.components.burnable ~= nil and
                    target.components.burnable:IsBurning() and
                    "ANNOUNCE_NOSLEEPONFIRE") 
                or (inst.components.hunger.current < TUNING.CALORIES_MED and "ANNOUNCE_NOHUNGERSLEEP")
                or (inst.components.beaverness ~= nil and inst.components.beaverness:IsStarving() and "ANNOUNCE_NOHUNGERSLEEP")
                or nil

            if failreason ~= nil then
                inst:PushEvent("performaction", { action = inst.bufferedaction })
                inst:ClearBufferedAction()
                inst.sg:GoToState("idle")
                if inst.components.talker ~= nil then
                    inst.components.talker:Say(GetString(inst, failreason))
                end
                return
            end

            inst.AnimState:PlayAnimation("eat")
            inst.sg:SetTimeout(11 * FRAMES)

            SetSleeperSleepState(inst)
        end,

        ontimeout = function(inst)
            local bufferedaction = inst:GetBufferedAction()
            if bufferedaction == nil then
                inst.sg:GoToState("idle", true)
                return
            end
            local home = bufferedaction.target
            if home == nil or
                not home:HasTag("maggothouse") or
                (home.components.burnable ~= nil and home.components.burnable:IsBurning()) then
                inst:PushEvent("performaction", { action = inst.bufferedaction })
                inst:ClearBufferedAction()
                inst.sg:GoToState("idle", true)
            else
                inst:PerformBufferedAction()
                inst.components.health:SetInvincible(true)
                inst:Hide()
                if inst.Physics ~= nil then
                    inst.Physics:Teleport(inst.Transform:GetWorldPosition())
                end
                if inst.DynamicShadow ~= nil then
                    inst.DynamicShadow:Enable(false)
                end
                inst.sg:AddStateTag("sleeping")
				inst.sg:AddStateTag("home")
                inst.sg:RemoveStateTag("busy")
                if inst.components.playercontroller ~= nil then
                    inst.components.playercontroller:Enable(true)
                end
            end
        end,

        onexit = function(inst)
            inst.components.health:SetInvincible(false)
            inst:Show()
            if inst.DynamicShadow ~= nil then
                inst.DynamicShadow:Enable(true)
            end
            if inst.sleepingbag ~= nil then
                --Interrupted while we are "sleeping"
                inst.sleepingbag.components.sleepingbag:DoWakeUp(true)
                inst.sleepingbag = nil
                SetSleeperAwakeState(inst)
            elseif not inst.sg.statemem.iswaking then
                --Interrupted before we are "sleeping"
                SetSleeperAwakeState(inst)
            end
        end,
    },
	
	State{
		name = "taunt",
		tags = {"busy"},

		onenter = function(inst)
			inst.components.locomotor:StopMoving()
			inst.Physics:Stop()
			inst.AnimState:PlayAnimation("taunt")
		end,

		timeline =
		{
			TimeEvent(6*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump")
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/taunt")
			end),
			TimeEvent(17*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
			end),
		},


		events = 
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
		},
	},
	
	State{
		name = "special_atk1",
		tags = {"busy"},

		onenter = function(inst)
			inst.components.locomotor:StopMoving()
			inst.Physics:Stop()
			inst.AnimState:PlayAnimation("taunt")
		end,

		timeline =
		{
			TimeEvent(6*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump")
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/taunt")
			end),
			TimeEvent(17*FRAMES, function(inst) 
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
			end),
		},


		events = 
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
		},
	},

	State{
		name = "hit",

		onenter = function(inst)
			inst.AnimState:PlayAnimation("hit")
			inst.Physics:Stop()
			inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
		end,

		events = 
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
		}
	},

	State{
		name = "walk_start",
		tags = {"moving", "canrotate"},

		onenter = function(inst)
			inst.AnimState:PlayAnimation("walk_pre")
			inst.components.locomotor:WalkForward()
		end,

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("walk") end),
		},		
	},

	State{
		name = "walk",
		tags = {"moving", "canrotate"},

		onenter = function(inst)
			inst.components.locomotor:WalkForward()
			inst.AnimState:PlayAnimation("walk_loop")

			local movesound = inst:HasTag("smallcreature") and "move_small" or "move"
			inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/"..movesound)
			if TheWorld.state.snowlevel > 0.15 or TheWorld.state.wetness > 15 then
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/sizzle_snow")
			end

            local elapsed = GetTime() - (inst.sg.mem.lastspawnmovefx or 0)
            inst.sg.statemem.task = inst:DoPeriodicTask(MOVE_FX_INTERVAL, SpawnMoveFx, math.max(0, MOVE_FX_INTERVAL - elapsed))
		end,

        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("walk") end),
        },

        onexit = function(inst)
            inst.sg.statemem.task:Cancel()
        end,
    },

	State{
		name = "walk_stop",
		tags = {"canrotate"},

		onenter = function(inst)
			if inst.components.locomotor then
				inst.components.locomotor:StopMoving()
			end
			inst.AnimState:PlayAnimation("walk_pst")
		end,

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
		},
	},

	State{
		name = "death",
		tags = {"busy"},

		onenter = function(inst)
			inst.Physics:Stop()
			inst.AnimState:PlayAnimation("death")
			inst.components.lootdropper:DropLoot(Vector3(inst.Transform:GetWorldPosition()))  
			inst.components.inventory:DropEverything(true)
        	inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/death")
			end,
		
		events =
			{
				EventHandler("animover", function(inst)
					if inst.AnimState:AnimDone() then
						if MOBGHOST == "Enable" then
							inst:PushEvent(inst.ghostenabled and "makeplayerghost" or "playerdied", { skeleton = false })
						else
							TheWorld:PushEvent("ms_playerdespawnanddelete", inst)
						end
					end
				end),
			},
			
	},

    State{
        name = "frozen",
        tags = {"busy", "frozen"},
        
        onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("frozen")
            inst.SoundEmitter:PlaySound("dontstarve/common/freezecreature")
        	inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/frozen")
        	inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/sizzle_snow")
        end,
        
        events =
        {   
            EventHandler("unfreeze", function(inst)	inst.components.health:Kill() end ),
            EventHandler("onthaw", function(inst) inst.sg:GoToState("thaw") end ),        
        },
    },

    State{
        name = "thaw",
        tags = {"busy", "thawing"},
        
        onenter = function(inst) 
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("frozen_loop_pst", true)
            inst.SoundEmitter:PlaySound("dontstarve/common/freezethaw", "thawing")
        end,
        
        onexit = function(inst)
            inst.SoundEmitter:KillSound("thawing")
        end,

        events =
        {   
            EventHandler("unfreeze", function(inst) inst.components.health:Kill() end),
        },
    },

    State{
        name = "thaw_break",
        tags = {"busy"},
        
        onenter = function(inst) 
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("shatter")
            
        end,
		
		events =
			{
				EventHandler("animover", function(inst)
					if inst.AnimState:AnimDone() then
						if MOBGHOST == "Enable" then
							inst:PushEvent(inst.ghostenabled and "makeplayerghost" or "playerdied", { skeleton = false })
						else
							TheWorld:PushEvent("ms_playerdespawnanddelete", inst)
						end
					end
				end),
			},
    },

	State{
		name = "nuzzle",
		tags = {"busy"},

		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("nuzzle")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/nuzzle")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/sizzle")
            
		end,

		events =
		{
			EventHandler("animover", function(inst) 
				inst:PerformBufferedAction()
				inst.sg:GoToState("idle") 
			end)
		},
	},

	State{
		name = "hungry",
		tags = {"busy"},

		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("hungry")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/beg")

		end,

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end)
		},
	},

	State{
		name = "peckish",
		tags = {"busy"},
		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("idle4")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/beg")

		end,

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end)
		},
	},

	State{
		name = "idle_hop",
		tags = {"busy"},

		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("idle3")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/happy_voice")
		end,

		timeline =
		{
			TimeEvent(6*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump") end),
			TimeEvent(14*FRAMES, function(inst)
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
				PlayFootstep(inst)
			end),
			TimeEvent(19*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump") end),
			TimeEvent(29*FRAMES, function(inst)
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
				PlayFootstep(inst)
			end),
			TimeEvent(34*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/jump") end),
			TimeEvent(45*FRAMES, function(inst)
				inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/land")
				PlayFootstep(inst)
			end),
		},

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end)
		},
	},

	State{
		name = "idle_spin",
		tags = {"busy"},
		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("idle2")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/twirl")
		end,

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end)
		},
	},

	State{
		name = "eat",
		tags = {"busy", "canrotate"},

		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("eat_pre")
            inst.AnimState:PushAnimation("eat_loop")
            inst.AnimState:PushAnimation("eat_pst", false)
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/happy_voice")
		end,
		
		timeline =
		{
			TimeEvent(20*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/eat") end),
			TimeEvent(35*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/happy_voice") end),
			TimeEvent(40*FRAMES, function(inst) inst:PerformBufferedAction() end)
		},

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

	State{
		name = "pickup",
		tags = {"busy"},
		onenter = function(inst)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("idle2")
            inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/twirl")
		end,

		timeline =
		{
			TimeEvent(20*FRAMES, function(inst) inst:PerformBufferedAction() end),
		},

		events =
		{
			EventHandler("animover", function(inst) inst.sg:GoToState("idle") end)
		},
	},

	State 
	{
        name = "sleep",
        tags = { "sleeping" }, --add tag "busy" if you hate sliding

        onenter = function(inst)
            if inst.components.locomotor ~= nil then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("sleep_pre")
			--inst.SoundEmitter:PlaySound("dontstarve/creatures/spiderqueen/fallasleep")
            --if fns ~= nil and fns.onsleep ~= nil then
                --fns.onsleep(inst)
            --end
        end,

        --timeline = timelines ~= nil and timelines.starttimeline or nil,
				
        events =
        {
            EventHandler("animqueueover", function(inst) inst.sg:GoToState("sleeping") end ),
            EventHandler("onwakeup", function(inst) inst.sg:GoToState("wake") end),
        },
    },

    State
    {
        name = "sleeping",
        tags = { "sleeping" },

        --onenter = onentersleeping,
		
		onenter = function(inst)
				inst.components.locomotor:StopMoving()
				local hungerpercent = inst.components.hunger:GetPercent()
				if hungerpercent ~= nil and hungerpercent ~= 0 then -- We don't want players to heal out starvation.
				inst.components.health:DoDelta(3, false)
				end
				--inst.SoundEmitter:PlaySound("dontstarve_DLC001/creatures/bearger/sleep")
				inst.AnimState:PlayAnimation("sleep_loop")
			end,

        --timeline = timelines ~= nil and timelines.sleeptimeline or nil,
		timeline =
		{
			TimeEvent(13*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/together/lavae/sleep") end),
		},

        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("sleeping") end ),
			EventHandler("onwakeup", function(inst) inst.sg:GoToState("wake") end),
        },
    },

    State
    {
        name = "wake",
        tags = { "busy", "waking" },

        onenter = function(inst)
            if inst.components.locomotor ~= nil then
                inst.components.locomotor:StopMoving()
            end
			--inst.SoundEmitter:PlaySound("dontstarve/creatures/spiderqueen/wakeup")
            inst.AnimState:PlayAnimation("sleep_pst")
            if inst.components.sleeper ~= nil and inst.components.sleeper:IsAsleep() then
                inst.components.sleeper:WakeUp()
            end
            --if fns ~= nil and fns.onwake ~= nil then
                --fns.onwake(inst)
            --end
        end,

        --timeline = timelines ~= nil and timelines.waketimeline or nil,
		
		events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
        },
    },
}





    
return StateGraph("lavae", states, events, "idle", actionhandlers)

