Jump to content

Recommended Posts

Let's say I have a char mod called "mychar" and with a hotkey button this char can "take root" while he heals nearby players.

I have the code in modmain.lua works but only if there is only one mychar. WIth more than one mychars an issue happens as follows:

mychar A presses the hotkey button and takes root. Mychar B suddenly stops and unable to walk/move.

How do you fix this?

Code below adapted from Luffy. Modmain.lua:

local function RootUnrootFn(inst)
    if inst:HasTag("playerghost") then return end
    
    --go back to normal
    if inst.transformed then
        local x, y, z = inst.Transform:GetWorldPosition()
        local fx = GLOBAL.SpawnPrefab("groundpound_fx")
        inst.SoundEmitter:PlaySound("dontstarve_DLC001/creatures/bearger/groundpound")
        fx.Transform:SetPosition(x, y, z)
        GLOBAL.SpawnPrefab("collapse_big").Transform:SetPosition(inst:GetPosition():Get())
        
        inst.AnimState:SetMultColour(1,1,1,1)
        
        if inst.components.health then
            inst.components.health.absorb = 0
        end
        
        if inst.components.hunger then
            inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE * 1)
        end
        
        if inst.rootedhealtask ~= nil then
            inst.rootedhealtask:Cancel()
            inst.rootedhealtask = nil
        end
        
        if inst.components.combat then
            inst.components.combat.canattack = true
        end
        
        SetModHUDFocus("mycharhud", false)
        
    --root
    else
        local x, y, z = inst.Transform:GetWorldPosition()
        local fx = GLOBAL.SpawnPrefab("groundpound_fx")
        inst.SoundEmitter:PlaySound("dontstarve_DLC001/creatures/bearger/groundpound")
        fx.Transform:SetPosition(x, y, z)
        GLOBAL.SpawnPrefab("collapse_big").Transform:SetPosition(inst:GetPosition():Get())
        GLOBAL.SpawnPrefab("mole_move_fx").Transform:SetPosition(inst.Transform:GetWorldPosition())
        
        for i, v in ipairs(GLOBAL.AllPlayers) do
            v:ShakeCamera(GLOBAL.CAMERASHAKE.FULL, .7, .02, .3, inst, 40) --does not seem to work
        end
        
        inst.AnimState:SetMultColour(0,1,0,1)
        
        if inst.components.locomotor then
            inst.components.locomotor:Stop()
        end
        
        if inst.components.health then
            inst.components.health.absorb = 0.7
        end
        
        if inst.components.hunger then
            inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE * 3)
        end
        
        if inst.rootedhealtask == nil then
            inst.rootedhealtask = inst:DoPeriodicTask(10, dorootedhealtask)
        end
        
        if inst.components.combat then
            inst.components.combat.canattack = false
            inst.components.combat:SetTarget(nil)
        end
        
        SetModHUDFocus("mycharhud", true)
     
    end
     
    inst.transformed = not inst.transformed

    return true
end

AddModRPCHandler("mychar", "RootUnroot", RootUnrootFn)

 

And in mychar.lua:

local common_postinit = function(inst)

  ...

  inst.transformed = false

  inst.AddComponent("keyhandler")

  inst.components.keyhandler:AddActionListener("mychar", MYCHAR_ROOTUNROOTKEY, "RootUnroot")

  ...

end

 

Question #2

Is this the correct way to add "hotkeys"?

(keyhandler component is from Luffy mod also)

 

Thanks.

What does dorootedhealtask function do?

But I think the problem is in that SetModHUDFocus is being executed within mod RPC handler, thus on the host/server. On the dedicated server this would have no effect apart from message in the log, on hosted server this would disable host's HUD, not the client's.

Edited by Muche
10 hours ago, SenL said:

Let's say I have a char mod called "mychar" and with a hotkey button this char can "take root" while he heals nearby players.

I have the code in modmain.lua works but only if there is only one mychar. WIth more than one mychars an issue happens as follows:

mychar A presses the hotkey button and takes root. Mychar B suddenly stops and unable to walk/move.

How do you fix this?

Remove SetModHUDFocus stuff, it's not needed. What you should do is set an external speed multiplier on the locomotor to 0 when you press the key then remove it when you press it again.

