• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Our friends from the Johto Times are hosting a favorite Pokémon poll - and we'd love for you to participate! Click here for information on how to vote for your favorites!
  • 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.

[Scripting Question] How to check for held items?

  • 132
    Posts
    10
    Years
    A better question would be, what script can I use to check if a player has EVER owned an item? pbQuantity doesn't seem to account for items being currently held by pokémon, so if I wanted to check to see whether the player has a venusaurite, the limitations of pbQuantity start getting in the way.

    Is there a script I can make that says something along the lines of, "you received a venusaurite. Now, pbHasOwnedItem?(PBItems::VENUSAURITE) = true."?

    Cheers!
     
    Well that means that you need to record that item as owned. So depending on how many items need to be checked you can just store them in a variable and with pbHasOwnedItem? check it. That'd be the straight forward solution
     
    Well that means that you need to record that item as owned. So depending on how many items need to be checked you can just store them in a variable and with pbHasOwnedItem? check it. That'd be the straight forward solution
    Wouldn't that mean I'd have to make variables for each mega stone? I'd like to specify that the script I've made is meant to check if the player has a pokémon who can mega evolve, and give the player the corresponding mega stone. Since the script occurs multiple times, it will wind up giving the player a stone that he or she has already been given.

    What could I do to simply flag a certain item with a true/false, that will remain true/false? Here's the bare bones of a script that would make sense to me:
    Code:
    def pbStoreOwned(item)
      if $PokemonBag.pbQuantity(item)>0
        [S-HIGHLIGHT]pbOwned(item)[/S-HIGHLIGHT]
      end
    end
    And then, to check the true/false flag:
    Code:
    def pbCheckOwned(item)
      if [S-HIGHLIGHT]pbOwned(item)=true[/S-HIGHLIGHT]
        return true
      else
        return fale
      end
    end
    The highlighted parts are what I'm unsure about. Any tips?
     
    No you don't need a seperate variable for each stone.
    You can store them in a array. But then again if it's just about considering held items as well then you can just firstcheck if the item is in the bag and if not if it is held by a Pokemon in your party.
     
    No you don't need a seperate variable for each stone.
    You can store them in a array. But then again if it's just about considering held items as well then you can just firstcheck if the item is in the bag and if not if it is held by a Pokemon in your party.
    Yeah, let's go with the second option then. What would be an easy way to do that that doesn't check through each pokemon? Could I use something like $Trainer.party.item to check all held items simultaneously?
    Thanks!
     
    Use a double equal sign for checking equivalence as the single equal sign is used for assignment of values to variables.
     
    Yeah, let's go with the second option then. What would be an easy way to do that that doesn't check through each pokemon? Could I use something like $Trainer.party.item to check all held items simultaneously?
    Thanks!
    I dont think there is a method but it shouldn't matter as you wouldn't notice a difference.

    Just check it by using something like
    Code:
    for i in $Trainer.party
    if i.item==(item to be checked for
    return true
    end
    return false 
    end
     
    If you'd like to use it in an event, a more compact version could be something like this:
    Code:
    $Trainer.party.any? { |e| e && e.item == PBItems::VENUSAURITE }


    You could use this directly in a conditional branch, or set it to a global variable (pbSet(1, [the code i just posted])
     
    Last edited:
    Awesome! Thanks, these two scripts will come in handy. Unfortunately, I can't get either of them to quite work.
    Code:
    for i in $Trainer.party
    if i.item==(item to be checked for
    return true
    end
    return false 
    end
    For some reason, this only works for the first pokemon in the party. ie, if venusaur is [0] and is holding its mega stone, the script will work and go on to check for other pokemon, but if venusaur is [1] through [5], the script will give you another venusaurite.
    Code:
    $Trainer.party.any? { |e| e && e.item == PBItems::VENUSAURITE }
    This results in an infinite loop for reasons I can't understand (probably something wrong on my end).

    Here is the script I've made:
    Code:
    loop do
        if pbHasSpecies?(PBSpecies::VENUSAUR)
          if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)==0
            if $Trainer.party.any? { |e| e && e.item == PBItems::VENUSAURITE }
              next
            else
                Kernel.pbReceiveItem(PBItems::VENUSAURITE)
                break
            end
          end
        end
        
        if pbHasSpecies?(PBSpecies::ALAKAZAM) #...so on and so forth
    Sorry for all the questions, but you're being a huge help! Thanks!
     
    What did you put in for "(item to be checked for)"?
     
    Last edited:
    Just (PBItems::VENUSAURITE). I didn't get any errors, it just checked for only the first pokemon in the party, strangely enough. Though, I'd assume "for i in $Trainer.party" would scan through all the party.
     
    I realized what was going on. My bad. The script has to look like this:
    Code:
    for i in $Trainer.party
     if i.item==(item to be checked for)
    return true 
    end
    end 
    return false
     
    I realized what was going on. My bad. The script has to look like this:
    Code:
    for i in $Trainer.party
     if i.item==(item to be checked for)
    return true 
    end
    end 
    return false
    Ughh, it's just not working for me. I should mention that my script is a loop and cannot be used in a conditional branch, so I can't use true or false. However, I did manage to get the loop working properly, so it's just a matter of i.item doing its job. ?How would you implement your script into mine, if mine looked like this:
    Code:
    loop do
        if pbHasSpecies?(PBSpecies::VENUSAUR)
          if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)==0
            for i in $Trainer.party
              if i.item!=(PBItems::VENUSAURITE)
                Kernel.pbReceiveItem(PBItems::VENUSAURITE)
                break if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)==1
              end
            end
            break if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)==1
          end
        end
    end
    :confused:
     
    Uhm just have to say that a loop in this script makes no sense. THere simply is no need for it since you don't need to do this x times. You only want to check once. Also in your code, as far as I can tell, this loop would run forever if you don't have a VENUSAURITE.

    Besides that it would also help to see the complete script (from the def line till the last end statment of this function) and to know how you use it (I assume you use it in a conditional branch in an event)
     
    Uhm just have to say that a loop in this script makes no sense. THere simply is no need for it since you don't need to do this x times. You only want to check once. Also in your code, as far as I can tell, this loop would run forever if you don't have a VENUSAURITE.

    Besides that it would also help to see the complete script (from the def line till the last end statment of this function) and to know how you use it (I assume you use it in a conditional branch in an event)
    I should really be more specific, my bad. The loop is required because, in the full script, the script checks through ALL pokemon that can possibly mega evolve. So if the player doesn't have a venusaur, the script will continue to check for others, like charizard, blastoise, alakazam, so on and so forth. If the player has none of the above, the loop gives the player one of 8 megastones (per gym) at random to prevent the player from receiving nothing.

    I [S-HIGHLIGHT]SOLVED[/S-HIGHLIGHT] this eventually. I think the way I was using "next" was resulting in an infinite loop. Here is a working version of the script that I've shortened to only two pokemon:
    Code:
    def pbReceiveMega
      loop do
        if pbHasSpecies?(PBSpecies::BULBASAUR) || pbHasSpecies?(PBSpecies::IVYSAUR) || pbHasSpecies?(PBSpecies::VENUSAUR)
          if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)==0
            if !$Trainer.party.any? { |e| e && e.item == PBItems::VENUSAURITE }
              Kernel.pbMessage(_INTL("This is perfect for you."))
              Kernel.pbReceiveItem(PBItems::VENUSAURITE)
              break if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)>0
            end
          end
        end
        if pbHasSpecies?(PBSpecies::ABRA) || pbHasSpecies?(PBSpecies::KADABRA) || pbHasSpecies?(PBSpecies::ALAKAZAM)
          if $PokemonBag.pbQuantity(PBItems::ALAKAZITE)==0
            if !$Trainer.party.any? { |e| e && e.item == PBItems::ALAKAZITE }
              Kernel.pbMessage(_INTL("This is perfect for you."))
              Kernel.pbReceiveItem(PBItems::ALAKAZITE)
              break if $PokemonBag.pbQuantity(PBItems::ALAKAZITE)>0
            end
          end
        end
      break
      end
    end
    I simply call the script after each gym leader is defeated. Thanks for all the help!! :)
     
    Okay now I see what you want to achieve. However the way you laid out your script doesn't even require a loop. besides that it is in fact not even looping. See what the loop does is, it is going through ALL code between
    Code:
    loop do
    and the loop closing
    Code:
    end
    so in your case it would loop through
    Code:
    if pbHasSpecies?(PBSpecies::BULBASAUR) || pbHasSpecies?(PBSpecies::IVYSAUR) || pbHasSpecies?(PBSpecies::VENUSAUR)
          if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)==0
            if !$Trainer.party.any? { |e| e && e.item == PBItems::VENUSAURITE }
              Kernel.pbMessage(_INTL("This is perfect for you."))
              Kernel.pbReceiveItem(PBItems::VENUSAURITE)
              break if $PokemonBag.pbQuantity(PBItems::VENUSAURITE)>0
            end
          end
        end
        if pbHasSpecies?(PBSpecies::ABRA) || pbHasSpecies?(PBSpecies::KADABRA) || pbHasSpecies?(PBSpecies::ALAKAZAM)
          if $PokemonBag.pbQuantity(PBItems::ALAKAZITE)==0
            if !$Trainer.party.any? { |e| e && e.item == PBItems::ALAKAZITE }
              Kernel.pbMessage(_INTL("This is perfect for you."))
              Kernel.pbReceiveItem(PBItems::ALAKAZITE)
              break if $PokemonBag.pbQuantity(PBItems::ALAKAZITE)>0
            end
          end
        end
      break

    but since on your last line you
    Code:
    break
    it will always break after the first time it went through the whole code.
    So then you could as well leave out the unneccssarry loop and instead of using
    Code:
     break if
    use
    Code:
    return if

    Also another thing you might want to consider is that a player might have an ALAKAZAM with a Mega Stone in a box. Then he would still be able to get a second mega stone of that sort. Especially for that reason it actually might be better to store the info which mega stone was received already in an array and then just check the array. It takes up less lines of code, especially if you work with all megas.

    Of course these are just my thoughts on it
     
    Back
    Top