Jump to content

How to get a creature to fall asleep?


Recommended Posts

So Tiny Box Tim's errors strike again! for the past 2 days I've been trying anything I can to get his brain to be smarter than ever!! I basically want it so that in the day time he'll wander in a distance close to his "eyebone" item and at dusk/in the caves/full moon I want him to follow and face Mark (I'll make changes between these 3 times later on in the future) yet during normal night time I want him to prioritize sleeping over anything else! but ofcorse wake up and face/follow if Mark walks too far away with the "eyebone" item or wakes Tim by opening him!

 

I've managed to get him to change whatever the heck he's doing during different time phases but he seems to not want to sleep at all ever no matter what I try o.o

it's like Mark keeps feeding him icecream behind my back!

and yes I've tried looking at how chester does it because that's EXACTLY what I want/need but let me put much emphasis on "no matter what I try" but he just keeps eating all that icecream when I'm not looking!

Thanks in advanced for any help I get :D

 

here's his brain

require "behaviours/follow"
require "behaviours/wander"
require "behaviours/faceentity"
require "behaviours/panic"
 
 
local MIN_FOLLOW_DIST = 0
local MAX_FOLLOW_DIST = 10
local TARGET_FOLLOW_DIST = 7
local MAX_WANDER_DIST = 5
 
 
local function GetFaceTargetFn(inst)
    return inst.components.follower.leader
end
 
local function KeepFaceTargetFn(inst, target)
    return inst.components.follower.leader == target
end
 
local function Sleep(inst)
return inst.components.sleeper:GoToSleep()
end
 
local tinyboxtimBrain = Class(Brain, function(self, inst)
    Brain._ctor(self, inst)
end)
 
 
function tinyboxtimBrain:OnStart()
    local clock = GetClock()
    
    local day = WhileNode( function() return clock and clock:IsDay() end, "IsDay",
    PriorityNode{
Wander(self.inst, function() return self.inst.components.knownlocations:GetLocation(TheSim:FindFirstEntityWithTag("tinytimdevice") or TheSim:FindFirstEntityWithTag("markiplier")) end, MAX_WANDER_DIST),
Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),
FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),
    }, .5)
 
local dusk = WhileNode( function() return clock and clock:IsDusk() end, "IsDusk",
    PriorityNode{
Wander(self.inst, function() return self.inst.components.knownlocations:GetLocation(TheSim:FindFirstEntityWithTag("tinytimdevice") or TheSim:FindFirstEntityWithTag("markiplier")) end, MAX_WANDER_DIST),
Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),
FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),
    }, .5)
 
local night = WhileNode( function() return clock and clock:IsNight() end, "IsNight",
PriorityNode{
Sleep(self.inst),
Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),
FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),
}, .5)
 
local fullmoon = WhileNode( function() return clock and not clock:IsNight() and clock:GetMoonPhase() == "full" end, "IsFullMoon",
PriorityNode{
Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),
FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),
}, .5)
 
local cave = WhileNode( function() return GetWorld():IsCave() end, "IsCave",
PriorityNode{
Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST),
FaceEntity(self.inst, GetFaceTargetFn, KeepFaceTargetFn),
}, .5)
 
local root = PriorityNode({cave, day, dusk, fullmoon, night}, .5)
    self.bt = BT(self.inst, root)
end
 
return tinyboxtimBrain

 

here's his stategraph

 
local actionhandlers = {}
 
local events = {
    EventHandler("locomote", function(inst) 
local is_moving = inst.sg:HasStateTag("moving")
local open = inst.sg:HasStateTag("open")
local sleeping = inst.sg:HasStateTag("sleeping")
        local should_move = inst.components.locomotor:WantsToMoveForward()
        if should_move and not is_moving and not open and not sleeping then
inst.sg:GoToState("bounce_pre")
        end
end),
EventHandler("gotosleep", function(inst)
if inst.sg:HasStateTag("sleeping") then
inst.sg:GoToState("sleeping")
else
inst.sg:GoToState("sleep")
end
end)
}
 
