• 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.

[Custom Feature Question] Held Item that increases HP Stat

79
Posts
8
Years
  • Age 28
  • Seen Jan 12, 2024
For example, if I wanted the Reaper Cloth to increase Dusknoir's HP stat by 33% while holding it, how would I code that? It would be different than just having the damage multiplier be 66%, since moves like Seismic Toss, Nightshade, Dragon Rage, and Sonic Boom deal direct damage. It would affect moves like Wish and Leech seed as well, where a simple defense change wouldn't.

I can't find anything like 'hpmult' (as opposed to speedmult and defmult), and I'd like to avoid making it a form change if possible.

Thanks
 
1,403
Posts
10
Years
  • Seen Apr 18, 2024
So I suppose the value you want to be modifying is "totalhp" (probably in PokeBattle_Pokemon). I'm not sure the best place to make the change, but calcStats seems like a reasonable candidate. You might need to make it so that equipping/unequipping an item calls calcStats if it doesn't already.
 
79
Posts
8
Years
  • Age 28
  • Seen Jan 12, 2024
You might need to make it so that equipping/unequipping an item calls calcStats if it doesn't already.

How would I go about doing this? I think I found the right place to change HP; the code is ugly but it doesn't return any errors lol
 
172
Posts
7
Years
  • Age 31
  • Seen Sep 6, 2022
For example, if I wanted the Reaper Cloth to increase Dusknoir's HP stat by 33% while holding it, how would I code that? It would be different than just having the damage multiplier be 66%, since moves like Seismic Toss, Nightshade, Dragon Rage, and Sonic Boom deal direct damage. It would affect moves like Wish and Leech seed as well, where a simple defense change wouldn't.

I can't find anything like 'hpmult' (as opposed to speedmult and defmult), and I'd like to avoid making it a form change if possible.

Thanks

Just giving you a heads up, changing up can get a little weird. I did this with some mega Pok?mon, not realizing that they never actual increase hp in the normal megas and it?s because of how it changes back and forth. So with your item for example, if it gets knocked off or taken during battle your dusknoir could just faint right when it loses the item if it?s hp is low enough. Or even outside of battle, for example if dusknoir is your only alive Pok?mon but is low on hp and you remove the item for some reason causing it to faint then your whole party is knocked out. Just make sure you cover all your bases when you do this so it doesn?t lead to any weird glitches or errors
 
79
Posts
8
Years
  • Age 28
  • Seen Jan 12, 2024
What did you write?

Does it cause the HP to increase?

in Pokebattle_Pokemon:

Code:
[COLOR="green"]# Returns the maximum HP of this Pok?mon.[/COLOR]
  def calcHP(base,level,iv,ev)
    return 1 if base==1
    return ((base*2+iv+(ev>>2))*level/100).floor+level+10
    [COLOR="Red"]if isConst?(self.species,PBSpecies,:DUSKNOIR) && 
      self.hasWorkingItem(:REAPERCLOTH)
      return ((((base*2+iv+(ev>>2))*level/100)+level+10)*1.3).floor
    end[/COLOR]
  end

edit: I tried rearranging the script so that dusknoir's code happens before the normal calculation:

Code:
[COLOR="green"]# Returns the maximum HP of this Pok?mon.[/COLOR]
  def calcHP(base,level,iv,ev)
    return 1 if base==1
[COLOR="Red"]    return ((((base*2+iv+(ev>>2))*level/100)+level+10)*1.3).floor if isConst?(self.species,PBSpecies,:DUSKNOIR) && 
      self.hasWorkingItem(:REAPERCLOTH)   [/COLOR]
    return ((base*2+iv+(ev>>2))*level/100).floor+level+10
  end

but it still doesn't change.
It so far is not changing HP at all, I'm assuming it's because equipping items isn't calling calcStats. Maybe I messed up somewhere else, idk
 
Last edited:
1,403
Posts
10
Years
  • Seen Apr 18, 2024
in Pokebattle_Pokemon:

