local TheNet = GLOBAL.TheNet
local require = GLOBAL.require
local TUNING = GLOBAL.TUNING
------------------------------------项圈 && HUD------------------------
local UpvalueHacker = require("tools/upvaluehacker3")
local writeables = require("writeables")
local kinds = UpvalueHacker.GetUpvalue(writeables.makescreen, "kinds")
local mylanguage = GetModConfigData("language")
local beefalo_names = {
	"Random",
}
local myprompt = "What do you want to call your koalefant?"
local mycancel = "Cancel"
local mymiddle = "Random"
local myaccept = "Name it!"
if mylanguage == 2 then
	beefalo_names = {
	"滑稽",
	"喜大普奔",
	"天涯",
	"海角",
	"编名字好累",
	"牛排",
	"肉块",
	"凑数的",
	"胖球",
	"看飞碟",
	"德玛西亚",
	"血蹄",
	"刚角",
	"里脊肉",
	"椒盐烤肉",
	"酒香坛肉",
	"宫保鸡丁",
	"宝马",
	"鱼香肉丝",
	}
	myprompt = "想给你的牛起个什么名?"
	mycancel = "取消"
	mymiddle = "随机"
	myaccept = "命名"
end
kinds.koalebeef_summer = {
    prompt = myprompt,
    animbank = "ui_board_5x3",
    animbuild = "ui_board_5x3",
    menuoffset = GLOBAL.Vector3(6, -70, 0),

    cancelbtn = { text = mycancel, cb = nil, control = GLOBAL.CONTROL_CANCEL },
    middlebtn = { text = mymiddle, cb = function(inst, doer, widget)
            widget:OverrideText( beefalo_names[math.random(#beefalo_names)] )
        end, control = GLOBAL.CONTROL_MENU_MISC_2 },
    acceptbtn = { text = myaccept, cb = nil, control = GLOBAL.CONTROL_ACCEPT },
}
kinds.koalebeef_winter = {
    prompt = myprompt,
    animbank = "ui_board_5x3",
    animbuild = "ui_board_5x3",
    menuoffset = GLOBAL.Vector3(6, -70, 0),

    cancelbtn = { text = mycancel, cb = nil, control = GLOBAL.CONTROL_CANCEL },
    middlebtn = { text = mymiddle, cb = function(inst, doer, widget)
            widget:OverrideText( beefalo_names[math.random(#beefalo_names)] )
        end, control = GLOBAL.CONTROL_MENU_MISC_2 },
    acceptbtn = { text = myaccept, cb = nil, control = GLOBAL.CONTROL_ACCEPT },
}

local ELEMENTBEEFALO = false
if ELEMENTBEEFALO then
	kinds.firebeefalo = {
	    prompt = myprompt,
	    animbank = "ui_board_5x3",
	    animbuild = "ui_board_5x3",
	    menuoffset = GLOBAL.Vector3(6, -70, 0),

	    cancelbtn = { text = mycancel, cb = nil, control = GLOBAL.CONTROL_CANCEL },
	    middlebtn = { text = mymiddle, cb = function(inst, doer, widget)
	            widget:OverrideText( beefalo_names[math.random(#beefalo_names)] )
	        end, control = GLOBAL.CONTROL_MENU_MISC_2 },
	    acceptbtn = { text = myaccept, cb = nil, control = GLOBAL.CONTROL_ACCEPT },
	}
	kinds.icebeefalo = {
	    prompt = myprompt,
	    animbank = "ui_board_5x3",
	    animbuild = "ui_board_5x3",
	    menuoffset = GLOBAL.Vector3(6, -70, 0),

	    cancelbtn = { text = mycancel, cb = nil, control = GLOBAL.CONTROL_CANCEL },
	    middlebtn = { text = mymiddle, cb = function(inst, doer, widget)
	            widget:OverrideText( beefalo_names[math.random(#beefalo_names)] )
	        end, control = GLOBAL.CONTROL_MENU_MISC_2 },
	    acceptbtn = { text = myaccept, cb = nil, control = GLOBAL.CONTROL_ACCEPT },
	}
	kinds.lightningbeefalo = {
	    prompt = myprompt,
	    animbank = "ui_board_5x3",
	    animbuild = "ui_board_5x3",
	    menuoffset = GLOBAL.Vector3(6, -70, 0),

	    cancelbtn = { text = mycancel, cb = nil, control = GLOBAL.CONTROL_CANCEL },
	    middlebtn = { text = mymiddle, cb = function(inst, doer, widget)
	            widget:OverrideText( beefalo_names[math.random(#beefalo_names)] )
	        end, control = GLOBAL.CONTROL_MENU_MISC_2 },
	    acceptbtn = { text = myaccept, cb = nil, control = GLOBAL.CONTROL_ACCEPT },
	}
	kinds.beefaloking = {
	    prompt = myprompt,
	    animbank = "ui_board_5x3",
	    animbuild = "ui_board_5x3",
	    menuoffset = GLOBAL.Vector3(6, -70, 0),

	    cancelbtn = { text = mycancel, cb = nil, control = GLOBAL.CONTROL_CANCEL },
	    middlebtn = { text = mymiddle, cb = function(inst, doer, widget)
	            widget:OverrideText( beefalo_names[math.random(#beefalo_names)] )
	        end, control = GLOBAL.CONTROL_MENU_MISC_2 },
	    acceptbtn = { text = myaccept, cb = nil, control = GLOBAL.CONTROL_ACCEPT },
	}
end
		
local ismastersim = TheNet:GetIsServer()

GLOBAL.ACTIONS.MIGRATE.mount_valid = true

if not ismastersim then return end

local Writeable = require("components/writeable")
local Freezable = require("components/freezable")
local shatterfx =
{
    character = "shatter",
}

local function MakeSmallFreezableCharacter(inst, sym, offset)
    inst:AddComponent("freezable")
    inst.components.freezable:SetShatterFXLevel(2)
    inst.components.freezable:AddShatterFX(shatterfx.character, offset or GLOBAL.Vector3(0, 0, 0), sym)
end

local function MakeLargeFreezableCharacter(inst, sym, offset)
    inst:AddComponent("freezable")
    inst.components.freezable:SetShatterFXLevel(4)
    inst.components.freezable:SetResistance(3)
    inst.components.freezable:AddShatterFX(shatterfx.character, offset or GLOBAL.Vector3(0, 0, 0), sym)
end

Writeable.near_dist = 3
local _SetText = Writeable.SetText

local function NearDeathDismount(oldrider)
	oldrider:RemoveEventCallback("dismounted", oldrider.oldmount.NearDeathDismount)
	GLOBAL.BrainManager:Hibernate(oldrider.oldmount)
	oldrider.oldmount.sg:GoToState("near_death_pre")
	oldrider.oldmount.NearDeathDismount = nil
	oldrider.oldmount.olderider = nil
	oldrider.oldmount = nil
end

local function HealthRedirect(inst, amount, overtime, cause, ignore_invincible, afflicter, ignore_absorb)
	if ignore_absorb then return false end --allow Kill to still work
	if afflicter and afflicter:HasTag("player") and inst.sg.state=="near_death" then
	inst._neardeathtask = inst:DoTaskInTime(1, function() inst.components.health:SetPercent(0) end)
	end
	if inst.near_death then return true end
	if inst.components.health.currenthealth + amount <= 0 then
	if inst.components.domesticatable and inst.components.domesticatable:IsDomesticated() and not (afflicter and afflicter.prefab and afflicter.prefab=="eyeplant") then
		inst.near_death = GLOBAL.GetTime() + 2000*TUNING.TOTAL_DAY_TIME
		inst._neardeathtask = inst:DoTaskInTime(2000*TUNING.TOTAL_DAY_TIME, function() inst.components.health:SetPercent(0) end)
		else
		inst.near_death = GLOBAL.GetTime() + 2*TUNING.TOTAL_DAY_TIME
		inst._neardeathtask = inst:DoTaskInTime(2*TUNING.TOTAL_DAY_TIME, function() inst.components.health:SetPercent(0) end)
		end
		inst.NearDeathDismount = NearDeathDismount
		if inst.components.rideable and inst.components.rideable.rider then
			inst.oldrider = inst.components.rideable.rider
			inst.oldrider.oldmount = inst
			inst.oldrider:ListenForEvent("dismounted", NearDeathDismount)
			inst.components.rideable:Buck(true)
		else
			GLOBAL.BrainManager:Hibernate(inst)
			if inst.components.sleeper then
            inst:RemoveComponent("sleeper")
			end
			if inst.components.freezable then
			inst:RemoveComponent("freezable")
			end
			inst:DoTaskInTime(GLOBAL.FRAMES*5, function() inst.sg:GoToState("near_death_pre") end)
		end
		return true
	end
end

local _Write = Writeable.Write
local CanEntitySeeTarget = GLOBAL.CanEntitySeeTarget

local MaxHealer = require("components/maxhealer")
local _Heal = MaxHealer.Heal
function MaxHealer:Heal(target, ...)
	local ret = _Heal(self, target, ...)
	if target and target.sg and ((target.prefab == "beefalo" and target.components.domesticatable) or  target.prefab == "babybeefalo" or  target.prefab == "koalebeef_summer" or  target.prefab == "koalebeef_winter") and target.near_death then
		if target.prefab == "babybeefalo" then
		target.components.health:SetPercent(0.15)
			if not target.components.sleeper then
            target:AddComponent("sleeper")
            target.components.sleeper:SetResistance(2)
			end
			if not target.components.freezable then
			MakeSmallFreezableCharacter(target, "beefalo_body")
			end
			else
			target.components.health:SetPercent(.05)
			if not target.components.sleeper then
            target:AddComponent("sleeper")
            target.components.sleeper:SetResistance(3)
			end
			if not target.components.freezable then
			MakeLargeFreezableCharacter(target, "beefalo_body")
			end
		end
		target._neardeathtask:Cancel()
		target.near_death = false
		target.sg:GoToState("wake")
		if target.prefab == "babybeefalo" then
		target:DoTaskInTime(1, FollowGrownBeefalo)
		end
		return true
	end
	return ret
end
local function UpdateName(inst)
	local name = inst.components.writeable:GetText()
	name = name and name or inst.owner_name .. GLOBAL.STRINGS.NAMES.BEEFALO
	inst.components.named:SetName(name)
end

local function OnSave(inst, data)
    data.tendency = inst.tendency
    data.owner_name = inst.owner_name
    data.collar_owner = inst.collar_owner
	data.near_death = inst.near_death and inst.near_death - GLOBAL.GetTime()
end

local function OnLoad(inst, data)
    if data then
    	if data.tendency then
        	inst.tendency = data.tendency
        end
        if data.owner_name then
        	inst.owner_name = data.owner_name
        end
        if data.collar_owner then
	        inst.collar_owner = data.collar_owner
	        inst.components.health.redirect = HealthRedirect
	    end
		inst.collar_owner = data.collar_owner
		if data.near_death then	
			inst._neardeathtask = inst:DoTaskInTime(data.near_death, function(inst) inst.components.health:SetPercent(0) end)
			inst.near_death = data.near_death + GLOBAL.GetTime()
			GLOBAL.BrainManager:Hibernate(inst)
			if inst.components.sleeper then
            inst:RemoveComponent("sleeper")
			end
			if inst.components.freezable then
			inst:RemoveComponent("freezable")
			end
			inst.sg:GoToState("near_death")
		end
    end
end

local REZCOMPATIBLITY = GLOBAL.KnownModIndex:IsModEnabled("workshop-741879530")
for _, moddir in ipairs(GLOBAL.KnownModIndex:GetModsToLoad()) do
	if moddir == "workshop-741879530" then
		REZCOMPATIBLITY = true
	end
end

local REZCOMPATIBLITY2 = GLOBAL.KnownModIndex:IsModEnabled("workshop-722788575")
for _, moddir in ipairs(GLOBAL.KnownModIndex:GetModsToLoad()) do
	if moddir == "workshop-722788575" then
		REZCOMPATIBLITY = true
	end
end

local REZCOMPATIBLITY3 = GLOBAL.KnownModIndex:IsModEnabled("workshop-722788575")
for _, moddir in ipairs(GLOBAL.KnownModIndex:GetModsToLoad()) do
	if moddir == "workshop-798768328" then
		REZCOMPATIBLITY = true
	end
end

if REZCOMPATIBLITY or REZCOMPATIBLITY2 or REZCOMPATIBLITY3 then
local function DomesticationTriggerFn(self, inst)
	local players = {}
	local had_gain = false
	--increase for players that have fed it recently
	if inst.components.hunger:GetPercent() > 0 then
		for k,v in pairs(self.recent_feeders) do
			players[k] = true
			had_gain = true
		end
	end
	--increase for the player riding it
	if inst.components.rideable:IsBeingRidden() then
		players[inst.components.rideable:GetRider().userid] = true
		had_gain = true
	end
	--increase for players nearby while sleeping
	if inst.components.sleeper:IsAsleep() then
		local x,y,z = inst:GetPosition():Get()
		for _,v in pairs(GLOBAL.AllPlayers) do
			if v:GetDistanceSqToPoint(x,y,z) < TUNING.BEEFALO_DOMESTICATION_SLEEP_DIST_SQ then
				players[v.userid] = true
				had_gain = true
			end
		end
	end
	return players, had_gain
end
local function OnBrushed(inst, doer, numprizes)
    if numprizes > 0 and inst.components.domesticatable ~= nil then
        inst.components.domesticatable:DeltaDomestication(TUNING.BEEFALO_DOMESTICATION_BRUSHED_DOMESTICATION, doer.userid)
        inst.components.domesticatable:DeltaObedience(TUNING.BEEFALO_DOMESTICATION_BRUSHED_OBEDIENCE)
    end
end
local TENDENCY = GLOBAL.TENDENCY
local function OnAttacked(inst, data)
    if inst.components.rideable:IsBeingRidden() then
        if not inst.components.domesticatable:IsDomesticated() or not inst.tendency == TENDENCY.ORNERY then
            inst.components.domesticatable:DeltaDomestication(TUNING.BEEFALO_DOMESTICATION_ATTACKED_DOMESTICATION, inst.components.rideable.rider.userid)
            -- inst.components.domesticatable:DeltaObedience(TUNING.BEEFALO_DOMESTICATION_ATTACKED_OBEDIENCE)
        end
        -- inst.components.domesticatable:DeltaTendency(TENDENCY.ORNERY, TUNING.BEEFALO_ORNERY_ATTACKED)
    else
        if data.attacker ~= nil and data.attacker:HasTag("player") then
            inst.components.domesticatable:DeltaDomestication(TUNING.BEEFALO_DOMESTICATION_ATTACKED_BY_PLAYER_DOMESTICATION, data.attacker.userid)
            -- inst.components.domesticatable:DeltaObedience(TUNING.BEEFALO_DOMESTICATION_ATTACKED_BY_PLAYER_OBEDIENCE)
        end
        -- inst.components.combat:SetTarget(data.attacker)
        -- inst.components.combat:ShareTarget(data.attacker, 30, CanShareTarget, 5)
    end
end
local function OnEat(inst, data)
    local full = inst.components.hunger:GetPercent() >= 1
    if not full then
        inst.components.domesticatable:DeltaObedience(TUNING.BEEFALO_DOMESTICATION_FEED_OBEDIENCE)

        inst.components.domesticatable:TryBecomeDomesticated()
    else
        inst.components.domesticatable:DeltaObedience(TUNING.BEEFALO_DOMESTICATION_OVERFEED_OBEDIENCE)
		if data.feeder then --just in case. if the feeder has no userid, then this will be ignored anyway
			inst.components.domesticatable:DeltaDomestication(TUNING.BEEFALO_DOMESTICATION_OVERFEED_DOMESTICATION, data.feeder.userid)
		end
        inst.components.domesticatable:DeltaTendency(TENDENCY.PUDGY, TUNING.BEEFALO_PUDGY_OVERFEED)
    end
    inst:PushEvent("eat", { full = full, food = data.food })
    inst.components.knownlocations:RememberLocation("loiteranchor", inst:GetPosition())
end
local TENDENCY_NAMES = {
	[GLOBAL.TENDENCY.DEFAULT] = "Ordinary ",
	[GLOBAL.TENDENCY.ORNERY] = "Ornery ",
	[GLOBAL.TENDENCY.RIDER] = "Speedy ",
	[GLOBAL.TENDENCY.PUDGY] = "Pudgy ",
}
local function UpdateName(inst)
	local name = inst.components.writeable:GetText()
	name = name and inst.owner_name .. name or inst.owner_name .. inst.tendency_name .. GLOBAL.STRINGS.NAMES.BEEFALO
	inst.components.named:SetName(name)
end
AddPrefabPostInit("koalebeef_summer", function(inst)
	inst:AddComponent("named")
	inst.UpdateName = UpdateName
	inst:DoTaskInTime(0, inst.UpdateName)
	inst.owner_name = ""
	inst.tendency_name = ""
	local _SetTendency = inst.SetTendency
	function inst.SetTendency(inst, changedomestication, ...)
		_SetTendency(inst, changedomestication, ...)
		if changedomestication == "domestication" then
			inst.tendency_name = TENDENCY_NAMES[inst.tendency]
			inst:UpdateName()
		elseif changedomestication == "feral" then
			inst.tendency_name = ""
			inst:UpdateName()
		end
	end
    inst.components.domesticatable:SetDomesticationTrigger(DomesticationTriggerFn)
    inst.components.brushable:SetOnBrushed(OnBrushed)
	inst:AddComponent("colourtweener") --for the beefalo exit/leave with player animation
	inst.components.locomotor.fasteronroad = true
    inst:ListenForEvent("attacked", OnAttacked)
	inst.components.eater:SetOnEatFn() --clear the normal one, replace with our OnEat
    inst:ListenForEvent("oneat", OnEat)
	local _test = inst.components.trader.test
	inst.components.trader:SetAcceptTest(function(inst, item, giver, ...)
		local _, max_domesticator = inst.components.domesticatable:GetMaxDomestication()
		return _test(inst, item, giver, ...) or (item.prefab == "beefalocollar"
			and inst.components.domesticatable.domesticated and not inst.components.combat:HasTarget()
			and max_domesticator == giver.userid)
	end)
	local _onaccept = inst.components.trader.onaccept
	inst.components.trader.onaccept = function(inst, giver, item, ...)
		inst._pre_eat_hunger = inst.components.hunger.current --need to know the actual delta hunger from eating
		_onaccept(inst, giver, item, ...)
		if item.prefab == "beefalocollar" then
			item:DoTaskInTime(0, item.Remove)
			inst.components.domesticatable:OnCollared(giver)
		end
	end
	inst:AddComponent("writeable")
	inst.components.writeable.near_dist = 10
	inst:RemoveTag("writeable")
	inst.components.writeable.onsettext = function() inst:UpdateName() end
	inst.components.inspectable.getspecialdescription = nil --we don't want the writer to store it here
	local _GetStatus = inst.components.inspectable.getstatus
	function inst.components.inspectable.getstatus(inst)
		if inst.components.domesticatable and inst.components.domesticatable.near_death then
			return "NEARDEATH"
		else
			return _GetStatus(inst)
		end
	end
	inst:ListenForEvent("saddlechanged", function(inst, data)
		if inst.components.domesticatable and inst.components.rideable
		and inst.components.domesticatable.near_death then
			-- Prevent adding the saddle from making it rideable if it's near death
			inst:DoTaskInTime(0, function() inst.components.rideable.canride = false end)
		end
	end)
end)


AddPrefabPostInit("koalebeef_winter", function(inst)
	inst:AddComponent("named")
	inst.UpdateName = UpdateName
	inst:DoTaskInTime(0, inst.UpdateName)
	inst.owner_name = ""
	inst.tendency_name = ""
	local _SetTendency = inst.SetTendency
	function inst.SetTendency(inst, changedomestication, ...)
		_SetTendency(inst, changedomestication, ...)
		if changedomestication == "domestication" then
			inst.tendency_name = TENDENCY_NAMES[inst.tendency]
			inst:UpdateName()
		elseif changedomestication == "feral" then
			inst.tendency_name = ""
			inst:UpdateName()
		end
	end
    inst.components.domesticatable:SetDomesticationTrigger(DomesticationTriggerFn)
    inst.components.brushable:SetOnBrushed(OnBrushed)
	inst:AddComponent("colourtweener") --for the beefalo exit/leave with player animation
	inst.components.locomotor.fasteronroad = true
    inst:ListenForEvent("attacked", OnAttacked)
	inst.components.eater:SetOnEatFn() --clear the normal one, replace with our OnEat
    inst:ListenForEvent("oneat", OnEat)
	local _test = inst.components.trader.test
	inst.components.trader:SetAcceptTest(function(inst, item, giver, ...)
		local _, max_domesticator = inst.components.domesticatable:GetMaxDomestication()
		return _test(inst, item, giver, ...) or (item.prefab == "beefalocollar"
			and inst.components.domesticatable.domesticated and not inst.components.combat:HasTarget()
			and max_domesticator == giver.userid)
	end)
	local _onaccept = inst.components.trader.onaccept
	inst.components.trader.onaccept = function(inst, giver, item, ...)
		inst._pre_eat_hunger = inst.components.hunger.current --need to know the actual delta hunger from eating
		_onaccept(inst, giver, item, ...)
		if item.prefab == "beefalocollar" then
			item:DoTaskInTime(0, item.Remove)
			inst.components.domesticatable:OnCollared(giver)
		end
	end
	inst:AddComponent("writeable")
	inst.components.writeable.near_dist = 10
	inst:RemoveTag("writeable")
	inst.components.writeable.onsettext = function() inst:UpdateName() end
	inst.components.inspectable.getspecialdescription = nil --we don't want the writer to store it here
	local _GetStatus = inst.components.inspectable.getstatus
	function inst.components.inspectable.getstatus(inst)
		if inst.components.domesticatable and inst.components.domesticatable.near_death then
			return "NEARDEATH"
		else
			return _GetStatus(inst)
		end
	end
	inst:ListenForEvent("saddlechanged", function(inst, data)
		if inst.components.domesticatable and inst.components.rideable
		and inst.components.domesticatable.near_death then
			-- Prevent adding the saddle from making it rideable if it's near death
			inst:DoTaskInTime(0, function() inst.components.rideable.canride = false end)
		end
	end)
end)


else
local function BeefaloInit(inst)
	inst:AddComponent("named")
	inst.UpdateName = UpdateName
	inst:DoTaskInTime(0, inst.UpdateName)
	inst.owner_name = ""
	inst.collar_owner = nil
	inst.near_death= false
    --inst.components.beard.prize = "beefalowool"
    --inst.components.brushable.prize = "poop"
	inst:AddComponent("colourtweener") --for the beefalo exit/leave with player animation
    
	local _test = inst.components.trader.test
	inst.components.trader:SetAcceptTest(function(inst, item, giver, ...)
		return _test(inst, item, giver, ...) or (item.prefab == "beefalocollar" and not inst.components.combat:HasTarget() and inst.collar_owner == nil) or (item.prefab == "featherpencil" and inst.collar_owner)
	end)
	
	local _onaccept = inst.components.trader.onaccept
	inst.components.trader.onaccept = function(inst, giver, item, ...)
		--inst._pre_eat_hunger = inst.components.hunger.current --need to know the actual delta hunger from eating
		_onaccept(inst, giver, item, ...)
		if item.prefab == "featherpencil" then
               item:DoTaskInTime(0, item.Remove)
               inst.components.writeable:BeginWriting(giver)
               end
		if item.prefab == "beefalocollar" then
			item:DoTaskInTime(0, item.Remove)
			inst.collar_owner = giver.userid
			inst:AddTag("notraptrigger")
			--print(tostring(giver.userid))
			local client = TheNet:GetClientTableForUser(giver.userid)
			inst.owner_name = client and client.name.."'s " or inst.owner_name
			inst.components.writeable:BeginWriting(giver)
			inst.components.health.redirect = HealthRedirect
		end
		if item.prefab == "dead_baby_beef_fresh" then
		   if inst.components.domesticatable ~= nil then
           inst.components.domesticatable:DeltaDomestication(TUNING.BEEFALO_DOMESTICATION_BRUSHED_DOMESTICATION*4)
           inst.components.domesticatable:DeltaObedience(TUNING.BEEFALO_DOMESTICATION_BRUSHED_OBEDIENCE*3)
           inst.components.domesticatable:DeltaTendency(GLOBAL.TENDENCY.PUDGY, -1)
           end
        inst:DoTaskInTime(3, function() inst.sg:GoToState("abused_positive") end)
		end
	end
	
	inst.OnSave = OnSave
    inst.OnLoad = OnLoad

	inst:AddComponent("writeable")
	inst.components.writeable.near_dist = 10
	inst:RemoveTag("writeable")
	inst.components.writeable.onsettext = function() inst:UpdateName() end
	inst.components.inspectable.getspecialdescription = nil --we don't want the writer to store it here
		local _GetStatus = inst.components.inspectable.getstatus
	function inst.components.inspectable.getstatus(inst)
		if inst.components.domesticatable and inst.near_death then
			return "NEARDEATH"
		else
			return _GetStatus(inst)
		end
	end
	inst:ListenForEvent("saddlechanged", function(inst, data)
		if inst.components.domesticatable and inst.components.rideable
		and inst.near_death then
			-- Prevent adding the saddle from making it rideable if it's near death
			inst:DoTaskInTime(0, function() inst.components.rideable.canride = false end)
		end
	end)
end

AddPrefabPostInit("koalebeef_summer",BeefaloInit)
AddPrefabPostInit("koalebeef_winter",BeefaloInit)
end
if ELEMENTBEEFALO then 
	AddPrefabPostInit("firebeefalo",BeefaloInit)
	AddPrefabPostInit("icebeefalo",BeefaloInit)
	AddPrefabPostInit("lightningbeefalo",BeefaloInit)
	AddPrefabPostInit("beefaloking",BeefaloInit)
end

local State = GLOBAL.State
local EventHandler = GLOBAL.EventHandler
AddStategraphState("koalebeef", State{
		name = "near_death_pre",
		tags = {"busy", "noattack"},

		onenter = function(inst)
			inst.components.health:SetInvincible(true)
			if inst.components.rideable then
			inst.components.rideable.canride = false
			end
			inst.SoundEmitter:PlaySound(inst.sounds.yell)
			inst.AnimState:PlayAnimation("death")
			inst.Physics:Stop()
		end,
		
        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("near_death") end),
        },
	})
	
AddStategraphState("koalebeef", State{
        name = "abused_positive",
        tags = {"canrotate"},

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("whipped_positive")
            if inst.prefab=="beefalo" then
            inst.SoundEmitter:PlaySound("babybeefalo/creature/adult_abused")
            else
            inst.SoundEmitter:PlaySound("babybeefalo/creature/baby_abused")
            end
        end,

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

		onenter = function(inst)
			inst.components.health:SetInvincible(true)
			if inst.components.rideable then
			inst.components.rideable.canride = false
			inst.components.rideable:Buck(true)
			end
			inst.AnimState:SetPercent("death", 1)
			inst.Physics:Stop()
		end,
		
		onexit = function(inst)
			inst.components.health:SetInvincible(false)
			if inst.components.rideable and inst.components.rideable.saddle ~= nil then
				inst.components.rideable.canride = true
			end
			GLOBAL.BrainManager:Wake(inst)
		end,
	})