local states = {
    State{
        name = "idle",
        tags = {"idle", "canrotate"},
        
        onenter = function(inst, pushanim)
inst.AnimState:SetBank("tinyboxtim_idle")
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("idle")
end,
        
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("idle") end)}
    },
    
    State{
        name = "open",
        tags = {"busy", "open"},
        
        onenter = function(inst)
inst.AnimState:SetBank("tinyboxtim_openandclose")
            inst.Physics:Stop()
if inst.components.sleeper:IsAsleep() then inst.components.sleeper:WakeUp() end
            inst.AnimState:PlayAnimation("pre_base")
        end,
 
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("open_idle") end )}
    },
 
    State{
        name = "open_idle",
        tags = {"busy", "open"},
        
        onenter = function(inst)
inst.AnimState:SetBank("tinyboxtim_openandclose")
            inst.AnimState:PlayAnimation("loop_base")
        end,
 
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("open_idle") end )}
    },
 
    State{
        name = "close",
        tags = {""},
        
        onenter = function(inst)
inst.AnimState:SetBank("tinyboxtim_openandclose")
            inst.AnimState:PlayAnimation("pst_base")
        end,
 
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("idle") end )}    
    },
State{
        name = "sleep",
        tags = {"busy", "sleeping"},
        
        onenter = function(inst)
inst.components.locomotor:StopMoving()
inst.AnimState:SetBank("tinyboxtim_sleeping")
            inst.AnimState:PlayAnimation("pre_sleeping")
        end,
 
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("sleeping") end ), EventHandler("onwakeup", function(inst) inst.sg:GoToState("wakeup") end)}    
    },
State{
        name = "sleeping",
        tags = {"busy", "sleeping"},
        
        onenter = function(inst)
inst.AnimState:SetBank("tinyboxtim_sleeping")
            inst.AnimState:PlayAnimation("loop_sleeping")
        end,
 
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("sleeping") end ), EventHandler("onwakeup", function(inst) inst.sg:GoToState("wakeup") end)}    
    },
State{
        name = "wakeup",
        tags = {"busy", "waking"},
        
        onenter = function(inst)
inst.components.locomotor:StopMoving()
inst.AnimState:SetBank("tinyboxtim_sleeping")
            inst.AnimState:PlayAnimation("pst_sleeping")
if inst.components.sleeper and inst.components.sleeper:IsAsleep() then
inst.components.sleeper:WakeUp()
end
        end,
 
        events = {EventHandler("animover", function(inst) inst.sg:GoToState("idle") end )}    
    },
State{
name = "bounce_pre",
tags = {"moving", "canrotate"},
 
onenter = function(inst) 
inst.AnimState:SetBank("tinyboxtim_bouncing")
inst.AnimState:PlayAnimation("pre_bouncing")
end,
 
events = {EventHandler("animover", function(inst) inst.sg:GoToState("bounce_mid") end )}
},
State{
name = "bounce_mid",
tags = {"moving"},
 
onenter = function(inst)
inst.AnimState:SetBank("tinyboxtim_bouncing")
inst.components.locomotor:WalkForward()
inst.AnimState:PlayAnimation("loop_bouncing")
end,
 
events = {EventHandler("animover", function(inst) inst.sg:GoToState("bounce_pst") end )}
},
State{
name = "bounce_pst",
tags = {"canrotate"},
 
onenter = function(inst)
inst.AnimState:SetBank("tinyboxtim_bouncing")
inst.components.locomotor:StopMoving()
inst.AnimState:PlayAnimation("pst_bouncing")
end,
 
events = { EventHandler("animover", function(inst) 
if inst.components.locomotor:WantsToMoveForward() then
inst.sg:GoToState("bounce_pre")
else
inst.sg:GoToState("idle")
end
end)}
}
}
 
return StateGraph("tinyboxtim", states, events, "idle", actionhandlers)

 

here's his prefab

require "prefabutil"
 
local WAKE_TO_FOLLOW_DISTANCE = 14
local SLEEP_NEAR_LEADER_DISTANCE = 7
 
local assets = {
Asset("ANIM", "anim/ui_cookpot_1x4.zip"),
    Asset("ANIM", "anim/tinyboxtim.zip"),
Asset("ANIM", "anim/tinywarfboxtim.zip"),
Asset("ANIM", "anim/euphoricboxtim.zip"),
Asset("ANIM", "anim/euphoricwarfboxtim.zip")
}
 
