Jump to content

Recommended Posts

I've been working on a character mod recently, and although I actually went into it not knowing Lua at all (but having learned other programming languages), I've learned quite a lot just from examining vanilla code. I'm still not exactly adept at coding for it yet, though. Of course, the reason I'm even posting at all is because I've got a question about it. 

What I'm trying to do right now is have a tool which changes drastically when hallucinations start to attack. The first step in doing this is to actually get the trigger to work; that is, it needs to check if the player is insane every time sanity goes up or down, and if they're insane, the item needs to change. However, any other prefab doesn't ever seem to call a particular part of another prefab, which is vital to known how to do because I must reference the tool in my character's prefab file. Here is the current code I've got to put in my character file:

Spoiler

    local function Change(inst)
        if inst.components.sanity:IsCrazy() then
            --[[(What do I put here?)]]:ChangeForm()
        else 
            --[[(What do I put here?)]]:ChangeBack()
        end
    end

    inst:ListenForEvent("sanitydelta", Change)

I've tried so many things to try to get the game to understand that I'm referencing my item's prefab file, but all I seem to get is errors. 

Does anyone know how I can do this? If any more information or clarification is needed, I'll be happy to provide it. Thanks in advance.

Do you have to reference the tool in the character's prefab file? Maybe you could just check the character's sanity from the item itself?

Assuming that you have to create the item first, maybe (And I'm just guessing here. I'm also new to Lua) you could keep a reference to the item when it is created. Thus you'll be able to write

myprefab.components.mycomponent:ChangeForm()

 

19 minutes ago, FlawlessHair said:

Do you have to reference the tool in the character's prefab file? Maybe you could just check the character's sanity from the item itself?

Assuming that you have to create the item first, maybe (And I'm just guessing here. I'm also new to Lua) you could keep a reference to the item when it is created. Thus you'll be able to write


myprefab.components.mycomponent:ChangeForm()

 

Yeah, I've tried to check the sanity from the item itself, but the ListenForEvent line seems to be the problem there (perhaps because "sanitydelta" is trying to check if the item's sanity has changed rather than the owner's - which of course won't work because items have no sanity). I'm also not quite sure what you mean by keeping a reference to the item when it is created, could you explain how I might be able to do that? 

Thanks for the response.

local function Change(inst)
	if inst.components.sanity:IsCrazy() then
		local x,y,z = GetPlayer().Transform:GetWorldPosition()
		local ents = TheSim:FindEntities(x,y,z, 9001)
		for k,v in pairs(ents) do
			if v.prefab == "itemprefabname" then
				v:ChangeForm()
			end
		end
	else
		local x,y,z = GetPlayer().Transform:GetWorldPosition()
		local ents = TheSim:FindEntities(x,y,z, 9001)
		for k,v in pairs(ents) do
			if v.prefab == "itemprefabname" then
				v:ChangeBack()
			end
		end
	end
end

inst:ListenForEvent("sanitydelta", Change)

The functions 'ChangeForm' and 'ChangeBack' should be defined like this (in your item's prefab file):

inst.ChangeForm = function(inst)
	--Do stuff
end

inst.ChangeBack = function(inst)
	--Do stuff
end

 

 

However, this will not persist. The tool will likely reset when you reload the save. It would be better to make a custom component for this. To do so, just make a file in 'scripts/components' (Use vanilla code for examples). You can then check for the component in the loop, like so:

if v.components.yourcomponentname then
	--Do Stuff
end

 

Ahh, thank you very much, the code seems to be triggering properly, with a little working! There is another problem, however. Don't Starve now lags extremely badly after the opening cutscene finishes. It seems the problem is to do with these lines:

		local x,y,z = GetPlayer().Transform:GetWorldPosition()
		local ents = TheSim:FindEntities(x,y,z, 9001)

Thanks for the help so far!

TheSim:FindEntities is a fairly expensive function to use frequently, and should be avoided if at all possible.

 

When the player goes fully nuts and the shadows start hitting, the event "goinsane" is pushed; likewise the inverse of going sane has "gosane" event pushed.

Using these as the trigger for switching will reduce the number of calls to TheSim:FindEntities since it only applies on sanity state changes rather than any delta sanity.

 

Further, since this is just Don't Starve with only one player to consider then you know that when the event is fired the player character is insane.

So you can register this event listener in the initialization of whatever prefab you're using:

(Taken from) dont_starve/data/scripts/prefabs/nightmarerock.lua:~227

local thePlayer = GetPlayer()
thePlayer:ListenForEvent("goinsane",
    function()
        inst:ChangeForm()
    end
)
thePlayer:ListenForEvent("gosane",
    function()
        inst:ChangeBack()
    end
)

The 'goinsane' event fires on post world init if the player is insane, so it'll automatically handle the insane state of the tool you're making if you make the assumption that the default load state is the 'sane' state.

 

Moreover, you can essentially copy how the rabbit works with its beardling behaviour.

Instead of registering an event listener it polls the player's sanity state periodically.

I assume this is to lower the load of the game logic when the player changes to insane by offloading the switching of all the rabbits over different time slots than at once.

You might consider this if you plan on having many items.

Edited by CarlZalph
Code syntax highlight removal.

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