Code:
[COLOR="green"]# Returns the maximum HP of this Pok?mon.[/COLOR]
  def calcHP(base,level,iv,ev)
    return 1 if base==1
    return ((base*2+iv+(ev>>2))*level/100).floor+level+10
    [COLOR="Red"]if isConst?(self.species,PBSpecies,:DUSKNOIR) && 
      self.hasWorkingItem(:REAPERCLOTH)
      return ((((base*2+iv+(ev>>2))*level/100)+level+10)*1.3).floor
    end[/COLOR]
  end

edit: I tried rearranging the script so that dusknoir's code happens before the normal calculation:

Code:
[COLOR="green"]# Returns the maximum HP of this Pok?mon.[/COLOR]
  def calcHP(base,level,iv,ev)
    return 1 if base==1
[COLOR="Red"]    return ((((base*2+iv+(ev>>2))*level/100)+level+10)*1.3).floor if isConst?(self.species,PBSpecies,:DUSKNOIR) && 
      self.hasWorkingItem(:REAPERCLOTH)   [/COLOR]
    return ((base*2+iv+(ev>>2))*level/100).floor+level+10
  end

but it still doesn't change.
It so far is not changing HP at all, I'm assuming it's because equipping items isn't calling calcStats. Maybe I messed up somewhere else, idk
Your second code looks reasonable?you're right that if you don't put the Dusknoir case above the normal case that it will never apply.

And I think you're also right that equipping items doesn't call calcStats?if I remove the item check the HP *is* modified; and if I leave the item check in (actually I used hasItem instead of hasWorkingItem) then my HP is modified if I faint/gain a level.

So add a call to calcStats in setItem and then have a think about what NewAgeSteel said about Pok?mon getting KOed by the sudden change in max HP.
 
79
Posts
8
Years
  • Age 28
  • Seen Jan 12, 2024
And I think you're also right that equipping items doesn't call calcStats?if I remove the item check the HP *is* modified; and if I leave the item check in (actually I used hasItem instead of hasWorkingItem) then my HP is modified if I faint/gain a level.

Yeah I tested this and it returned an undefined method error. changing 'self.hasWorkingItem(:REAPERCLOTHER)' to 'isConst?(self.item,PBItems,:REAPERCLOTH)' fixed this.

So add a call to calcStats in setItem

this is a dumb question but how do I add a call to something? I tried adding 'def calcStats above setItem's script in Pokebattle_Pokemon, but this returned an error:

Code:
[COLOR="Green"]# Sets this Pok?mon's item. Accepts symbols[/COLOR].
[COLOR="Red"]   def calcStats[/COLOR]
     def setItem(value)
       if value.is_a?(String) || value.is_a?(Symbol)
            value=getID(PBItems,value)
       end
       self.item=value
     end
[COLOR="red"]   end[/COLOR]

This was basically me just guessing so I kinda expected it not to work lol
 
1,403
Posts
10
Years
  • Seen Apr 18, 2024
this is a dumb question but how do I add a call to something? I tried adding 'def calcStats above setItem's script in Pokebattle_Pokemon, but this returned an error:

Code:
[COLOR="Green"]# Sets this Pok?mon's item. Accepts symbols[/COLOR].
[COLOR="Red"]   def calcStats[/COLOR]
     def setItem(value)
       if value.is_a?(String) || value.is_a?(Symbol)
            value=getID(PBItems,value)
       end
       self.item=value
     end
[COLOR="red"]   end[/COLOR]

What you did there is essentially redefine calcStats and remove the definition of setItem, so yeah, I wouldn't expect that to work.

You want to write something more like this:

Code:
     [COLOR="Green"]# Sets this Pok?mon's item. Accepts symbols[/COLOR].
     def setItem(value)
       if value.is_a?(String) || value.is_a?(Symbol)
            value=getID(PBItems,value)
       end
       self.item=value
       [COLOR="Red"]self.calcStats[/COLOR]
     end

The intent here is that the last thing we do after setting the item is recalculate the stats.
 