if inst:HasTag("playerghost") then return end
    
    --go back to normal
    if inst.transformed then
        local x, y, z = inst.Transform:GetWorldPosition()
        local fx = GLOBAL.SpawnPrefab("groundpound_fx")
        inst.SoundEmitter:PlaySound("dontstarve_DLC001/creatures/bearger/groundpound")
        fx.Transform:SetPosition(x, y, z)
        GLOBAL.SpawnPrefab("collapse_big").Transform:SetPosition(inst:GetPosition():Get())
        
        inst.AnimState:SetMultColour(1,1,1,1)
        
        if inst.components.health then
            inst.components.health.absorb = 0
        end
        
        if inst.components.hunger then
            inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE * 1)
        end
        
	if inst.components.locomotor then
            inst.components.locomotor:Stop()
		inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, inst)
        end

        if inst.rootedhealtask ~= nil then
            inst.rootedhealtask:Cancel()
            inst.rootedhealtask = nil
        end
        
        if inst.components.combat then
            inst.components.combat.canattack = true
        end
        
        --SetModHUDFocus("mycharhud", false)
        
    --root
    else
        local x, y, z = inst.Transform:GetWorldPosition()
        local fx = GLOBAL.SpawnPrefab("groundpound_fx")
        inst.SoundEmitter:PlaySound("dontstarve_DLC001/creatures/bearger/groundpound")
        fx.Transform:SetPosition(x, y, z)
        GLOBAL.SpawnPrefab("collapse_big").Transform:SetPosition(inst:GetPosition():Get())
        GLOBAL.SpawnPrefab("mole_move_fx").Transform:SetPosition(inst.Transform:GetWorldPosition())
        
        for i, v in ipairs(GLOBAL.AllPlayers) do
            v:ShakeCamera(GLOBAL.CAMERASHAKE.FULL, .7, .02, .3, inst, 40) --does not seem to work
        end
        
        inst.AnimState:SetMultColour(0,1,0,1)
        
        if inst.components.locomotor then
            inst.components.locomotor:Stop()
		inst.components.locomotor:SetExternalSpeedMultiplier(inst, inst, 0)
        end
        
        if inst.components.health then
            inst.components.health.absorb = 0.7
        end
        
        if inst.components.hunger then
            inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE * 3)
        end
        
        if inst.rootedhealtask == nil then
            inst.rootedhealtask = inst:DoPeriodicTask(10, dorootedhealtask)
        end
        
        if inst.components.combat then
            inst.components.combat.canattack = false
            inst.components.combat:SetTarget(nil)
        end
        
        --SetModHUDFocus("mycharhud", true)
     
    end
     
    inst.transformed = not inst.transformed

    return true

This code will prevent only you from moving while allowing others of your character to move. There is a small animation issue which shows you "running" when you press keys, but you don't move. You could go the long route of making it act like a true root, but the effort isn't worth it to be honest.

10 hours ago, SenL said:

Question #2

Is this the correct way to add "hotkeys"?

(keyhandler component is from Luffy mod also)

The Keyhandler component that Arcade from Steam Workshop is using; is the one I created. To answer the question yes it is the proper way to create hotkeys and handle them on both dedicated servers and hosted servers.

 

Edited by Kzisor
Fixed code, stupid typo.

Kzisor: I will add credit to you for the Keyhandler component. Thanks for that.

The reason I want to go with SetModHUDFocus is to also disable hud completely to avoid user to eat (since rooting drains hunger fast).

Modifying only locomotor works but it was not enough.

 

I tried doing the net_bool thing with eventlistener but failed miserably. I don't understand this yet.

Here's what I did:

mychar.lua

...

local function OnRootUnRootDirty(inst)
    if inst._transformeddirty:value() == true then
        SetModHUDFocus("mychar", true)
    else
        SetModHUDFocus("mychar", false)
    end
end

local function OnRootUnRoot(inst)
    if inst.transformed == true then
        SetModHUDFocus("mychar", true)
    else
        SetModHUDFocus("mychar", false)
    end
end

...

local common_postinit = function(inst)

...

inst._transformeddirty = net_bool(inst.GUID, "_transformeddirty", "onrootunrootdirty")

if not TheWorld.ismastersim then

  inst:ListenForEvent("onrootunrootdirty", "OnRootUnRootDirty")

else

  inst:ListenForEvent("onrootunroot", "OnRootUnroot")

end

...

end

 

modmain.lua

local function RootUnrootFn(inst)

  ...

  if inst.transformed then

    ...

    inst._transformeddirty:set(false)

  else

    ...

    inst._transformeddirty:set(true)

  end

end

 

It doesn't work. It may be missing PushEvent somewhere and/or may contain major flaws.

Any help to understand how net variables work and how the host uses them (with event listeners and pushevents etc).

Looking at Yoda in Starve Wars mod, I may be able to do something like that

 

Spoiler

 

inst.components.locomotor:SetExternalSpeedMultiplier(inst, "Yoda", 0.01)

    inst:SetStateGraph("SGwilsonghost")
    inst.sg:GoToState("idle")

    if inst.components.playercontroller ~= nil then
        inst.components.playercontroller:Enable(false)
    end    

    if not inst.AnimState:IsCurrentAnimation("idle") then
                inst.AnimState:PlayAnimation("idle", true)
    end

 

 

Hmm...

 

Edit:

Yes! It seems to work. I still need to test it in multiplayer though.

Edited by SenL

Hm still able to eat even when rooted. Not desirable.

This is also what Muche suggested in Disable Combat thread.

Edit:

Following up on that thread, I will now try to modify GLOBAL.ACTIONS.EAT.fn

Edit:

Yup it works.

local old_Eat = GLOBAL.ACTIONS.EAT.fn
GLOBAL.ACTIONS.EAT.fn = function(act)
    if act.doer.prefab == "mychar" and act.doer.transformed == true then
        return --can't eat while rooted
    end
    return old_Eat(act)
end

Nice.

Edited by SenL

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
×
  • Create New...