Sign in to follow this  
Naplez

My custom chester runs away from me when I restart the game...

Recommended Posts

Naplez    3

post-549594-0-91711200-1424675070.png

 

This is my custom-reskined Chester, Minimoose.

And right one is his DOOMSDAY device controller as chester_eyebone.

 

I put chester.lua and chester_eyebone.lua in my mod character's prefabs

and added this global string into modmain.lua:

 

GLOBAL.STRINGS.NAMES.CHESTER = "Minimoose"GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.CHESTER = "The Minimoose!"GLOBAL.STRINGS.NAMES.CHESTER_EYEBONE = "DOOMSDAY device controller"GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.CHESTER_EYEBONE = "The DOOM is coming!"

 

and I added my customed anims:

chester / chester_build / chester_shadow_build / chester_snow_build / 

chester_eyebone / chester_eyebone_build / chester_eyebone_shadow_build / chester_eyebone_snow_build.

 

also added images/inventoryimages/chester_eyebone.tex and xml.

 

and put chester_eyebone in my character's start item.

 

This progress reskined the Chester into the Minimoose. He looks good but have a problem.

 

 

When I started the game he's fine. He comes to me from somewhere. But when I exit the game and restart it he suddenly runs away from me. If chase him, he stops where the 'another' controller(eyebone) on the ground. 

 

I think the game doesn't recognize that my character already has a controller(eyebone) in his inventory so it makes new one when the world generates. 

 

I also thought maybe the way to solve the problem is make Minimoose into a new companion. Not just reskin the chester. Make game recognize Minimoose as a new companion. And maybe this way is better for multiplaying with my mod.

 

 

So I renamed chester.lua / chester_eyebone.lua as minimoose.lua / minimoose_ctrl.lua. And same as the /anim and /inventoryimages files. And added new map_icons/minimoose.tex and xml for his minimap icon.

 

And I didn't want shadow/snow morph function for him so decided to delete that part from lua.

 

These are the edited lua:

 

Part of modmain.lua

local require = GLOBAL.requirelocal STRINGS = GLOBAL.STRINGSlocal Ingredient = GLOBAL.Ingredientlocal RECIPETABS = GLOBAL.RECIPETABSlocal ACTIONS = GLOBAL.ACTIONSlocal Action = GLOBAL.ActionPrefabFiles = {"zim","minimoose"}GLOBAL.STRINGS.NAMES.MINIMOOSE = "Minimoose"GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.MINIMOOSE = "The Minimoose!"GLOBAL.STRINGS.NAMES.MINIMOOSE_CTRL = "DOOMSDAY device controller"GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.MINIMOOSE_CTRL = "The DOOM is coming!"Assets = {    Asset( "IMAGE", "images/saveslot_portraits/zim.tex" ),    Asset( "ATLAS", "images/saveslot_portraits/zim.xml" ),    Asset( "IMAGE", "images/selectscreen_portraits/zim.tex" ),    Asset( "ATLAS", "images/selectscreen_portraits/zim.xml" ),    Asset( "IMAGE", "images/selectscreen_portraits/zim_silho.tex" ),    Asset( "ATLAS", "images/selectscreen_portraits/zim_silho.xml" ),    Asset( "IMAGE", "bigportraits/zim.tex" ),    Asset( "ATLAS", "bigportraits/zim.xml" ),Asset( "IMAGE", "images/map_icons/zim.tex" ),Asset( "ATLAS", "images/map_icons/zim.xml" ),Asset( "IMAGE", "images/avatars/avatar_zim.tex" ),    Asset( "ATLAS", "images/avatars/avatar_zim.xml" ),Asset( "IMAGE", "images/avatars/avatar_ghost_zim.tex" ),    Asset( "ATLAS", "images/avatars/avatar_ghost_zim.xml" ),Asset( "IMAGE", "images/map_icons/minimoose.tex" ),    Asset( "ATLAS", "images/map_icons/minimoose.xml" ),}AddPrefabPostInit('minimoose')AddMinimapAtlas("images/map_icons/minimoose.xml")

 

prefabs/minimoose.lua

