Bunnyash Posted October 7, 2018 Share Posted October 7, 2018 Hello, I've been looking for a code to make a character's perk where they are able to have a very small chance of dropping gems from any types of boulders. if any one can help me with this code, it'll be very appreciated !! Link to comment Share on other sites More sharing options...
Ultroman Posted October 7, 2018 Share Posted October 7, 2018 The player doing the mining is never told when or what is dropped by the mine (or whatever is being "worked" for resources). So there's no event to listen for. And if you change the loot tables of the mines, the loot will change for every player. That said, the rocks prefabs all call SetOnWorkCallback on their workable component, setting their onwork callback to the OnWork function in the rocks prefab. You could do something like this: local cached_onwork = nil local function MyOnWork(inst, worker, workleft) inst.components.workable.onwork(inst, worker, workleft) -- Do something to randomly spawn a gem prefab end local MyPostInit cached_onwork = inst.components.workable.onwork inst.components.workable:SetOnWorkCallback(MyOnWork) end AddPrefabPostInit("rock1", MyPostInit) I haven't tested this at all. Think of it mostly as pseudo code. Link to comment Share on other sites More sharing options...
Bunnyash Posted October 7, 2018 Author Share Posted October 7, 2018 42 minutes ago, Ultroman said: The player doing the mining is never told when or what is dropped by the mine (or whatever is being "worked" for resources). So there's no event to listen for. And if you change the loot tables of the mines, the loot will change for every player. That said, the rocks prefabs all call SetOnWorkCallback on their workable component, setting their onwork callback to the OnWork function in the rocks prefab. You could do something like this: local cached_onwork = nil local function MyOnWork(inst, worker, workleft) inst.components.workable.onwork(inst, worker, workleft) -- Do something to randomly spawn a gem prefab end local MyPostInit cached_onwork = inst.components.workable.onwork inst.components.workable:SetOnWorkCallback(MyOnWork) end AddPrefabPostInit("rock1", MyPostInit) I haven't tested this at all. Think of it mostly as pseudo code. Thanks for the comment @Ultroman, may I ask where do I place this? Thanks! Link to comment Share on other sites More sharing options...
Ultroman Posted October 8, 2018 Share Posted October 8, 2018 This code is basically a full mod. Just paste it into your mod anywhere you want. Beware, though, that it is close to working, but I can't guarantee anything, as I haven't actually tested it. There are most likely syntax errors, since I just wrote it from my mind. This code changes all "rock1" prefabs to have extra code run on them. You must remember to check for a certain tag unique to your character mod, at the spot where it says "Do something to randomly spawn a gem prefab". So, check the "worker" player instance for that tag, and ONLY IF it has that tag, you drop a gem randomly. Also, "rock1" is only one of the many different rocks/boulders found in the game. Look in the "rocks" prefab to find the rest. This means you could give the different boulders different drops, by making different versions of the "MyPostInit" and "MyOnWork" functions for each of them. Link to comment Share on other sites More sharing options...
Bunnyash Posted October 8, 2018 Author Share Posted October 8, 2018 3 hours ago, Ultroman said: This code is basically a full mod. Just paste it into your mod anywhere you want. Beware, though, that it is close to working, but I can't guarantee anything, as I haven't actually tested it. There are most likely syntax errors, since I just wrote it from my mind. This code changes all "rock1" prefabs to have extra code run on them. You must remember to check for a certain tag unique to your character mod, at the spot where it says "Do something to randomly spawn a gem prefab". So, check the "worker" player instance for that tag, and ONLY IF it has that tag, you drop a gem randomly. Also, "rock1" is only one of the many different rocks/boulders found in the game. Look in the "rocks" prefab to find the rest. This means you could give the different boulders different drops, by making different versions of the "MyPostInit" and "MyOnWork" functions for each of them. Hi, @Ultroman, I appreciate the help anyway, even if it doesn't work I've added this code into the modmain.LUA file and I've got an error. My mod has one tag which is: ``inst:AddTag("narcissist")`` Have I done something wrong? Link to comment Share on other sites More sharing options...
Ultroman Posted October 8, 2018 Share Posted October 8, 2018 (edited) Change local local MyPostInit to local MyPostInit(inst) Just a reminder, the current code should result in nothing happening If it doesn't crash, and you can mine boulders and they have loot coming out of them, you're ready to add your own custom code. Edited October 8, 2018 by Ultroman Link to comment Share on other sites More sharing options...
Bunnyash Posted October 8, 2018 Author Share Posted October 8, 2018 6 hours ago, Ultroman said: Change local local MyPostInit to local MyPostInit(inst) Just a reminder, the current code should result in nothing happening If it doesn't crash, and you can mine boulders and they have loot coming out of them, you're ready to add your own custom code. Hi @Ultroman, thanks for helping me out, though I'm not sure which file this code goes into, I've placed it into the modmain.LUA and the same error happened, however I placed them into the the characters prefab file and got another error. Is there something I'm doing wrong or does it need to be in a specific place? (This error happened when I placed it into the character prefab file) Link to comment Share on other sites More sharing options...
Ultroman Posted October 8, 2018 Share Posted October 8, 2018 (edited) You we're right the first time. It's supposed to go in modmain.lua. And I missed something obvious when writing it. It's supposed to be: local function MyPostInit(inst) I'm sorry, but I can't code this mod for you. If you want to create this mod, you must look into how to create mods. There are plenty of tutorials, and many, many mods to look at, which show how this is all done. Start by coding something extremely simple. Maybe even something you already have a mod which does. I strongly encourage you to study your way to success. It'll only feel that much sweeter Also, you wouldn't have had to wait for hours for me to reply, with the answer to fix my stupid mistake. Edited October 8, 2018 by Ultroman Link to comment Share on other sites More sharing options...
Bunnyash Posted October 9, 2018 Author Share Posted October 9, 2018 14 hours ago, Ultroman said: You we're right the first time. It's supposed to go in modmain.lua. And I missed something obvious when writing it. It's supposed to be: local function MyPostInit(inst) I'm sorry, but I can't code this mod for you. If you want to create this mod, you must look into how to create mods. There are plenty of tutorials, and many, many mods to look at, which show how this is all done. Start by coding something extremely simple. Maybe even something you already have a mod which does. I strongly encourage you to study your way to success. It'll only feel that much sweeter Also, you wouldn't have had to wait for hours for me to reply, with the answer to fix my stupid mistake. Hi @Ultroman, I have a basic understanding with creating mods, Just not an expert, it was just this one specific code I have been struggling with, I did have a look for any help/existing codes before asking on the forums but couldn't find anything like or even similar. I am also very patient with replies, as you're extremely helpful, and I appreciate your time. The code did work entering the world however it crashes when I mine rocks. Link to comment Share on other sites More sharing options...
Lumina Posted October 9, 2018 Share Posted October 9, 2018 I don't know the cause of the crash, but at the moment your code is doing nothing since there is no function to make some gems spawn or whatever. Possible that your code is doing a loop that makes the stack overflow or something ? Link to comment Share on other sites More sharing options...
Bunnyash Posted October 9, 2018 Author Share Posted October 9, 2018 2 hours ago, Lumina said: I don't know the cause of the crash, but at the moment your code is doing nothing since there is no function to make some gems spawn or whatever. Possible that your code is doing a loop that makes the stack overflow or something ? I'm having a little fiddle with it currently but nothing seems to be working so far, this is a little more advance than I'm used to so I have very little idea of what I'm doing Link to comment Share on other sites More sharing options...
Lumina Posted October 9, 2018 Share Posted October 9, 2018 Yes, it's not the kind of code i'm familiar with either, so i can't really help. Link to comment Share on other sites More sharing options...
Ultroman Posted October 9, 2018 Share Posted October 9, 2018 It's my "pseudo" code at fault again. I knew I should've written it as comments instead of actual code. The MyOnWork of course needs to call the cached on_work function, and NOT onwork on the component. local function MyOnWork(inst, worker, workleft) cached_onwork(inst, worker, workleft) -- Do something to randomly spawn a gem prefab end Link to comment Share on other sites More sharing options...
Bunnyash Posted October 9, 2018 Author Share Posted October 9, 2018 3 hours ago, Ultroman said: It's my "pseudo" code at fault again. I knew I should've written it as comments instead of actual code. The MyOnWork of course needs to call the cached on_work function, and NOT onwork on the component. local function MyOnWork(inst, worker, workleft) cached_onwork(inst, worker, workleft) -- Do something to randomly spawn a gem prefab end Hi @Ultroman, There has been no crashes this time, and mining is fine Thank you! I'm ready to add in the custom drops, do you know how to add that part in? Link to comment Share on other sites More sharing options...
Ultroman Posted October 9, 2018 Share Posted October 9, 2018 Check for the tag on the "worker", which is your player. If that checks out, do some randomness with a certain chance of spawning, and then just do SpawnPrefab() with whatever gem prefab you want to spawn. Link to comment Share on other sites More sharing options...
Bunnyash Posted October 10, 2018 Author Share Posted October 10, 2018 (edited) 1 hour ago, Ultroman said: Check for the tag on the "worker", which is your player. If that checks out, do some randomness with a certain chance of spawning, and then just do SpawnPrefab() with whatever gem prefab you want to spawn. Do you have an example I can use? I'm having a bit of a mess around at the moment. Edited October 10, 2018 by Bunnyash Link to comment Share on other sites More sharing options...
Ultroman Posted October 10, 2018 Share Posted October 10, 2018 (edited) if worker:HasTag("narcissist") then local rand = math.random() if rand <= 0.1 then SpawnPrefab("bluegem").Transform:SetPosition(inst:GetPosition():Get()) end end Gives a 10% chance of dropping a blue gem. It's all stolen from the rocks prefab. math.random() gives a random number between 0.0 and 1.0. Remember, the code I provided only affects the "rock1" prefab. You'll need to affect the other types of rocks you want, as well. Edited October 10, 2018 by Ultroman Link to comment Share on other sites More sharing options...
Bunnyash Posted October 10, 2018 Author Share Posted October 10, 2018 Everything seems to work fine, I mine a few rocks until it suddenly crashes which I assume is trying to do the random blue gem drop? (screen shot of crash doesn't work for some reason O_O I had a look through the client log) LUA ERROR stack traceback: ../mods/Gemini/modmain.lua:217 in (field) onwork (Lua) <211-221> inst = 115998 - rock1 (valid:false) worker = 114639 - gemini (valid:true) workleft = 0 rand = 0.042817468794824 scripts/components/workable.lua:121 in (upvalue) old (Lua) <112-132> self = onwork = function - ../mods/Gemini/modmain.lua:211 lastworktime = 26.166668031365 inst = 115998 - rock1 (valid:false) savestate = false Link to comment Share on other sites More sharing options...
Ultroman Posted October 10, 2018 Share Posted October 10, 2018 Probably just needs to be GLOBAL.SpawnPrefab("bluegem").Transform:SetPosition(inst:GetPosition():Get()) Link to comment Share on other sites More sharing options...
Bunnyash Posted October 10, 2018 Author Share Posted October 10, 2018 8 minutes ago, Ultroman said: Probably just needs to be GLOBAL.SpawnPrefab("bluegem").Transform:SetPosition(inst:GetPosition():Get()) Perfect! It works!! thank you so much for all your time, I really appreciate it do I just copy and paste this code if I wanted other random drops like redgems, purplegems etc? Link to comment Share on other sites More sharing options...
Ultroman Posted October 10, 2018 Share Posted October 10, 2018 You're welcome To answer your question, well, not exactly. If you understand what's happening in the code right now, you should be able to do whatever you want with a few if and elseif statements. How you do that, depends on several factors. Should a rock only be able to drop one gem at a time? Do they all have the same droprate? Do you want different rock prefabs to drop different gems? Many things could influence how you should go about this. Link to comment Share on other sites More sharing options...
Bunnyash Posted October 10, 2018 Author Share Posted October 10, 2018 1 minute ago, Ultroman said: You're welcome To answer your question, well, not exactly. If you understand what's happening in the code right now, you should be able to do whatever you want with a few if and elseif statements. How you do that, depends on several factors. Should a rock only be able to drop one gem at a time? Do they all have the same droprate? Do you want different rock prefabs to drop different gems? Many things could influence how you should go about this. Yes, every rock can only drop one gem each, it can be any one of the 6 gems. Red and blue being the most common while the others are less likely to drop. Link to comment Share on other sites More sharing options...
Ultroman Posted October 10, 2018 Share Posted October 10, 2018 (edited) What I meant was, whether the rocks should only be able to drop one gem per whack with the pickaxe, which is easy to accomplish. If you want to limit all rocks to only be able to drop 1 gem, no matter how many times you whack at them, you'll need to store a variable on every rock prefab, saying whether it has already dropped one, and it'll be even more complicated if you want to ensure that they all drop a gem. If you're going with the first option, which I would do if I were you, it's pretty easy. Just do something like this: local rand = math.random() -- This gives 10% chance to drop a gem if rand <= 0.1 then -- New random value, used to determine which gem. We're reusing the previous variable, since its value won't be used anymore. rand = math.random() -- Now we MUST drop a gem. -- This gives 30% chance to drop a blue gem if rand <= 0.3 then SpawnPrefab("bluegem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 30% chance to drop a red gem elseif rand <= 0.6 then SpawnPrefab("redgem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 10% chance to drop a purple gem elseif rand <= 0.7 then SpawnPrefab("purplegem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 10% chance to drop a yellow gem elseif rand <= 0.8 then SpawnPrefab("yellowgem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 10% chance to drop a green gem elseif rand <= 0.9 then SpawnPrefab("greengem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives the last 10% chance to drop an orange gem else SpawnPrefab("orangegem").Transform:SetPosition(inst:GetPosition():Get()) end end What I've done here, is to separate the chance of dropping a gem, from the chance of dropping each color gem. I've simply made another random number, and divided the percentages over the different gem types. This is a very simplified way to do it, and it only works because I've divided all the possible values of the random number between the different types of gems. If you want to change any of the droprates, you must change the others to match the full spectrum of possible values. If you want different droprates, you'll probably have an easier time structuring it differently. Edited October 10, 2018 by Ultroman Link to comment Share on other sites More sharing options...
Bunnyash Posted October 10, 2018 Author Share Posted October 10, 2018 20 minutes ago, Ultroman said: What I meant was, whether the rocks should only be able to drop one gem per whack with the pickaxe, which is easy to accomplish. If you want to limit all rocks to only be able to drop 1 gem, no matter how many times you whack at them, you'll need to store a variable on every rock prefab, saying whether it has already dropped one, and it'll be even more complicated if you want to ensure that they all drop a gem. If you're going with the first option, which I would do if I were you, it's pretty easy. Just do something like this: local rand = math.random() -- This gives 10% chance to drop a gem if rand <= 0.1 then -- New random value, used to determine which gem. We're reusing the previous variable, since its value won't be used anymore. rand = math.random() -- Now we MUST drop a gem. -- This gives 30% chance to drop a blue gem if rand <= 0.3 then SpawnPrefab("bluegem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 30% chance to drop a red gem elseif rand <= 0.6 then SpawnPrefab("redgem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 10% chance to drop a purple gem elseif rand <= 0.7 then SpawnPrefab("purplegem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 10% chance to drop a yellow gem elseif rand <= 0.8 then SpawnPrefab("yellowgem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives 10% chance to drop a green gem elseif rand <= 0.9 then SpawnPrefab("greengem").Transform:SetPosition(inst:GetPosition():Get()) -- This gives the last 10% chance to drop an orange gem else SpawnPrefab("orangegem").Transform:SetPosition(inst:GetPosition():Get()) end end What I've done here, is to separate the chance of dropping a gem, from the chance of dropping each color gem. I've simply made another random number, and divided the percentages over the different gem types. This is a very simplified way to do it, and it only works because I've divided all the possible values of the random number between the different types of gems. If you want to change any of the droprates, you must change the others to match the full spectrum of possible values. If you want different droprates, you'll probably have an easier time structuring it differently. I've added it, again everything works fine until it tries to spawn the gem, it crashes. Link to comment Share on other sites More sharing options...
Ultroman Posted October 10, 2018 Share Posted October 10, 2018 You're missing an "end" at the end. If you fixed the indentation it'd be staring you right in the face. 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