Scottnov Posted March 17, 2016 Share Posted March 17, 2016 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. Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/ Share on other sites More sharing options...
FlawlessHair Posted March 17, 2016 Share Posted March 17, 2016 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() Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/#findComment-734917 Share on other sites More sharing options...
Scottnov Posted March 17, 2016 Author Share Posted March 17, 2016 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. Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/#findComment-734922 Share on other sites More sharing options...
Arkathorn Posted March 17, 2016 Share Posted March 17, 2016 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 Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/#findComment-734961 Share on other sites More sharing options...
Scottnov Posted March 18, 2016 Author Share Posted March 18, 2016 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! Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/#findComment-735448 Share on other sites More sharing options...
CarlZalph Posted March 18, 2016 Share Posted March 18, 2016 (edited) 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 March 18, 2016 by CarlZalph Code syntax highlight removal. Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/#findComment-735458 Share on other sites More sharing options...
Scottnov Posted March 19, 2016 Author Share Posted March 19, 2016 Aha! Thank you very much. Now that the trigger works properly, I've already begun work on adding the effects of the form change. Thanks again to everyone here for the help. Link to comment https://forums.kleientertainment.com/forums/topic/65492-referring-to-a-prefab-file-within-another-prefab-file/#findComment-735791 Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now