require "prefabutil"local brain = require "brains/minimoosebrain"local WAKE_TO_FOLLOW_DISTANCE = 14local SLEEP_NEAR_LEADER_DISTANCE = 7local assets ={    Asset("ANIM", "anim/ui_chest_3x3.zip"),    Asset("ANIM", "anim/chester.zip"),    Asset("ANIM", "anim/chester_build.zip"),    Asset("SOUND", "sound/chester.fsb"),}local prefabs ={    "minimoose_ctrl",    "chesterlight"}local function ShouldWakeUp(inst)    return DefaultWakeTest(inst) or not inst.components.follower:IsNearLeader(WAKE_TO_FOLLOW_DISTANCE)endlocal function ShouldSleep(inst)    --print(inst, "ShouldSleep", DefaultSleepTest(inst), not inst.sg:HasStateTag("open"), inst.components.follower:IsNearLeader(SLEEP_NEAR_LEADER_DISTANCE))    return DefaultSleepTest(inst) and not inst.sg:HasStateTag("open") and inst.components.follower:IsNearLeader(SLEEP_NEAR_LEADER_DISTANCE) and not TheWorld.state.isfullmoonendlocal function ShouldKeepTarget()    return false -- chester can't attack, and won't sleep if he has a targetendlocal function OnOpen(inst)    if not inst.components.health:IsDead() then        inst.sg:GoToState("open")    endend local function OnClose(inst)    if not inst.components.health:IsDead() and inst.sg.currentstate.name ~= "transition" then        inst.sg:GoToState("close")    endend -- eye bone was killed/destroyedlocal function OnStopFollowing(inst)    --print("chester - OnStopFollowing")    inst:RemoveTag("companion")endlocal function OnStartFollowing(inst)    --print("chester - OnStartFollowing")    inst:AddTag("companion")endlocal function create_minimoose()    --print("chester - create_chester")    local inst = CreateEntity()        inst.entity:AddTransform()    inst.entity:AddAnimState()    inst.entity:AddSoundEmitter()    inst.entity:AddDynamicShadow()    inst.entity:AddMiniMapEntity()    inst.entity:AddNetwork()    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:AddTag("companion")    inst:AddTag("character")    inst:AddTag("scarytoprey")    inst:AddTag("minimoose")    inst:AddTag("notraptrigger")    inst.MiniMapEntity:SetIcon("chester.png")    inst.MiniMapEntity:SetCanUseCache(false)    inst.AnimState:SetBank("minimoose")    inst.AnimState:SetBuild("minimoose_build")    inst.DynamicShadow:SetSize(2, 1.5)    inst.Transform:SetFourFaced()    inst.entity:SetPristine()    ------------------------------------------    --print("   combat")    inst:AddComponent("combat")    inst.components.combat.hiteffectsymbol = "chester_body"    inst.components.combat:SetKeepTargetFunction(ShouldKeepTarget)    --inst:ListenForEvent("attacked", OnAttacked)    --print("   health")    inst:AddComponent("health")    inst.components.health:SetMaxHealth(TUNING.CHESTER_HEALTH)    inst.components.health:StartRegen(TUNING.CHESTER_HEALTH_REGEN_AMOUNT, TUNING.CHESTER_HEALTH_REGEN_PERIOD)    inst:AddTag("noauradamage")    --print("   inspectable")    inst:AddComponent("inspectable")inst.components.inspectable:RecordViews()    --inst.components.inspectable.getstatus = GetStatus    --print("   locomotor")    inst:AddComponent("locomotor")    inst.components.locomotor.walkspeed = 3    inst.components.locomotor.runspeed = 7    --print("   follower")    inst:AddComponent("follower")    inst:ListenForEvent("stopfollowing", OnStopFollowing)    inst:ListenForEvent("startfollowing", OnStartFollowing)    --print("   knownlocations")    inst:AddComponent("knownlocations")    --print("   burnable")    MakeSmallBurnableCharacter(inst, "chester_body")        --("   container")    inst:AddComponent("container")    inst.components.container:WidgetSetup("chester")    inst.components.container.onopenfn = OnOpen    inst.components.container.onclosefn = OnClose    --print("   sleeper")    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)    MakeHauntableDropFirstItem(inst)    AddHauntableCustomReaction(inst, function(inst, haunter)        if math.random() <= TUNING.HAUNT_CHANCE_ALWAYS then            inst.components.hauntable.panic = true            inst.components.hauntable.panictimer = TUNING.HAUNT_PANIC_TIME_SMALL            inst.components.hauntable.hauntvalue = TUNING.HAUNT_SMALL            return true        end        return false    end, false, false, true)    --print("   sg")    inst:SetStateGraph("SGminimoose")    inst.sg:GoToState("idle")    --print("   brain")    inst:SetBrain(brain)    --print("chester - create_chester END")    return instendreturn Prefab("common/minimoose", create_minimoose, assets, prefabs)

 

