Jump to content

[resolved] Change only 1 function from original


rez

Recommended Posts

First of all, I have everything working pretty much, so please don't think I want someone to do the work for me. I'm only a beginner in Lua, so please bear with me if I ask some stupid things or use incorrect terms. I have searched beforehand for a couple of days, but have to ask you anyway.

 

So, I have a mod, that modifies 'media\lua\client\TimedActions\ISScavengeAction.lua' file.

The mod is basically done by a copy of existing with a small change. Example:

ISScavengeAction = ISBaseTimedAction:derive("ISScavengeAction")
[.. snipped ..]
function ISScavengeAction:perform()
    -- x5 increase from 20 actions to 100 per 'fatigue day'
    self.character:getStats():setFatigue(self.character:getStats():getFatigue() + 0.01)
	-- needed to remove from queue / start next.
	ISBaseTimedAction.perform(self)
end

As I understand, if I create and load another mod that has the same file overridden, the mods will be incompatible (because of how modloader works).

Is there a way to do something similar to Java's 'extend' for the function? I presume that's what the 'derive' keyword is for.

What's the best approach here? Remove everything standard except the changed functions and definitions from the mod and use 'derive'? Will everything work? Or is there something else I should know?

Ideally I'd like to go as low as changing only 1 variable in a function so that cross-mod compatibility is the highest.

 

Any advice from experience is welcome!

Thank you.

Edited by rez
resolved, added tags
Link to comment
Share on other sites

Remove everything except the changed functions, ignore derive....this is a function that creates a lua metatable (basically a object class).

To ensure its loaded after other mods so its not overwritten, you'd have to define the function inside a event such as OnGameStart (or similar)

 

Edited by Fenris_Wolf
Link to comment
Share on other sites

I may have understood you incorrectly, but it seems like the file from mod actually overrides the file from the base game as a whole, so leaving only one function in the mod file broke the game. I have removed everything except those changed functions, and that broke everything up to a point where right click no longer even works.

Reverted files back to as they were, everything works again.

Maybe I am missing something, my new file basically contained the ship above (without derive line).

Link to comment
Share on other sites

20 hours ago, Fenris_Wolf said:

It overrides the base file if it has the same name. The function you plan on overriding doesn't have to be in the same file, so name it something else like media\lua\client\MyOverrides.lua

 

Thank you.

I have changed file name, and placed it in './media/lua' directory. The game is fine now, but the overrides don't work.

I remember you saying that I have to load the function from the file after the game is started. Is there some preferred way of doing it?

Is the way like this correct?

Events.OnGameStart.Add(ISScavengeAction:perform());

I am afraid that this will trigger instant increase in a fatigue. While this is a minor thing (+0.01), this design may matter in case of a function that, say, contains code that heals player or repairs an item or does anything similar. Can I just ask Zomboid to reread mod contents after the game is started, without calling a function directly?

Link to comment
Share on other sites

if the override isn't working, it may need a 'require' statement

Theres multiple correct ways of adding the event, technically what you wrote when it hits that line in the code will run the perform function, then add its return value as the function to trigger on game start...

require "TimedActions/ISScavengeAction"

Events.OnGameStart.Add(
    function() -- need a extra wrapper function, triggered on the event
        -- now define our override function
        function ISScavengeAction:perform()
            -- x5 increase from 20 actions to 100 per 'fatigue day'
            self.character:getStats():setFatigue(self.character:getStats():getFatigue() + 0.01)
            -- needed to remove from queue / start next.
            ISBaseTimedAction.perform(self)    
        end
    end
)

 

The above is what the event would need to do, though personally I would probably write it more like:

require "TimedActions/ISScavengeAction"

-- create the function first, since its not being created in a Object:method style, define 'self' as a argument
local override = function(self) 
    -- x5 increase from 20 actions to 100 per 'fatigue day'
    self.character:getStats():setFatigue(self.character:getStats():getFatigue() + 0.01)
	-- needed to remove from queue / start next.
	ISBaseTimedAction.perform(self)    
end

Events.OnGameStart.Add(
    function()
        -- note the use of . instead of :
        ISScavengeAction.perform = override 
    end
)

 

Link to comment
Share on other sites

On 9/27/2017 at 9:37 PM, Fenris_Wolf said:

The above is what the event would need to do, though personally I would probably write it more like:

Thank you! I was able to replace several functions, and I like your way of defining replacements first, then overriding them. In large mods these parts can even be separated to different files. This also works for replacing parts of already defined tables. Will mark this topic as resolved as I had no issues for a day now.

Another thing I have found: modloader does not load files from './media/lua/', they have to be in a subdirectory 'client', 'server' or 'shared'. I wish that was reflected in documentation...

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