Advertiser Content
Male
Canada
Seen 4 Days Ago
Posted 3 Weeks Ago
6 posts
32 Days
Hey all, I made a script for Beast Boost that utilizes for loops to check which stat of the Pokémon should be raised. I tried my best to condense it, but this is about as short as I could make it. It works really well in game and I haven't had any issues yet. If you want to use it, just paste it under '# Moxie' in the 'PokeBattle_Battler' script section. If you have any questions don't hesitate to ask!

    # Beast Boost
    if user.hasWorkingAbility(:BEASTBOOST) && target.fainted?
      
      # Store user's current stats and boostable stats in seperate arrays
      userStats=[user.attack,user.defense,user.spatk,user.spdef,user.speed]
      statBoost=[PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPATK,PBStats::SPDEF,PBStats::SPEED]
      statCheck=0
      statToBoost=0
      boost=0
      
      # Check which user stat is the most proficient
      for i in userStats
        if i>statCheck
          statCheck=i
          statToBoost=userStats.index(i)
        end
        for j in statBoost
          if statBoost.index(j)==statToBoost
            boost=statBoost.index(j)
          end
        end            
      end
      if !user.pbCanIncreaseStatStage?(boost,user)
        @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",userFb.pbThis))
      end
      if user.pbIncreaseStatWithCause(boost,1,user,PBAbilities.getName(user.ability))
        PBDebug.log("[Ability triggered] #{user.pbThis}'s Beast Boost")
      end
    end

mgriffin

Online now
Posted 1 Day Ago
757 posts
5.6 Years
I think you might be interested to learn about #max_by which encapsulates iterating an array and finding the maximum value based on some logic, which here encapsulates "return :attack if user.attack is the biggest" (via #send because user.send(:attack) = user.attack). I'm also doing something a bit cheeky to convert from :attack to :ATTACK via #upcase (which works like String's #upcase), and then using getConst to get that value from PBStats (i.e. getConst(PBStats, :attack.upcase) = getConst(PBStats, :ATTACK) = PBStats::ATTACK).

Also I think you can use elsif for pbIncreaseStatWithCause because presumably it's not going to do anything if we can't increase stat stage?

if user.hasWorkingAbility(:BEASTBOOST) && target.fainted?
  stats = [:attack, :defense, :spatk, :spdef, :speed]
  max_stat = stats.max_by {|stat| user.send(stat)}.upcase
  boost = getConst(PBStats, max_stat)
  if !user.pbCanIncreaseStatStage?(boost, user)
    @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!", userFb.pbThis))
  elsif user.pbIncreaseStatWithCause(boost, 1, user, PBAbilities.getName(user.ability))
    PBDebug.log("[Ability triggered] #{user.pbThis}'s Beast Boost")
  end
I'm not sure if the version of Ruby in RMXP actually supports max_by, but I hope so!

If not…
Spoiler:

… I suspect your use of #index is suboptimal. For example, your statBoosts are ordered the same as userStats, so if you know the index of one then you can find the index of the other.

for i in userStats
  if i>statCheck
    statCheck=i
    statToBoost=userStats.index(i)
  end
  boost=statBoost[statToBoost]
end
Then you could use #each_with_index to avoid having to call #index on each iteration (which makes your code quadratic time because for each element in userStats #index will iterate each element of userStats).

userStats.each_with_index do |i, index|
  if i > statCheck
    statCheck = i
    boost = statBoost[index]
  end
end
Note that statToBoost is no longer needed at all. Personally I'd rename your variables too, ultimately settling on something like this:

if user.hasWorkingAbility(:BEASTBOOST) && target.fainted?
  userStats = [user.attack, user.defense, user.spatk, user.spdef, user.speed]
  stats = [PBStats::ATTACK, PBStats::DEFENSE, PBStats::SPATK, PBStats::SPDEF, PBStats::SPEED]

  maxUserStat = 0
  maxStat = nil
  userStats.each_with_index do |userStat, i|
    if userStat > maxUserStat
      maxUserStat = userStat
      maxStat = stats[i]
    end
  end

  if !user.pbCanIncreaseStatStage?(boost, user)
    @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!", userFb.pbThis))
  elsif user.pbIncreaseStatWithCause(boost, 1, user, PBAbilities.getName(user.ability))
    PBDebug.log("[Ability triggered] #{user.pbThis}'s Beast Boost")
  end
end
Advertiser Content