local prefabs = { "tinytimdevice" }
 
local function ShouldWakeUp(inst)
    return DefaultWakeTest(inst) or not inst.components.follower:IsNearLeader(WAKE_TO_FOLLOW_DISTANCE)
end
 
local function ShouldSleep(inst)
    return DefaultSleepTest(inst) and not inst.sg:HasStateTag("open") and inst.components.follower:IsNearLeader(SLEEP_NEAR_LEADER_DISTANCE) and not GetWorld().components.clock:GetMoonPhase() == "full"
end
 
local function OnOpen(inst)
    inst.sg:GoToState("open")
end 
 
local function OnClose(inst) 
    inst.sg:GoToState("close")
end 
 
local function itemtest(inst, item, slot)
if item.prefab == "chester_eyebone" or item.prefab == "tinytimdevice" or item.prefab == "lexitoy" then
return false
else
return true
end
end
 
local function OnStartFollowing(inst) 
    inst:AddTag("companion") 
end
 
local function getstatus(inst)
if inst.Warfified == true and inst.Euphoric == false then return "WARFBOX"
elseif inst.Euphoric == true and inst.Warfified == false then return "EUPHORIC"
elseif inst.Euphoric == true and inst.Warfified == true then return "WARPHORIC"
elseif inst.Warfified == false and inst.Euphoric == false then return "GENERIC"
end
end
 
local slotpos = {
Vector3(0,64+32+8+15,0), 
Vector3(0,32+18,0),
Vector3(0,-(15+4),0), 
Vector3(0,-(64+10+8+4),0),
Vector3(0,-(64+28+8+55),0)
}
 
local function create_tinyboxtim()
    local inst = CreateEntity()
    
    inst:AddTag("companion")
    inst:AddTag("character")
    inst:AddTag("tinyboxtim")
    inst:AddTag("notraptrigger")
 
    inst.entity:AddTransform()
 
    inst.entity:AddMiniMapEntity()
inst.MiniMapEntity:SetIcon("tinyboxtim.tex")
    inst.entity:AddAnimState()
    inst.AnimState:SetBank("tinyboxtim")
    inst.AnimState:SetBuild("tinyboxtim")
inst.AnimState:PlayAnimation("idle")
inst.Transform:SetScale(0.3,0.3,0.3)
 
    inst.entity:AddSoundEmitter()
 
    inst.entity:AddDynamicShadow()
    inst.DynamicShadow:SetSize( 1, 1 )
 
    MakeCharacterPhysics(inst, 75, .5)
    
    inst.Physics:SetCollisionGroup(COLLISION.CHARACTERS)
    inst.Physics:ClearCollisionMask()
    inst.Physics:CollidesWith(COLLISION.WORLD)
    inst.Physics:CollidesWith(COLLISION.OBSTACLES)
    inst.Physics:CollidesWith(COLLISION.CHARACTERS)
 
    inst.Transform:SetFourFaced()
 
    inst:AddTag("noauradamage")
 
    inst:AddComponent("locomotor")
    inst.components.locomotor.walkspeed = 30
    inst.components.locomotor.runspeed = 30
inst.components.locomotor.fasteronroad = true
 
    inst:AddComponent("follower")
 
    inst:AddComponent("knownlocations")
    MakeSmallBurnableCharacter(inst, "chester_body")
 
    inst:AddComponent("container")
    inst.components.container:SetNumSlots(5)
 
    inst.components.container.onopenfn = OnOpen
    inst.components.container.onclosefn = OnClose
inst.components.container.itemtestfn = itemtest
 
inst:AddComponent("characterspecific")
    inst.components.characterspecific:SetOwner("markiplier")
    
    inst.components.container.widgetslotpos = slotpos
    inst.components.container.widgetanimbank = "ui_cookpot_1x4"
    inst.components.container.widgetanimbuild = "ui_cookpot_1x4"
    inst.components.container.widgetpos = Vector3(0,200,0)
    inst.components.container.side_align_tip = 160
 
    inst:AddComponent("sleeper")
    inst.components.sleeper:SetResistance(3)
    inst.components.sleeper.testperiod = GetRandomWithVariance(6, 2)
    inst.components.sleeper:SetSleepTest(ShouldSleep)
    inst.components.sleeper:SetWakeTest(ShouldWakeUp)
 
    inst:SetStateGraph("SGtinyboxtim")
    inst.sg:GoToState("idle")
 
