Well-met Posted April 9, 2019 Share Posted April 9, 2019 hey When my custom char dies, I'd like to modify the properties of the following skeleton spawn. Such as Transform:Scale(0.9,0.9,0.9) This one seems tricky because player skeletons are included in "skeleton.lua" which is also the map spawns too. I don't wanna screw up other char skeletons either. Am I to mess with the "death" stategraph or skeleton.lua? Is it a AddComponentPostInit or AddStategraphPostInit? Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 (edited) As you can see in player_common_extensions.lua the skeleton is created, gets a description and is then left to its own devices. There are no references to be had to the skeleton after the functions (OnMakePlayerGhost and RemoveDeadPlayer) have returned. Looking at the skeleton-prefab code and how it's being called, there is an easy solution. Extend the function SetSkeletonDescription on the skeleton prefab, where you call the original function first, and then say if inst.char == "CHAR_NAME" then inst.Transform:Scale(0.9,0.9,0.9) Be aware, though, that only player skeletons have this function, so you should change the prefab "skeleton_player" but not "skeleton". Edited April 10, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 --not going to use the spear skeleton until anim to take spear is made interesting. AddPrefabPostInit("skeleton", function(inst) local old = SetSkeletonDescription(inst, char, playername, cause, pkname) SetSkeletonDescription = function(inst, char, playername, cause, pkname) if inst.prefab == "melium" then skeleton_player.Transform:Scale(0.9,0.9,0.9) end return old(inst, char, playername, cause, pkname) end end) tried this. doesn't work? Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 (edited) Your code: AddPrefabPostInit("skeleton", function(inst) local old = SetSkeletonDescription(inst, char, playername, cause, pkname) SetSkeletonDescription = function(inst, char, playername, cause, pkname) if inst.prefab == "melium" then skeleton_player.Transform:Scale(0.9,0.9,0.9) end return old(inst, char, playername, cause, pkname) end end) There are a number of problems here. Just for the sake of teaching I'll list them all here: Line 1: As I said, "skeleton_player" prefab, not "skeleton". Only "skeleton_player" has the function we want to change, and also we don't care about the other normal skeletons. Line 2: You shouldn't include the parenthesis when you reference a function. Only when you declare it or call it. Line 2: You need to reference the function on the instance. Just writing the function won't do anything. Line 3: You need to reference the function on the instance. What you did there, was simply declaring a function, without defining the scope e.g. putting "local" before it. If you want to override a function, you need to provide the instance/object on which you want to change the function. Line 5: There is no variable anywhere named "skeleton_player". You should be making changes to the inst inside the function. Not sure if this is actually needed, but I try to avoid confusion by making sure that no variables and parameters within the same function are named the same, so I changed it to skeleton_inst, so I could parrot the original parameter names of the function we're overriding. The names do not really matter, except to us humans. AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst:SetSkeletonDescription skeleton_inst:SetSkeletonDescription = function(inst, char, playername, cause, pkname) if inst.prefab == "melium" then inst.Transform:Scale(0.9,0.9,0.9) end return old(inst, char, playername, cause, pkname) end end) -- And if that doesn't work, because I've forgotten how to properly override functions, try this: AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst.SetSkeletonDescription skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) if inst.prefab == "melium" then inst.Transform:Scale(0.9,0.9,0.9) end return old(self, inst, char, playername, cause, pkname) end end) Edited April 10, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 @Ultroman 1st crashes 2nd doesn't work See here the thing is that "skeleton_player" doesn't seem to exist? I can't find it in scripts/prefabs. skeleton_player.lua is unfindable Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Prefab LUAs can have more than one prefab in them. Look at the bottom of the LUA files. E.g. staff.lua has all the staves in the game, and hats.lua has all the hats. Crash log, please. I can't test it, since I don't have the mod. Try this: AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst.SetSkeletonDescription skeleton_inst:SetSkeletonDescription = function(inst, char, playername, cause, pkname) if inst.prefab == "melium" then inst.Transform:Scale(0.9,0.9,0.9) end return old(self, inst, char, playername, cause, pkname) end end) Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 (edited) @Ultroman where do I find crash logs at? To be clear the second block doesn't crash. It just doesn't do the desired effect Edited April 10, 2019 by Hell-met Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 (edited) Yeah, but i want the first one to work xD It's a better way. I think the third option I posted should work. Uh oh, someone didn't make it to the "debugging" section of my newcomer post It tells you about the crash logs and how to debug your code by leveraging them. It also tells you a lot of other things. * cough * LUA Crash Course * cough * Edited April 10, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 ya Documents\Klei\DoNotStarveTogether/client_log.txt. Had a brain fart I shall try your third idea Third block crash : [string "../mods/melium/modmain.lua"]:200: function arguments expected near '=' Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Which line is line 200? Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 Sorry, skeleton_inst:SetSkeletonDescription = function(inst, char, playername, cause, pkname) Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Probably the third one, right? skeleton_inst:SetSkeletonDescription = function(inst, char, playername, cause, pkname) In that case, use the second version. Try setting the scale to 0.5, 0.5, 0.5 Maybe it's hard to see or something. HA! Got it! AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst.SetSkeletonDescription skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) if char == "melium" then self.inst.Transform:Scale(0.9,0.9,0.9) end return old(self, inst, char, playername, cause, pkname) end end) First thing, inst.prefab is already passed in as the parameter "char". Not the problem, though, just looks better Problem was we were scaling inst...but inst is the player, not the skeleton! The skeleton is only available within the function as self. Not sure if it should be self.inst.Transform:Scale(0.9,0.9,0.9) or self.Transform:Scale(0.9,0.9,0.9) Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 (edited) -testing- I am sorry but it just won't work . if an experienced user like you can't figure it out, how is a newbie like me even supposed to stand a chance at learning this? Edited April 10, 2019 by Hell-met Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Try, try, try again. It's the only way to learn anything. Gimme a sec, I'll test it myself. Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 (edited) This is SUPER weird...this is supposed to work AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst.SetSkeletonDescription skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) if char == "melium" then self.Transform:Scale(0.5,0.5,0.5) end return old(self, inst, char, playername, cause, pkname) end end) But it says that the Scale function doesn't exists on the transform...I don't get it. The Transform is there... ... ... it's SetScale...not Scale * facepalm * This works. I added that it should only do this on the server. if GLOBAL.TheNet and GLOBAL.TheNet:GetIsServer() then AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst.SetSkeletonDescription skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) if char == "melium" then self.Transform:SetScale(0.5,0.5,0.5) end return old(self, inst, char, playername, cause, pkname) end end) end Edited April 10, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 (edited) @Ultroman Have you actually witnessed it working? Because for me it still doesn't. I understand this may be getting frustrating to you so I'll just ditch the idea Edited April 10, 2019 by Hell-met Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 It's working for me. 100%. Let me see your modmain The only difference is I didn't restrict it with a char name. I just made all player skeletons shrink to half the size. I have Try adding some print-statements to the code e.g. if GLOBAL.TheNet and GLOBAL.TheNet:GetIsServer() then AddPrefabPostInit("skeleton_player", function(skeleton_inst) print("BOOP 1") local old = skeleton_inst.SetSkeletonDescription skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) print("BOOP 2") print("char: "..char) if char == "melium" then print("BOOP 3") self.Transform:SetScale(0.5,0.5,0.5) end return old(self, inst, char, playername, cause, pkname) end end) end Does your server have caves on? If so, the problem might be that I added the server check. I just thought it only had to happen on the server. Try this next code first, then. The only difference is that I removed the outer if-statement. AddPrefabPostInit("skeleton_player", function(skeleton_inst) local old = skeleton_inst.SetSkeletonDescription skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) if char == "melium" then self.Transform:SetScale(0.5,0.5,0.5) end return old(self, inst, char, playername, cause, pkname) end end) If the problem is with the server code, then the first code (with the server check AND the print-statements) should NOT print BOOP 1 in your client log. No matter what, it's very useful to put in some print-statements. Then you can be 100% sure about what is happening and what isn't. Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 I don't use caves since it makes it so I become a client on my own server and creates all sorts of annoyingness. At any rate, I've found out "char" references to my name and not my character. That must be it? Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Yep. And it shouldn't. char should be "melium" and your name should be in playername. That means that all the parameters are shifted one to the left, which would mean that we aren't getting self, but we do... EDIT: I'm an idiot. Remove inst from the list of parameters from both these lines: skeleton_inst.SetSkeletonDescription = function(self, inst, char, playername, cause, pkname) return old(self, inst, char, playername, cause, pkname) Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 (edited) that did it! I thank you once more and I'm gonna use that block as a base or reference for future stuff. PS - is it possible to do "char:HasTag("tag")"? It didn't like that. Edited April 10, 2019 by Hell-met Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Nope. The "char" parameter is a string, m8. It's the character prefab name of the player who died. Inside this function we have no way of getting the player. We only have access to the skeleton, and a bunch of information about the player it belongs to. I don't know if it's possible to get a player using their player name, which we have in the parameter "playerName", though. Maybe. Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 (edited) okay well I'd rather have the modified skeleton only happen if the player has a specific tag. I'll try stuff. got it with GLOBAL.ThePlayer Edited April 10, 2019 by Hell-met Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Yeah, but since it's only running the code on the server, I think it'll always read the server's player, and not the player who actually died. Link to comment Share on other sites More sharing options...
Well-met Posted April 10, 2019 Author Share Posted April 10, 2019 5 minutes ago, Ultroman said: Yeah, but since it's only running the code on the server, I think it'll always read the server's player, and not the player who actually died. So that means it won't work for my friend using the same char even if they have the tag? Ah well. it's this or nothing. Link to comment Share on other sites More sharing options...
Ultroman Posted April 10, 2019 Share Posted April 10, 2019 Not really. You can get this, too. Look here. All these commands are available to you, as well. You have the playerName inside the function. You also have access to AllPlayers, which is a list of all players. Loop over AllPlayers and check their names. Link to comment 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