Enemy drop rate and multiple item drops

Started by Jeff, July 13, 2019, 04:26:00 AM

Previous topic - Next topic
July 13, 2019, 04:26:00 AM Last Edit: July 14, 2019, 01:41:10 AM by Kamigousu
Hello! During the development of a project of mine, I found myself in need of an drop rate script that would be able to decide the type and number of item(s) you will get when killing an enemy. I didn't find anything on here ( although I could have overlooked something) so I made one of my own that works well enough for me to share. Hopefully someone will find a use for it. It isn't really pretty or perfect, but it works well.

function enemy:on_dying()
  local x, y, layer = self:get_position()
  local chance = math.random(100)
  if chance >= 95 then  --you have a 5% chance for this to execute.
    bonus_drop = math.random(1,3)

  elseif 75 <= chance and chance < 95 then  --you have a 20% chance for this to execute.
    bonus_drop = math.random(1,2)

  elseif 25 <= chance and chance < 75 then  --you have a 50% chance for this to execute.
    bonus_drop = 1
  else  --you have a 25% chance for this to execute.
    self:set_treasure(nil)
  end
return bonus_drop
end

function enemy:on_dead()
  local map = enemy:get_map()
  local bonus_drop = bonus_drop   --# of extra items dropped.
  local c_treasure, c_variant = self:get_treasure() --common treasure (currency)
  local x, y, layer = self:get_position()


  if bonus_drop ~= nil then
    --the following for loop is the heart of this function. It lays out multiple currency units (or items) depending on a random number generator.
    for i = 1, bonus_drop do
      local irons_prop = {    --properties table for irons.
        ["layer"] = layer,
        ["x"] = x + (math.random(-16, 16)),   --using a random range to mix up the placement of each iron spawned.
        ["y"] = y + (math.random(-16, 16)),   --change the +/-16 to the min and max values for the radius of pixels
        ["treasure_name"] = c_treasure,         --that you would like to allow the item to spawn in. The larger the range
        ["treasure_variant"] = c_variant,         --(and the larger the numbers) the larger the spawn area for the items.
      }
      map:create_pickable(irons_prop)
    end
  end
end


The on_dying section sets up the item chance and determines the drop and the on_death function spawns the dropped items on the map in a pseudo random fashion to make them easy to pick up and see. I think the script is pretty self explanatory but any feedback or criticism is welcome.

edited with corrections as described below.
Build a man a fire, he will be warm for the night. Set a man on fire, he will be warm for the rest of his life.
Other Handles: Kamigousu, Xejk, Mr Sheik

This is an interesting script, thank you for sharing it. :)

You are constantly reseeding the RNG, which will actually make things less "random". You should only set the random seed once when you start a game.

July 14, 2019, 01:36:23 AM #3 Last Edit: July 14, 2019, 01:39:50 AM by Kamigousu
Thank you both for the feedback!

@llamazing -- I edited the script with your recommendation and it is working just fine. ~~Not sure if it really is more random or not, it seems the same.~~ But I like the idea of writing less code so I appreciate the tip.

Edit: it definitely is more random considering I don't have to make a bunch of changes to the seed to get random numbers.
Build a man a fire, he will be warm for the night. Set a man on fire, he will be warm for the rest of his life.
Other Handles: Kamigousu, Xejk, Mr Sheik