Jump to content

Token based drop system for custom survivor


Recommended Posts

Hey there!

Soo, I've been thinking about a unique drop system for my custom character, but first, I would like to discuss and collect feedback about how should I actually approach this, as I tend to overcomplicate things by myself.

The system:

- The character would be able to craft tokens that she could carry in her inventory (I can make this)

- She would be able to make mobs randomly drop gold nuggets upon hitting them

- For each token she carries, she should have a higher chance to make the mobs drops gold (not more gold, just increase the chance of dropping one)

- On the other hand, she can lose (completely disappear from her inventory) these tokens if she takes physical damage

I'm not expecting fully polished codings form you (though, if you have some of them, I don't mind them either), I'm absolutely grateful for tips or for examples that I could use as reference.

Thanks in advance everyone!

Have a great day!

Link to comment
Share on other sites

local drop_rate_chance = 0.5 --lower equals higher chance drop
local drop_rate_max_chance = 10 --how many items unitll it reaches a 100% rate
local drop_rate_item = 'insert_prefab_which_increases_drop_rate'
local drop_item = 'Item_which_will_be_dropped'

--reused from wortox code line 175
local function GetStackSize(item)
    return item.components.stackable ~= nil and item.components.stackable:StackSize() or 1
end

--reused from wortox code line 183-189
local function AmountOfItem(inst)
    local item = inst.components.inventory:FindItems(function(i)return i.prefab== drop_rate_item)
    --will be explained in a spoiler below
    local count = 0
    for i, v in ipairs(item) do
        count = count + GetStackSize(v)
    end
    return count
end

inst:ListenForEvent("onattackother", function(inst, data) 
--data.target = target you attacked, data.weapon = weapon you hit them with, data.projectile = object that you hit them with , data.stimuli = thing that you hit
--written on line 882 in scripts/components/combat

if (math.clamp(math.random()  + (AmountOfItem(inst) / drop_rate_max_chance) , 0,1)) > drop_rate_chance then 
   SpawnPrefab(drop_item).Transform:SetPosition(data.target.Transform:GetWorldPosition())
    end
end)

This code should work but it's untested i'll explain the method in the spoilers below
if you'd like to change any code just ask but i'll only explain how you should do it

Counting The amount of items

Spoiler

local function GetStackSize(item)
    return item.components.stackable ~= nil and item.components.stackable:StackSize() or 1
end

It will first check if the components stackable is present to know if there could be more than 1 item
"item.components.stackable ~= nil"

If it does it will activate the function inside the component which counts the total in the stack
"item.components.stackable:StackSize()"

if the item.components stackable isn't there than it will bring it's value to 1 by default since it can be no more than 1
"or 1"

 


local function AmountOfItem(inst)
    local item = inst.components.inventory:FindItems(function(i)return i.prefab== drop_rate_item)
    --will be explained in a spoiler below
    local count = 0
    for i, v in ipairs(item) do
        count = count + GetStackSize(v)
    end
    return count
end

it will get a list of the items in the inventory which match the criteria given in this case it's
if the item is the same prefab given this is written in an function
below is the same code but written in a more readable way


function (items)
  return items.prefab == item
end

next it will count though each item in the list and check how many are in each element of the list
image.png.d48171e0f87f0b5222fafb31ff19b293.png
here we see what would be in a list but certain items could have multiple so it uses the code before to check how many are in the element
which is later added onto the varaible count this is done with every element in the list
"count = count + GetStackSize"

this will than return the full value of every found item in the player's inventory
"return count"

Calculating the chance of drop on hit
 

Spoiler

inst:ListenForEvent("onattackother", function(inst, data) 
--data.target = target you attacked, data.weapon = weapon you hit them with, data.projectile = object that you hit them with , data.stimuli = thing that you hit
--written on line 882 in scripts/components/combat

if (math.clamp(math.random()  + (AmountOfItem(inst) / drop_rate_max_chance) , 0,1)) > drop_rate_chance then 
   SpawnPrefab(drop_item).Transform:SetPosition(data.target.Transform:GetWorldPosition())
    end
end)

By using the event "onattackother" it triggers everytime you attack someone and give the data.target to get the location of the drop after you hit them

"inst:ListenForEvent("onattackother",function(paremeters))

The huge if statement is simply 4 pieces of math being run in a single line which could also be read as
 


local chance = math.random() --base random chance
local amount_of_items_found = AmountOfitem(inst)
local percentage =  amount_of_items_found / maxiumum amount of items that make a diffrence

local chance = chance + percentage 
local chance = math.clamp(chance, miniumum value or 0, maxiumim value or 1)
-- to make sure that it doesn't go over a reasonable value however it's not neccary now that i look at it

if chance > chance to get item then
   --run code
end


if the code goes through than it'll spawn the single item on the mob
 


 SpawnPrefab(drop_item).Transform:SetPosition(data.target.Transform:GetWorldPosition())
--SpawnPrefab to drop item
--.Transform:SetPosition() to move the prefab to desired area
--data.target.Transform:GetWorldPosition() to get the position of the target


 

 

kinda burnt out so reply if you're suck and i'll replay tommroow 

  • Thanks 1
Link to comment
Share on other sites

Uhm don't tell anyone but do you see that mini function in the brackets can you add a little end to end it off :]

Probably my woopsie.

On 9/3/2021 at 5:50 PM, Thomas Die said:

local item = inst.components.inventory:FindItems(function(i)return i.prefab== drop_rate_item)

This thing

  • Like 1
Link to comment
Share on other sites

33 minutes ago, Thomas Die said:

Uhm don't tell anyone but do you see that mini function in the brackets can you add a little end to end it off :]

Probably my woopsie.

This thing

That was correct of you, this function wants a function as an argument.

But you still need to change it to:

local item = inst.components.inventory:FindItems(function(i)return i.prefab== drop_rate_item end)

as it wants the function to end.

Line 57/58 there is an end too much, just delete one of it ;)

Edited by Monti18
  • Like 3
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...