Jump to content

[Help] left/rightclickoverride does not work in client


Recommended Posts

I'm trying to override the click but it just work on server side, On server everything works well, but in client side the click functions stay unchanged.
Here's my code:

local function LeftActions(inst, target, position) 
    if target and inst:HasTag("other") then  
		if target ~= nil and target ~= inst then
			if inst.replica.combat:CanTarget(target) then
			  return (not target:HasTag("player") or inst.components.playercontroller:IsControlPressed(CONTROL_FORCE_ATTACK))
				  and inst.components.playeractionpicker:SortActionList({ ACTIONS.ATTACK }, target, nil)
				  or nil
     		end
	   end              
end

[...]
-- Change leftclick actions
if leftClick then
		inst.components.playeractionpicker.leftclickoverride = nil
	else 
		inst.components.playeractionpicker.leftclickoverride = LeftActions
	end
[...]                

Any suggestion?

Link to comment
Share on other sites

I tried running ThePlayer.components.playeractionpicker.leftclickoverride = LeftActions in the console while on my dedicated server (local mode) and it worked, in that the LeftAction function was being periodically executed.

Is your Change leftclick actions section being executed on the client as well or is it after TheWorld.ismastersim check?

Link to comment
Share on other sites

Can you explain me how does  TheWorld.ismastersim works?
I thought that it is only for new components or prefabs and I'm just working on a character based on a existing things.

sorry my english :)

Link to comment
Share on other sites

TheWorld.ismastersim is true on the server/host and false on the client. Thus it's used to determine which parts of the code are accessible on server/client, since some components are available only on server.
However its value is set after the world is initialized, so it can't be used directly in the modmain. For that one can use TheNet:GetIsServer() or TheNet:GetIsClient().

Also see

I found this piece of code in one of my test mods (to be put into modmain):

local function getmastersims()
    local ismastersim = GLOBAL.TheWorld == nil and "TheWorld_nil" or GLOBAL.TheWorld.ismastersim
    local isdedicated
    if GLOBAL.TheNet then
        local isded = GLOBAL.TheNet:IsDedicated()
        if isded == nil then
            isdedicated = "TheNetIsDedicated_nil"
        else
            isdedicated = isded
        end
    else
        isdedicated = "TheNet_nil"
    end
    local isserver
    if GLOBAL.TheNet then
        local isser = GLOBAL.TheNet:GetIsServer()
        if isser == nil then
            isserver = "TheNetGetIsServer_nil"
        else
            isserver = isser
        end
    else
        isserver = "TheNet_nil"
    end
    return string.format("ismastersim=%s, isdedicated=%s, isserver=%s", tostring(ismastersim), tostring(isdedicated), tostring(isserver))
end

GLOBAL.getmastersims = getmastersims

Then entered into debug console print(getmastersims()) whenever I wanted to print all those three values, to see how they changed.

Edited by Muche
Link to comment
Share on other sites

Ok thanks for the explanation.
But in my problem case, i have to run that code (leftclickoverride) on client or host side?
So, how can i force run on client/host? 
I tried call then both in common_postinit and and master_postinit together TheWorld.ismastersim if but did not work.

Link to comment
Share on other sites

I'd recommend doing some research first: put a uniquely identifiable debug print into the function of interest (in this case PlayerActionPicker:GetLeftClickActions and PlayerActionPicker:GetRightClickActions, play the game and see if it appears when you expect it to and if it shows up in client_log when hosting a world/playing as client or server_log when hosting multilevel world.
I usually go with something like print(string.format("[PlayerActionPicker:GetLeftClickActions(%s,%s)] self.leftclickoverride=%s", tostring(position), tostring(target), tostring(self.leftclickoverride))), or, since self.leftclickoverride can hold a function, I might go with

local function format_fn(fn)
    assert(type(fn) == "function", string.format("Type of fn is %s, expected function", type(fn)))
    local info = debug.getinfo(fn)
    return string.format("%s %s %s <%s-%s>", tostring(fn), tostring(info.source), tostring(info.name or "?"), tostring(info.linedefined), tostring(info.lastlinedefined))
end
local _fn = type(self.leftclickoverride) == "function" and format_fn(self.leftclickoverride) or tostring(self.leftclickoverride)
print(string.format("[PlayerActionPicker:GetLeftClickActions(%s,%s)] self.leftclickoverride=%s", tostring(position), tostring(target), _fn))

In this case, if I am not mistaken, GetLeft|RightClickActions runs on client, so having the code section in common_postinit seems more appropriate.

However, looking into player_common.lua, playeractionpicker component is being added in OnSetOwner(), which is used as a listener for setowner event, so it's possible that playeractionpicker component might not yet exist at the time the common_postinit function is run. You might need delayed execution with something like

inst:DoTaskInTime(0.5, function()
    if inst.components.playeractionpicker ~= nil then
        if leftClick then
            inst.components.playeractionpicker.leftclickoverride = nil
        else 
            inst.components.playeractionpicker.leftclickoverride = LeftActions
        end
    else
        print(string.format("[UniqueFoobar] playeractionpicker component of inst (%s) is nil", tostring(inst)))
    end
end)

In player_common|MakePlayerCharacter()|fn() can be seen how common_postinit and master_postinit parameters are used in regards to TheWorld.ismastersim - first the common_postinit is executed (if defined), then TheWorld.ismastersim check determines if it is being run on the server (the rest of the function is executed, which includes execution of master_postinit) or client (function returns).

Link to comment
Share on other sites

I really can not make it work. :(
I'm based in woodie code and I can't understand why some functions doesn't works like:
inst.components.playeractionpicker.leftclickoverride

inst.components.playeractionpicker.rightclickoverride

inst.components.playercontroller.actionbuttonoverride 

inst.components.playervision:ForceNightVision(true)

inst.components.playervision:SetCustomCCTable(BEAVERVISION_COLOURCUBES)

 

 

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...