Jump to content

Making the mouse work with controller in DST


Recommended Posts

So a mod exists for this already under DS, but I want it to work in DST because sometimes its just easier with the mouse to do stuff quickly, but it's really hard on my wrist to use a keyboard while moving around.

I noticed someone already tried to convert it but just dropped off the map here. I shot them a message to see if they made it work, but no reply:

So I tried messing around with it and changing the headers so it would load in DST but it crashes because (as pointed out in the OP linked).

[00:00:46]: error calling simpostinit in mod MouseController (EnableMouse with Controller): 
[string "../mods/mymod/modmain.lua"]:17: attempt to index local 'inst' (a nil value)
LUA ERROR stack traceback:
        ../mods/MouseController/modmain.lua(17,1)
        =(tail call) ?
        =[C] in function 'xpcall'
        scripts/mods.lua(165,1)
        scripts/mods.lua(772,1) in function 'SimPostInit'

I understand that inst. is coming back as nil because in DST inst. doesn't refer to what it should refer to, but I can't figure out what I should be referring to instead, and I can't find any documentation that would help me understand that relationship better.

Any recommendations on what I can read up on that might get me to a quick fix? Attached is the source that I'm messing around with if anyone wants to take crack at it.

modmain.lua

Link to comment
Share on other sites

From what I saw penguin comment on there, you're expecting inst to be GetPlayer() but is nil

Iirc, for DST, GetPlayer() is now ThePlayer. And refers to each person

For a client-only mod, this should be something like

GLOBAL.The Player

If that's still giving you a nil, I've seen the "Action Queue Reborn", and "Place Statues" mods do something like this before

AddComponentPostInit("playercontroller", function(self)
    ThePlayer = GLOBAL.ThePlayer
    TheWorld = GLOBAL.TheWorld
end)

 

Good luck :)

Edited by Bigfootmech
  • Wavey 1
Link to comment
Share on other sites

Thanks a ton for your reply. I'm not a LUA genius by any stretch, so I guess what's throwing me off is what does inst. do, and how does it interact with other components. For example, the problematic line is:

inst.components.playercontroller, so would I then just go to GLOBAL.ThePLayer.components.playercontroller, (and Ctrl-F the other ones) or should I define a replacement for inst like:
 

local ThePlayer =  GLOBAL.ThePlayer

Also, while I do understand the issue with ThePlayer (as there are many players, and therefore it could apply to others), I've seen "self" be used, and I'm not clear on how "self" and ThePlayer are different (other that perhaps ThePlayer can mean any player)

Link to comment
Share on other sites

I don't like "self", or "inst" for this reason either. They're shorthands that are not so obvious to me

(I'm also new to DST modding by the way)

 

 

In the "ActionQueue Reborn" mod, it actually has more stuff

AddComponentPostInit("playercontroller", function(self, inst)
    if inst ~= GLOBAL.ThePlayer then return end
    ThePlayer = GLOBAL.ThePlayer
    TheWorld = GLOBAL.TheWorld

	...

end)

So, as far as I can tell, GLOBAL.ThePlayer is an instance (client-side, the ONLY intance) of the /scripts/components/playercontroller.lua and that "playercontroller" is itself a "class"

Of course, classes don't exist by default in Lua. Just tables with functions in them, so this is a KleiLuaClass let's call it

Coding wise... Instances are a class that's been instantiated

ie: made from dead code in to live code, by a constructor

ie: made from a template (class), in to a living mutable thing (object/instance)

(my hunch is, in lua, I think this could be done by "shallow copying" an empty "class", but I don't know/haven't seen this part yet. and of course _ctor hints at use of metatables)

 

But although there is also a class file (/scripts/class.lua), I don't see it imported anywhere before for example a

local PlayerController = Class( function(self,inst) ... end)

is called in /scripts/components/playercontroller.lua

 

I'm assuming the Class(fn) function is the Class(base, _ctor, props) function inside /scripts/class.lua

 

But I don't know how this (or these "environments" people talked about) is set up yet.

 

Maybe someone else can shed further light on this?

 

But also maybe that's getting too off topic?

Edited by Bigfootmech
typo
Link to comment
Share on other sites

Also, if you already have an Object, and you're curious about it, you can try printing it for debug

In Lua, all the objects are tables, so we can do


for key, value in pairs(thingWeAreInterestedIn) do
	print(key)
	print(value)
end

there are even functions in util that do this recursively, but they might crash if the thing you're looking at is too big

And metatables are not my area of expertise :p

Link to comment
Share on other sites

23 hours ago, Bigfootmech said:

I don't like "self", or "inst" for this reason either. They're shorthands that are not so obvious to me

 

In the "ActionQueue Reborn" mod, it actually has more stuff


AddComponentPostInit("playercontroller", function(self, inst)
    if inst ~= GLOBAL.ThePlayer then return end
    ThePlayer = GLOBAL.ThePlayer
    TheWorld = GLOBAL.TheWorld

	...

end)

So, as far as I can tell, GLOBAL.ThePlayer is an instance (client-side, the ONLY intance) of the /scripts/components/playercontroller.lua and that "playercontroller" is itself a "class"

'self' should be used for when you're dealing with an object-like thing.  Objects have member functions and variables expected of them to exist (don't assume anything actually exists in modding as other mods can remove functions and such on the fly).

'inst' is usually used for an instance of something that may or may not have inherent characteristics of something.

In the case of AddComponentPostInit the callback function signature passes along the component created as the first argument "self" and then the owner of the component as the second argument "inst".

All components have a member variable called "inst" which is this second argument being passed so it's a bit redundant for this callback to have this information as you could use self.inst to refer to that.

 

The reason why these mods are using this to do this is to cache the first instance of these values.  I think this is really bad form to do so, just use GLOBAL.ThePlayer elsewhere in your code and if it may not exist yet then check for that then.  Caching things in mods sets you up to break other mods from functioning properly if they try editing the base thing you cached.

  • Like 2
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...