prefabs/minimoose_ctrl.lua

local assets ={    Asset("ANIM", "anim/minimoose_ctrl.zip"),    Asset("ANIM", "anim/minimoose_ctrl_build.zip"),}local SPAWN_DIST = 30local trace = function() endlocal function GetSpawnPoint(pt)    local theta = math.random() * 2 * PI    local radius = SPAWN_DISTlocal offset = FindWalkableOffset(pt, theta, radius, 12, true)return offset ~= nil and (pt + offset) or nilendlocal function SpawnMinimoose(inst)    --print("chester_eyebone - SpawnChester")    local pt = inst:GetPosition()    --print("    near", pt)            local spawn_pt = GetSpawnPoint(pt)    if spawn_pt ~= nil then        --print("    at", spawn_pt)        local minimoose = SpawnPrefab("minimoose")        if minimoose ~= nil then            minimoose.Physics:Teleport(spawn_pt:Get())            minimoose:FacePoint(pt:Get())            return minimoose        end    --else        -- this is not fatal, they can try again in a new location by picking up the bone again        --print("chester_eyebone - SpawnChester: Couldn't find a suitable spawn point for chester")    endendlocal StartRespawnlocal function StopRespawn(inst)    --print("chester_eyebone - StopRespawn")    if inst.respawntask ~= nil then        inst.respawntask:Cancel()        inst.respawntask = nil        inst.respawntime = nil    endendlocal function RebindMinimoose(inst, minimoose)    minimoose = minimoose or TheSim:FindFirstEntityWithTag("minimoose")    if minimoose ~= nil then        inst.AnimState:PlayAnimation("idle_loop", true)        inst:ListenForEvent("death", function() StartRespawn(inst, TUNING.MINIMOOSE_RESPAWN_TIME) end, minimoose)        if minimoose.components.follower.leader ~= inst then            minimoose.components.follower:SetLeader(inst)        end        return true    endendlocal function RespawnMinimoose(inst)    --print("chester_eyebone - RespawnChester")    StopRespawn(inst)    RebindMinimoose(inst, TheSim:FindFirstEntityWithTag("minimoose") or SpawnMinimoose(inst))endStartRespawn = function(inst, time)    StopRespawn(inst)    time = time or 0    inst.respawntask = inst:DoTaskInTime(time, RespawnMinimoose)    inst.respawntime = GetTime() + time    inst.AnimState:PlayAnimation("dead", true)endlocal function FixMinimoose(inst)inst.fixtask = nil--take an existing chester if there is oneif not RebindMinimoose(inst) then        inst.AnimState:PlayAnimation("dead", true)if inst.components.inventoryitem.owner ~= nil thenlocal time_remaining = 0local time = GetTime()if inst.respawntime and inst.respawntime > time thentime_remaining = inst.respawntime - time endStartRespawn(inst, time_remaining)endendendlocal function OnPutInInventory(inst)    if inst.fixtask == nil then        inst.fixtask = inst:DoTaskInTime(1, FixMinimoose)    endendlocal function OnSave(inst, data)    --print("chester_eyebone - OnSave")    if inst.respawntime ~= nil then        local time = GetTime()        if inst.respawntime > time then            data.respawntimeremaining = inst.respawntime - time        end    endendlocal function OnLoad(inst, data)    if data == nil then        return    end    if data.respawntimeremaining ~= nil then        inst.respawntime = data.respawntimeremaining + GetTime()    endendlocal function GetStatus(inst)    --print("smallbird - GetStatus")    if inst.respawntask ~= nil then        return "WAITING"    endendlocal function fn()    local inst = CreateEntity()    inst.entity:AddTransform()    inst.entity:AddAnimState()    inst.entity:AddNetwork()    --so I can find the thing while testing    --inst.entity:AddMiniMapEntity()    --inst.MiniMapEntity:SetIcon("treasure.png")    MakeInventoryPhysics(inst)    inst:AddTag("minimoose_ctrl")    inst:AddTag("irreplaceable")    inst:AddTag("nonpotatable")    inst.AnimState:SetBank("minimoose_ctrl")    inst.AnimState:SetBuild("minimoose_ctrl_build")    inst.AnimState:PlayAnimation("idle_loop", true)    if not TheWorld.ismastersim then        return inst    end    inst.entity:SetPristine()    inst:AddComponent("inventoryitem")    inst.components.inventoryitem:SetOnPutInInventoryFn(OnPutInInventory)    inst.components.inventoryitem.imagename = "minimoose_ctrl"    inst.components.inventoryitem.atlasname = "images/inventoryimages/minimoose_ctrl.xml"    inst:AddComponent("inspectable")    inst.components.inspectable.getstatus = GetStatusinst.components.inspectable:RecordViews()    inst:AddComponent("leader")    MakeHauntableLaunch(inst)    inst.OnLoad = OnLoad    inst.OnSave = OnSaveinst.fixtask = inst:DoTaskInTime(1, FixMinimoose)    return instendreturn Prefab("common/minimoose_ctrl", fn, assets)

 