79
Posts
8
Years
  • Age 28
  • Seen Jan 12, 2024
You want to write something more like this:

Code:
     [COLOR="Green"]# Sets this Pok?mon's item. Accepts symbols[/COLOR].
     def setItem(value)
       if value.is_a?(String) || value.is_a?(Symbol)
            value=getID(PBItems,value)
       end
       self.item=value
       [COLOR="Red"]self.calcStats[/COLOR]
     end

The intent here is that the last thing we do after setting the item is recalculate the stats.

This worked! Thank you!

Just giving you a heads up, changing up can get a little weird. I did this with some mega Pok?mon, not realizing that they never actual increase hp in the normal megas and it?s because of how it changes back and forth. So with your item for example, if it gets knocked off or taken during battle your dusknoir could just faint right when it loses the item if it?s hp is low enough. Or even outside of battle, for example if dusknoir is your only alive Pok?mon but is low on hp and you remove the item for some reason causing it to faint then your whole party is knocked out. Just make sure you cover all your bases when you do this so it doesn?t lead to any weird glitches or errors

Would there be a way to have it so if its HP hit zero upon the item's removal, it would go to 1 HP instead? This would fix most of the problems, I think.
 
1,403
Posts
10
Years
  • Seen Apr 18, 2024
Would there be a way to have it so if its HP hit zero upon the item's removal, it would go to 1 HP instead? This would fix most of the problems, I think.

I am confident that if you have a look at the nearby code you can work out how to do that yourself. (Or something very similar)
 
79
Posts
8
Years
  • Age 28
  • Seen Jan 12, 2024
I am confident that if you have a look at the nearby code you can work out how to do that yourself. (Or something very similar)

I'm sure it would be 'return 1 if...' but I don't know where to go from there, or where to put it. I don't know how to code "if item is removed and hp drops to zero or below" lol

Also, if the item is lost during battle, it won't recalculate its hp. I tried adding 'opponent.calcStats' to Knock Off's script, but I got an undefined method error:

Code:
class PokeBattle_Move_0F0 < PokeBattle_Move
  def pbEffectAfterHit(attacker,opponent,turneffects)
    if !attacker.fainted? && !opponent.fainted? && opponent.item!=0 &&
       opponent.damagestate.calcdamage>0 && !opponent.damagestate.substitute
      if !attacker.hasMoldBreaker && opponent.hasWorkingAbility(:STICKYHOLD)
        abilityname=PBAbilities.getName(opponent.ability)
        @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",opponent.pbThis,abilityname,@name))
      elsif [email protected](opponent,opponent.item)
        itemname=PBItems.getName(opponent.item)
        opponent.item=0
        [COLOR="Red"]opponent.calcStats[/COLOR]
        opponent.effects[PBEffects::ChoiceBand]=-1
        opponent.effects[PBEffects::Unburden]=true
        @battle.pbDisplay(_INTL("{1} dropped its {2}!",opponent.pbThis,itemname))
      end
    end
  end
 
1,403
Posts
10
Years
  • Seen Apr 18, 2024
I'm sure it would be 'return 1 if...' but I don't know where to go from there, or where to put it. I don't know how to code "if item is removed and hp drops to zero or below" lol
Like I said, look at nearby code. You should be able to prevent a Pok?mon from fainting because of a change in their HP base stat (which is not quite the same thing, but I don't think the difference is all that relevant).

Also, if the item is lost during battle, it won't recalculate its hp. I tried adding 'opponent.calcStats' to Knock Off's script, but I got an undefined method error:
Yeah, I think that Pok?mon in battle are a different type (PokeBattle_Battler) to Pok?mon out of battle (PokeBattle_Pokemon). This is why I used hasItem? instead of hasWorkingItem?. You could try opponent.pokemon.calcStats, but it makes more sense to try and find what the equivalent function is. Search for calcStats in PokeBattle_Battler and make a judgement call about which function that calls calcStats is most likely to be what you want.
 
Last edited:
Back
Top