Jump to content

Recommended Posts

I would like to overwrite the OnActivate function from teleportato_base, but for some reason it is not called and I don't know what I made wrong:
 

local function TeleportatoPostInit(inst)
    print("TeleportatoPostInit") -- is printed
    local _OnActivate = inst.OnActivate
    function OnActivate(inst,doer)
        print("MOD teleportato activated") -- is not printed
        _OnActivate(inst,doer)
    end
    inst.OnActivate = OnActivate
end

AddPrefabPostInit("teleportato_base", TeleportatoPostInit) 

I also tried it with "OnActive" instead of "inst.OnActivate".

The Game function in the teleportato.lua script is called.

Or is it a special case with the teleportato, because it got deleted somewhere, so I have to add a prefablist or simular?


And another question:
Is there an Event that is only called after the world is generated? So not everytime the game loads a savegame?
 

Edited by Serpens

Is it possible to overwrite a function in a prefab file, that is not attached to anything from inst?
Just a local function.

I need to change the "PowerUp" function from teleportato.lua

edit:
I changed the "ItemGet" function instead now. But would be still nice to know, if it is possible to change PowerUp

Edited by Serpens
1 hour ago, Serpens said:

Is it possible to overwrite a function in a prefab file, that is not attached to anything from inst?
Just a local function.

I need to change the "PowerUp" function from teleportato.lua

edit:
I changed the "ItemGet" function instead now. But would be still nice to know, if it is possible to change PowerUp

If you are going to make a total overhaul of the teleportato, it would be a good idea to copypaste the whole teleportato.lua file into your scripts/prefabs folder.

That way, the game will load your file, instead of the original one. And so, you can edit everything in there.

That's how it should be done in your case. The game doesn't even use the teleportato for anything else.

 

Now, you can do what I did for GetRoomsTable().

local function GetUpvalue(func, name)
	local debug = GLOBAL.debug
	local i = 1
	while true do
		local n, v = debug.getupvalue(func, i)
		if not n then
			return nil, nil
		end
		if n == name then
			return v, i
		end
		i = i + 1
	end
end

local function SetUpvalue(func, ind, value)
	local debug = GLOBAL.debug
	debug.setupvalue(func, ind, value)
end

local function HackTeleportato()
	local require = GLOBAL.require
	local teleportato_fn = require("prefabs/teleportato")

	local ItemGet = GetUpvalue(teleportato_fn.fn, "ItemGet")
	local TestForPowerUp = GetUpvalue(ItemGet, "TestForPowerUp")
	local PowerUp, PowerUp_index = GetUpvalue(TestForPowerUp, "PowerUp")

	local old_PowerUp = PowerUp
	local new_PowerUp = function(inst)
		print("Hello")
	end

	SetUpvalue(TestForPowerUp, PowerUp_index, new_PowerUp)
end

HackTeleportato()

Not the best course of action, but it is an option, if you have some variables called outside a function you do have access to.

-- Here, upfunc is upvalue of helloworld

local upfunc = function() end

local function helloworld()
	upfunc()
end
-- Here, it is not
-- You can't reach it with getupvalue

local function helloworld()
	local upfunc = function() end
	upfunc()
end

 

wow O.ô
That is a really nice way to mod functions :)

Just to make sure I understood everything correct:
But this is only possible, if I have the lua file I want to change in my mod folder?
And for changing OnSave and OnLoad I just add:
 

local OnSave, OnSave_index = GetUpvalue(teleportato_fn.fn, "OnSave")
local OnLoad, OnLoad_index = GetUpvalue(teleportato_fn.fn, "OnLoad")
local old_OnSave = OnSave
local new_OnSave = function(inst,data)
	print("Hello")
end
local old_OnLoad = OnLoad
local new_OnLoad = function(inst,data)
	print("Hello")
end
SetUpvalue(teleportato_fn.fn, OnSave_index, new_Save) -- is this correct ?!
SetUpvalue(teleportato_fn.fn, OnLoad_index, new_OnLoad)

in the Hacking function? ... hm no it does not work...
Or should I still use AddPrefabPostInit for those functions?

And for functions that are not returned, I have to start at a function that is returned (that's why you started with "ItemGet" in your example) and then I can "hangle" from function to function ?

Edit:
Btw, is there a diffencre between:
 

local function test()
end

and
 

local test = function() end

 

Edited by Serpens
corrected code
9 hours ago, Serpens said:

But this is only possible, if I have the lua file I want to change in my mod folder?

No.

You have two separate options:

1) Put lua file in your own mod folder. Game will load your file.

2) Put code of debug library to hack into the upvalues of functions.

9 hours ago, Serpens said:

in the Hacking function? ... hm no it does not work...

That doesn't work. Even my PowerUp upvalue hack didn't work either.

This is because of the prefab files loading.

local function GetUpvalue(func, name)
	local debug = GLOBAL.debug
	local i = 1
	while true do
		local n, v = debug.getupvalue(func, i)
		if not n then
			return nil, nil
		end
		if n == name then
			return v, i
		end
		i = i + 1
	end
end

local function SetUpvalue(func, ind, value)
	local debug = GLOBAL.debug
	debug.setupvalue(func, ind, value)
end

local function HackTeleportato()
	local teleportato_fn = GLOBAL.Prefabs["teleportato_base"].fn

	local OnSave, OnSave_index = GetUpvalue(teleportato_fn, "OnSave")
	local OnLoad, OnLoad_index = GetUpvalue(teleportato_fn, "OnLoad")

	local old_OnSave = OnSave
	local new_OnSave = function(inst,data)
		print("potato")
	end

	local old_OnLoad = OnLoad
	local new_OnLoad = function(inst,data)
		print("cranko")
	end

	SetUpvalue(teleportato_fn, OnSave_index, new_OnSave)
	SetUpvalue(teleportato_fn, OnLoad_index, new_OnLoad)
end

AddPrefabPostInit("world", HackTeleportato)

This works.

Doing the hack after the world prefab is initialized seems to do the trick.

9 hours ago, Serpens said:

And for functions that are not returned, I have to start at a function that is returned (that's why you started with "ItemGet" in your example) and then I can "hangle" from function to function ?

Yes. That's how rezecib's upvalue hacker works.

You can see it on his game rebalance, on the steam workshop.

 

As for the rest:

local function test()
end

-- equals

local test
test = function()
end

Read: https://www.lua.org/pil/6.2.html

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