inst:DoTaskInTime(0.1, function(inst)
        if not TheSim:FindFirstEntityWithTag("tinytimdevice") then
            inst:Remove()
        end
    end)
 
inst:AddComponent("sanityaura")
    inst:AddComponent("inspectable")
inst.components.inspectable.getstatus = getstatus
inst:AddComponent("named")
inst.Warfified = false
inst.Euphoric = false
inst:DoPeriodicTask(0.1, function(inst)
if not inst.sg:HasStateTag("sleeping") then 
local WarfMe = false
local FancyMe = false
for k,v in pairs(inst.components.container.slots) do
if v then
if v.prefab == "warfmini" or v.prefab == "warfstache" or v.prefab == "warfstaff" or v.prefab == "warfbug" or v.prefab == "poofgun" or v.prefab == "warfbutter" then
WarfMe = true
end
if v.prefab == "fedora" then
FancyMe = true
end
end
end
local function ChangeTim(inst, name, stringname, sanity)
inst.AnimState:SetBank(name)
inst.AnimState:SetBuild(name)
inst.MiniMapEntity:SetIcon(name..".tex")
inst.components.named:SetName(stringname)
inst.components.sanityaura.aurafn = function() return TUNING.SANITYAURA_TINY * sanity end
if inst.sg:HasStateTag("open") then inst.sg:GoToState("open") else inst.sg:GoToState("idle") end
end
if WarfMe == true and FancyMe == false and (inst.Warfified == false or (inst.Warfified == true and inst.Euphoric == true)) then
if inst.Euphoric == true then inst.Euphoric = false end
inst.Warfified = true
ChangeTim(inst, "tinywarfboxtim", "Tiny WarfBox Tim", 2.5)
elseif FancyMe == true and WarfMe == false and (inst.Euphoric == false or (inst.Warfified == true and inst.Euphoric == true)) then
if inst.Warfified == true then inst.Warfified = false end
inst.Euphoric = true
ChangeTim(inst, "euphoricboxtim", "Euphoric Box Tim", 3)
elseif WarfMe == true and FancyMe == true and (inst.Warfified == false or inst.Euphoric == false) then
if inst.Warfified == false then inst.Warfified = true end
if inst.Euphoric == false then inst.Euphoric = true end
ChangeTim(inst, "euphoricwarfboxtim", "Euphoric WarfBox Tim", 5)
elseif WarfMe == false and FancyMe == false and (inst.Warfified == true or inst.Euphoric == true) then
if inst.Warfified == true then inst.Warfified = false end
if inst.Euphoric == true then inst.Euphoric = false end
ChangeTim(inst, "tinyboxtim", "Tiny Box Tim", 0.5)
end
end
end)
 
local brain = nil
if MarkMod.TimBrain == true then
brain = require "brains/tinyboxtimsmartbrain"
else
brain = require "brains/tinyboxtimdumbbrain"
end
    inst:SetBrain(brain)
 
    return inst
end
 
return Prefab( "common/tinyboxtim", create_tinyboxtim, assets, prefabs) 

Link to comment
Share on other sites

@Fidooop Hmm. Chester seems to be controlling sleep patterns through the sleeper component inside chester.lua (prefab). What happened when you tried it that way, if you did?

 

Also, in your brain code, are you sure this is how you want it?

local fullmoon = WhileNode( function() return clock and not clock:IsNight() and clock:GetMoonPhase() == "full" end,

Specifically, it's not night and the moon is full?

Link to comment
Share on other sites

Also, in your brain code, are you sure this is how you want it?

local fullmoon = WhileNode( function() return clock and not clock:IsNight() and clock:GetMoonPhase() == "full" end,

Specifically, it's not night and the moon is full?

I saw that.... and fixed it... thanks for pointing it out though! XD

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...