Jump to content

Mod works for host but not for clients


Recommended Posts

In this mod I'm trying to make it so when I give "petals" to a koalefant_summer it becomes a follower.

But in order to be able to give it the flower, I need to make it stop running away when I'm trying to give it something. So I wrote my own custom ShouldRunAway function that checks if the if the player is trying to trade with the koalefant.

 

It works when I play it as the Host. But it does not work if I'm playing as a Client, including when I am hosting but have caves turned on.

 

But the thing is, I know my custom ShouldRunAway method is still being used, because it also stops the Koalefant from running away if it is a follower to the player, and that part does work as a client. It's only the part where I need to check if the user is trying to trade with the Koalefant that does not work. Any ideas?

 

On a possibly related note, any print( ) calls that I make inside my CustomShouldRunAway function are not showing up in the console, so I don't know what's going on. But again I do know that this method is being ran. If I comment it out the Koalefant still runs away when I am its leader, When I uncomment it out the Koalefant stops running away when I am its leader. I have no doubt that this function is running, but I don't know why the check for IsTryingToTradeWithMe fails and I don't know why the prints aren't working.

 

 

Koalefant.zip

Edited by HomShaBom
Link to comment
Share on other sites

Can't take a look right now, but usually, when an host could do something but client can't (like when you host world with cave, you are client), then it's because a component, that should be only server side, is also client side. So either you lack a 


    if not TheWorld.ismastersim then
        return inst
    end

Or a similar test somewhere.

Not sure, but look like this.

Link to comment
Share on other sites

I am checking TheWorld.ismastersim in the AddPrefabPostInit function:

local function MakeFollower(inst)
  if TheWorld.ismastersim then
    if inst.components.trader == nil then
      inst:AddComponent("trader")
    end
    local trader = inst.components.trader
    trader:SetAcceptTest(ShouldAcceptItem)
    trader.onaccept = OnGetItemFromPlayer
    trader.onrefuse = OnRefuseItem

    if inst.components.follower == nil then
      inst:AddComponent("follower")
    end
    local follower = inst.components.follower
    follower.maxfollowtime = TUNING.TOTAL_DAY_TIME * 0.6
  end
end

AddPrefabPostInit("koalefant_summer", MakeFollower)

In the AddBrainPostInit function, I am not checking TheWorld.ismastersim. I'm not sure where, if anywhere, it would go in this function. When I tried to put it in, it just caused a disconnect whenever a Koalefant spawned

AddBrainPostInit("koalefantbrain", function(brain)

  local function CustomShouldRunAway(inst, target, oldfn)
    -- If they want to give me something, I'll stay put.
    if inst.components.trader ~= nil and inst.components.trader:IsTryingToTradeWithMe(target) then
      return false
    end

    -- If it is my leader, I won't run away
    if inst.components.follower ~= nil and inst.components.follower.leader == target then
      -- But if my leader is trying to hurt me, I'm outta here!
      if target.components.combat ~= nil and target.components.combat.target == inst then
        return true
      end
      return false
    end

    -- Custom rules have been evaluated, fall back to default behavior
    return oldfn(target)
  end

  for i,v in ipairs(brain.bt.root.children) do
    if v.name == "Sequence" then
      for j,k in ipairs(v.children) do
        if k.name == "RunAway" then

          local old_shouldrunfn = k.hunterfn
          k.hunterfn = function(target)
            return CustomShouldRunAway(brain.inst, target, old_shouldrunfn)
          end

          break
        end
      end
      break
    end
  end
end)

 

Link to comment
Share on other sites

When I removed the check for mastersim it makes the game crash instantly when a koalefant spawns.

Put the check back in, game doesn't crash but 

 inst.components.trader:IsTryingToTradeWithMe(target) 

still returns false when it should return true.

Edited by HomShaBom
Link to comment
Share on other sites

It has to do with the replication system the game uses.
There are certain stuff that only exist on the serve, brains are one of these things, certain components, and many other things get replicated to the clients without actually existing on the clients.
If you are hosting a game (with no caves) there will be no problem since you are running the game locally (the server is also the client, put in simple words). With caves, since you need to have dedicated servers for caves and up-top. So, in fact, you are actually running three different instances of the game: one that hosts the caves, one that hosts the regular world, and another one which will be the client.

Also, the prints you are talking about are being printed in the server's log. Check your log files (In Windows it will be in your Documents/Klei/Don't Starve Together folder)

I hope I have shed some light on your problem. Once you see the log's with the errors I thing you'll be able to advance.

PS: On a project I'm working in, I needed to use RPC's to change the brains of a character, but I was swapping the whole brain for a new one upon a click. If you just what to had some behaviour to some brain, I think that your approach is the correct one.

Link to comment
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
 Share

×
  • Create New...