prefabs/brains/minimoosebrain.lua

require "behaviours/follow"require "behaviours/wander"require "behaviours/faceentity"require "behaviours/panic"local MIN_FOLLOW_DIST = 0local MAX_FOLLOW_DIST = 12local TARGET_FOLLOW_DIST = 6local MAX_WANDER_DIST = 3local function GetFaceTargetFn(inst)    return inst.components.follower.leaderendlocal function KeepFaceTargetFn(inst, target)    return inst.components.follower.leader == targetendlocal MinimooseBrain = Class(Brain, function(self, inst)    Brain._ctor(self, inst)end)function MinimooseBrain:OnStart()    local root =     PriorityNode({        WhileNode( function() return self.inst.components.hauntable and self.inst.components.hauntable.panic end, "PanicHaunted", Panic(self.inst)),        WhileNode( function() return self.inst.components.health.takingfiredamage end, "OnFire", Panic(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),        Wander(self.inst, function() return self.inst.components.knownlocations:GetLocation("home") end, MAX_WANDER_DIST),            }, .25)    self.bt = BT(self.inst, root)endreturn MinimooseBrain

 

prefabs/stategraphs/SGminimoose.lua

require("stategraphs/commonstates")local actionhandlers = {}local events={    CommonHandlers.OnStep(),    CommonHandlers.OnSleep(),    CommonHandlers.OnLocomote(false,true),    EventHandler("attacked", function(inst)        if inst.components.health and not inst.components.health:IsDead() then            inst.sg:GoToState("hit")            inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/hurt")        end    end),    EventHandler("death", function(inst) inst.sg:GoToState("death") end),}local states={    State{        name = "idle",        tags = {"idle", "canrotate"},                onenter = function(inst, pushanim)            inst.Physics:Stop()            inst.AnimState:PlayAnimation("idle_loop")                        if not inst.sg.mem.pant_ducking or inst.sg:InNewState() theninst.sg.mem.pant_ducking = 1end        end,                events=        {            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),        },        timeline=        {            TimeEvent(7*FRAMES, function(inst) inst.sg.mem.pant_ducking = inst.sg.mem.pant_ducking or 1inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/pant", nil, inst.sg.mem.pant_ducking) if inst.sg.mem.pant_ducking and inst.sg.mem.pant_ducking > .35 theninst.sg.mem.pant_ducking = inst.sg.mem.pant_ducking - .05endend),        },           },           State{        name = "death",        tags = {"busy"},                onenter = function(inst)            inst.components.container:Close()            inst.components.container:DropEverything()            inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/death")            inst.AnimState:PlayAnimation("death")            inst.Physics:Stop()            RemovePhysicsColliders(inst)                    end,    },        State{        name = "open",        tags = {"busy", "open"},                onenter = function(inst)            inst.Physics:Stop()            inst.components.sleeper:WakeUp()            inst.AnimState:PlayAnimation("open")        end,        events=        {               EventHandler("animover", function(inst) inst.sg:GoToState("open_idle") end ),        },        timeline=        {            TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/open") end),        },            },    State{        name = "open_idle",        tags = {"busy", "open"},                onenter = function(inst)            inst.AnimState:PlayAnimation("idle_loop_open")                        if not inst.sg.mem.pant_ducking or inst.sg:InNewState() theninst.sg.mem.pant_ducking = 1end                    end,        events=        {               EventHandler("animover", function(inst) inst.sg:GoToState("open_idle") end ),        },        timeline=        {                            TimeEvent(3*FRAMES, function(inst) inst.sg.mem.pant_ducking = inst.sg.mem.pant_ducking or 1inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/pant", nil, inst.sg.mem.pant_ducking) if inst.sg.mem.pant_ducking and inst.sg.mem.pant_ducking > .35 theninst.sg.mem.pant_ducking = inst.sg.mem.pant_ducking - .05endend),        },            },    State{        name = "close",                onenter = function(inst)            inst.AnimState:PlayAnimation("closed")        end,        events=        {               EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),        },        timeline=        {            TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/close") end),        },            },    State{        name = "transition",        tags = {"busy"},        onenter = function(inst)            inst.Physics:Stop()            --Remove ability to open chester for short time.            inst.components.container:Close()            inst.components.container.canbeopened = false            --Create light shaft            inst.sg.statemem.light = SpawnPrefab("chesterlight")            inst.sg.statemem.light.Transform:SetPosition(inst:GetPosition():Get())            inst.sg.statemem.light:TurnOn()            inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/raise")            inst.AnimState:PlayAnimation("idle_loop")            inst.AnimState:PushAnimation("idle_loop")            inst.AnimState:PushAnimation("idle_loop")            inst.AnimState:PushAnimation("transition", false)        end,        onexit = function(inst)            --Add ability to open chester again.            inst.components.container.canbeopened = true            --Remove light shaft            if inst.sg.statemem.light then                inst.sg.statemem.light:TurnOff()            end        end,        timeline =         {            TimeEvent(56*FRAMES, function(inst)                 local x, y, z = inst.Transform:GetWorldPosition()                SpawnPrefab("chester_transform_fx").Transform:SetPosition(x, y + 1, z)            end),            TimeEvent(60*FRAMES, function(inst)                inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/pop")            end),        },        events =        {            EventHandler("animqueueover", function(inst) inst.sg:GoToState("idle") end ),        },    },}CommonStates.AddWalkStates(states, {    walktimeline =     {         --TimeEvent(0*FRAMES, function(inst)  end),        TimeEvent(1*FRAMES, function(inst)             inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/boing")            inst.components.locomotor:RunForward()         end),        --TimeEvent(12*FRAMES, function(inst) PlayFootstep(inst) end),        TimeEvent(14*FRAMES, function(inst)             PlayFootstep(inst)            inst.components.locomotor:WalkForward()        end),    }}, nil, true)CommonStates.AddSleepStates(states,{    starttimeline =     {        TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/close") end)    },    waketimeline =     {        TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/chester/open") end)    },})CommonStates.AddSimpleState(states, "hit", "hit", {"busy"})return StateGraph("minimoose", states, events, "idle", actionhandlers)

 

And I put minimoose_ctrl in his start inventory instead of chester_eyebone.

 

 

But I got this error when I starts the new world:

post-549594-0-06104000-1424678295_thumb.

 

Can you help me with solve this problem?

 

I think there are many error/missed parts in edited lua...

Maybe this is too big project to a beginner, but I want do my best to make the mod better.

I would really appreciate if you could help me.

 

Thank you for reading this far!

Edited by Naplez

Share this post


Link to post
Share on other sites
rezecib    3170

@Kzisor, Naplez did make it a new item.

 

@Naplez, I think the problem is that you didn't add minimoose_ctrl to the PrefabFiles table, the crash you're showing means that SpawnPrefab('minimoose_ctrl') returned nil.

Edited by rezecib

Share this post


Link to post
Share on other sites
Naplez    3

Don't use chester_eyebone, make it a new item. There is massive headache otherwise.

 

@Kzisor, Naplez did make it a new item.

 

@Naplez, I think the problem is that you didn't add minimoose_ctrl to the PrefabFiles table, the crash you're showing means that SpawnPrefab('minimoose_ctrl') returned nil.

 

Thank you! I'll try!

Share this post


Link to post
Share on other sites
afetogbo    37

kooky and I have made a working blue chester mod. it adds a blue chester to the game and leaves the original alone.  if you want any help with minimoose let me know.

Share this post


Link to post
Share on other sites
Naplez    3

kooky and I have made a working blue chester mod. it adds a blue chester to the game and leaves the original alone.  if you want any help with minimoose let me know.

 

Oh my god, thank you for letting me know! You did a truly one great job! I'll check your blue chester mod on workshop. Thank you so much!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this