Jump to content

{Character perks} mining gems


Recommended Posts

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

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

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

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

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?

404 error.png

Link to comment
Share on other sites

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 by Ultroman
Link to comment
Share on other sites

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)

 

404 error.png

Link to comment
Share on other sites

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 by Ultroman
Link to comment
Share on other sites

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.

404 error.png

Link to comment
Share on other sites

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

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

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

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 :D 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

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 by Bunnyash
Link to comment
Share on other sites

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 by Ultroman
Link to comment
Share on other sites

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

404 error.png

Link to comment
Share on other sites

8 minutes ago, Ultroman said:

Probably just needs to be


GLOBAL.SpawnPrefab("bluegem").Transform:SetPosition(inst:GetPosition():Get())

 

Perfect! It works!! :D 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

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

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

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 by Ultroman
Link to comment
Share on other sites

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.

404 error.png

Link to comment
Share on other sites

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
 Share

×
  • Create New...