• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Proper Wild Item Drops

  • 16
    Posts
    4
    Years
    • Seen May 3, 2022
    This is a Proper Wild Item Drop script. I based my script on the work of Cilerba ((broken link removed))
    I'd also like to say thank you to ThatWelshOne_, Vendily and Golisopod User for helping with parts of the script and pointing me in the right direction, respectively!

    Essentially, what this does is read the pokemon.txt PBS file and generate a list of items that can be "dropped" by a wild pokemon at the end of a battle. These items are completely separate from Wild Hold Items (so a wild pokemon can both hold an item and drop completely different items at the same time if you so wish). The way the script is set up now, a pokemon will have up to 3 different drop items defined. At the end of a battle, a random number between 1-3 will be set for each item and that number of items will be "dropped" and added to the player's bag. There is a 50 percent chance to drop the common item, 20 to drop the uncommon item, and 5 to drop the rare item. These can be edited in the portion of the script "chances". There are also 2 other arrays of chances that the script will use instead, if the first pokemon in your party has the Compound Eyes ability, or the Super Luck ability, respectively.

    Set up is very simple.

    First, you're gonna want to define wildDropItems. In PokeBattle_Pokemon, find the section def wildHoldItems, and underneath it, paste this bit of code:

    Code:
    # Returns the items this species can drop in the wild.
      def wildDropItems
        ret = []
        ret.push(pbGetSpeciesData(@species,formSimple,SpeciesWildDropCommon))
        ret.push(pbGetSpeciesData(@species,formSimple,SpeciesWildDropUncommon))
        ret.push(pbGetSpeciesData(@species,formSimple,SpeciesWildDropRare))
        return ret
      end

    In Compiler_PBS find

    Code:
    # If any held item is defined for this form, clear default data for all
          # three held items.
          if (contents["WildItemCommon"] && contents["WildItemCommon"]!="") ||
             (contents["WildItemUncommon"] && contents["WildItemUncommon"]!="") ||
             (contents["WildItemRare"] && contents["WildItemRare"]!="")
            speciesData[speciesID][SpeciesWildItemCommon]   = nil
            speciesData[speciesID][SpeciesWildItemUncommon] = nil
            speciesData[speciesID][SpeciesWildItemRare]     = nil
          end

    and paste this directly below it:

    Code:
    if (contents["WildDropCommon"] && contents["WildDropCommon"]!="") ||
             (contents["WildDropUncommon"] && contents["WildDropUncommon"]!="") ||
             (contents["WildDropRare"] && contents["WildDropRare"]!="")
            speciesData[speciesID][SpeciesWildDropCommon]   = nil
            speciesData[speciesID][SpeciesWildDropUncommon] = nil
            speciesData[speciesID][SpeciesWildDropRare]     = nil
          end

    Now to add the proper fields to the PBS file:

    in Misc_Data, scroll down to the section labeled Pokemon Data and add these to the list of things there:
    SpeciesWildDropCommon = 28
    SpeciesWildDropUncommon = 29
    SpeciesWildDropRare = 30
    (Make sure the numbers you use here are unused in your file, my next available ones were 28-30 but if you're already using those, just use the next available numbers)

    then, just below, in def self.optionalValues(compilingForms = false)
    find

    Code:
     "WildItemCommon"      => [SpeciesWildItemCommon,   "e", :PBItems],
          "WildItemUncommon"    => [SpeciesWildItemUncommon, "e", :PBItems],
          "WildItemRare"        => [SpeciesWildItemRare,     "e", :PBItems],

    and directly underneath it, paste:

    Code:
    "WildDropCommon"      => [SpeciesWildDropCommon,   "e", :PBItems],
          "WildDropUncommon"    => [SpeciesWildDropUncommon, "e", :PBItems],
          "WildDropRare"        => [SpeciesWildDropRare,     "e", :PBItems],

    the next step is the actual script, put this anywhere above "Main". I recommend directly above, as that is where I have it placed.

    Code:
    class PokeBattle_Scene
     
      def pbWildBattleSuccess
        @battle.battlers.each {|b|
        next if !b
        next if !b.opposes?
        pkmn = b.pokemon
        next if !pkmn
        if pkmn.wildDropItems.inject(0){|sum,x| sum + x } != 0
          # Get array of item IDs of held items
          wildDrop = pkmn.wildDropItems
          firstqty = rand(3)+1
          secondqty = rand(3)+1
          thirdqty = rand(3)+1
          firstPkmn = $Trainer.firstPokemon
          chances = [50,20,5]
          chances = [60,40,15] if firstPkmn && isConst?(firstPkmn.ability,PBAbilities,:COMPOUNDEYES)
          chances = [50,50,50] if firstPkmn && isConst?(firstPkmn.ability,PBAbilities,:SUPERLUCK)
          droprnd = rand(100)
          # This bit is tricky because a Pokémon might not have all their items defined
          # Plus, wildHold would need to be a single item
          # As it stands, it's an array, so the methods below don't work unedited
          # I've subsetted the array to the second element for testing purposes for now
          if (wildDrop[0]==wildDrop[1] && wildDrop[1]==wildDrop[2]) || droprnd<chances[0]
            if $PokemonBag.pbStoreItem(wildDrop[0],firstqty)
              itemname = PBItems.getName(wildDrop[0])
              pocket = pbGetPocket(wildDrop[0])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,firstqty))
            end
          end
          if droprnd<chances[1]
            if $PokemonBag.pbStoreItem(wildDrop[1],secondqty)
              itemname = PBItems.getName(wildDrop[1])
              pocket = pbGetPocket(wildDrop[1])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,secondqty))
            end
          end
          if droprnd<chances[2]
            if $PokemonBag.pbStoreItem(wildDrop[2],thirdqty)
              itemname = PBItems.getName(wildDrop[2])
              pocket = pbGetPocket(wildDrop[2])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,thirdqty))
            end
          end
        end
    	}
      @battleEnd = true
      pbBGMPlay(pbGetWildVictoryME)  
      end
    end

    The very last step is adding the fields WildDropCommon/WildDropUncommon/WildDropRare to the PBS file for whichever pokemon you want and defining the item that you want to be dropped. This is an optional field, so you don't have to define one at all, and I personally recommend putting those fields underneath the POKEDEX entry (or WIldItemCommon/WildItemUncommon/WildItemRare fields, if those are defined. I'm not sure if the position is important, but why chance it?)

    If you have questions or any bugs/issues to report, lemme know and I'll try my best to help. I'm still learning to code myself! Also, I've only tested this script in wild single battles, there may be some issues with wild double battles or wild triple battles but I'm gonna work on that. Please credit TungstenBasilisk (me), ThatWelshOne_, Vendily and Cilerba!
     

    Attachments

    • Proper Wild Item Drops
      Screenshot Wild Item Drops.png
      23.2 KB · Views: 158
    Last edited:
  • 16
    Posts
    4
    Years
    • Seen May 3, 2022
    One thing I just noticed, is that for some reason the text displayed when a Pokemon drops an item will say "The wild the wild (Pokemon)..."
    just remove "The wild" from the display text in the main script and it'll display properly
     
  • 16
    Posts
    4
    Years
    • Seen May 3, 2022
    So this is the final version of the script! It works for single, double, and triple battles. Should work for anything bigger than that as well, if you have those features in your game (like horde battles for instance). Enjoy!
     
  • 465
    Posts
    7
    Years
    • Seen Jun 1, 2024
    Glad to see someone reworked the old busted code, it knew someone would some day (i was trying to figure it out aswell at some point)

    this is actually rather simple to downport to v17 (since you say its final means you wont need to keep updating it if people want it)
    all you need to change if the "@battle.battlers.each {|b|" to "for i in 0...4" and add an "end" near the bottom (replacing the "}" basically)
    and add "[email protected]". change "next if !b.opposes?" to "next if [email protected]?(i)" and it should work for v17.

    might just be a v17 issue or that i used just wild hold items over wild drop items (simplicity sakes, mainly why i didnt share my v17 version as just a code block)
    but unless you add "wildDrop[0]!=nil" (and one for wildDrop[1] and wildDrop[2] it will get a "Item number 0 is invalid" error, again either my doing or a v17 thing, felt i'd share.
    it works perfectly so far for v17. (Assuming this isnt added as you want people to give atleast an item for each, understandable)
     
  • 16
    Posts
    4
    Years
    • Seen May 3, 2022
    I've made a small change to the script for those of you who are using it or plan to use it. As it currently stands in the OP, there is only 1 random number generated for all 3 drops (Common, Uncommon, and Rare) so that means that if you get a rare drop, you will always get the common and uncommon drops as well. And if you get the uncommon drop, you will always get the common drop as well. It also means you can't get just the uncommon or rare drops by themselves. So to remedy this, I just created a droprnd variable for each drop (droprndC, droprndU, and droprndR) like so:

    Code:
    droprndC = rand(100)
    droprndU = rand(100)
    droprndR = rand(100)

    then below, it should look like this:

    Code:
    if droprndC<chances[0]
            if $PokemonBag.pbStoreItem(wildDrop[0],firstqty)
              itemname = PBItems.getName(wildDrop[0])
              pocket = pbGetPocket(wildDrop[0])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,firstqty))
            end
          end
          if droprndU<chances[1]
            if $PokemonBag.pbStoreItem(wildDrop[1],secondqty)
              itemname = PBItems.getName(wildDrop[1])
              pocket = pbGetPocket(wildDrop[1])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,secondqty))
            end
          end
          if droprndR<chances[2]
            if $PokemonBag.pbStoreItem(wildDrop[2],thirdqty)
              itemname = PBItems.getName(wildDrop[2])
              pocket = pbGetPocket(wildDrop[2])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,thirdqty))
            end
          end

    P.S: I also removed the part that said
    Code:
    (wildDrop[0]==wildDrop[1] && wildDrop[1]==wildDrop[2]) ||
    this is not necessary, it's just personal preference. All this part does is guarantee a 100% chance to drop an item if all 3 drop items are the same in the PBS, and I just don't like that part personally anymore so I removed it.
     
  • 8
    Posts
    3
    Years
    • They/Them
    • Seen Jun 13, 2022
    Glad to see someone reworked the old busted code, it knew someone would some day (i was trying to figure it out aswell at some point)

    this is actually rather simple to downport to v17 (since you say its final means you wont need to keep updating it if people want it)
    all you need to change if the "@battle.battlers.each {|b|" to "for i in 0...4" and add an "end" near the bottom (replacing the "}" basically)
    and add "[email protected]". change "next if !b.opposes?" to "next if [email protected]?(i)" and it should work for v17.

    might just be a v17 issue or that i used just wild hold items over wild drop items (simplicity sakes, mainly why i didnt share my v17 version as just a code block)
    but unless you add "wildDrop[0]!=nil" (and one for wildDrop[1] and wildDrop[2] it will get a "Item number 0 is invalid" error, again either my doing or a v17 thing, felt i'd share.
    it works perfectly so far for v17. (Assuming this isnt added as you want people to give atleast an item for each, understandable)


    Could you be more specific with this? I don't know where you're suggesting to add "wildDrop[0]!=nil"
     
  • 465
    Posts
    7
    Years
    • Seen Jun 1, 2024
    Could you be more specific with this? I don't know where you're suggesting to add "wildDrop[0]!=nil"

    bit late of a reply lol, but thankfully, i can explain; if you do use wild held items (like lucky eggs off some mons) over wild item drops, i had to add the wildDrop[0]!=nil as otherwise it got errors.
    i added it to the "if droprndC<chances[0]" (if you use OP's updated changes/script from march they were introduced then) aswell as one for droprndU and droprndR (but 1 and 2 over 0)
    i also added "wildDrop[0]!=0" as i think it did the same. hope that helps, its the only place i added it so thats where it relates, thats more of a bugfix for using wild held items over the added wild item drops though, not for the downport (unless it is as i never tested with wild drops over held items)
     
  • 8
    Posts
    3
    Years
    • They/Them
    • Seen Jun 13, 2022
    Hey honestly I'm surprised and grateful you replied at all, lol.
    I'm pretty sure it's just an issue with the script period, as I'm in 18 and not using hold items instead (though I did experiment with that at first). Thanks to your help I was eventually able to figure out where to put the fixes. I'm gonna post it here for future users.

    Code:
    class PokeBattle_Scene
     
      def pbWildBattleSuccess
        @battle.battlers.each {|b|
        next if !b
        next if !b.opposes?
        pkmn = b.pokemon
        next if !pkmn
        if pkmn.wildDropItems.inject(0){|sum,x| sum + x } != 0
          # Get array of item IDs of held items
          wildDrop = pkmn.wildDropItems
          firstqty = rand(2)+1
          secondqty = rand(2)+1
          thirdqty = rand(2)+1
          firstPkmn = $Trainer.firstPokemon
          chances = [50,25,5]
          chances = [60,40,15] if firstPkmn && isConst?(firstPkmn.ability,PBAbilities,:COMPOUNDEYES)
          chances = [50,50,50] if firstPkmn && isConst?(firstPkmn.ability,PBAbilities,:SUPERLUCK)
          droprndC = rand(100)
          droprndU = rand(100)
          droprndR = rand(100)
          # This bit is tricky because a Pokémon might not have all their items defined
          # Plus, wildHold would need to be a single item
          # As it stands, it's an array, so the methods below don't work unedited
          # I've subsetted the array to the second element for testing purposes for now
          if droprndC<chances[0] && wildDrop[0]!=0 && wildDrop[0]!=nil
            if $PokemonBag.pbStoreItem(wildDrop[0],firstqty)
              itemname = PBItems.getName(wildDrop[0])
              pocket = pbGetPocket(wildDrop[0])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,firstqty))
            end
          end
          if droprndU<chances[1] && wildDrop[1]!=0 && wildDrop[1]!=nil
            if $PokemonBag.pbStoreItem(wildDrop[1],secondqty)
              itemname = PBItems.getName(wildDrop[1])
              pocket = pbGetPocket(wildDrop[1])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,secondqty))
            end
          end
          if droprndR<chances[2] && wildDrop[2]!=0 && wildDrop[2]!=nil
            if $PokemonBag.pbStoreItem(wildDrop[2],thirdqty)
              itemname = PBItems.getName(wildDrop[2])
              pocket = pbGetPocket(wildDrop[2])
              @battle.pbDisplayPaused(_INTL("{1} dropped\n{2} <icon=bagPocket#{pocket}> x{3}!",b.pbThis,itemname,thirdqty))
            end
          end
        end
    	}
      @battleEnd = true
      pbBGMPlay(pbGetWildVictoryME)  
      end
    end
     
  • 20
    Posts
    4
    Years
    • Seen Nov 24, 2023
    does not work in version 19.1. there is how to make it work for pokemon to drop items.
     
  • 20
    Posts
    4
    Years
    • Seen Nov 24, 2023
    does not work in version 19.1. there is how to make it work for pokemon to drop items.
     
    Back
    Top