Seen 1 Week Ago
Posted March 7th, 2021
24 posts
3 Years
So I'm almost at the last stretch of adding custom moves to my game. Most of the moves were simple modifications of already established moves, but I have a few more that may need original scripts with new function codes to make them work.

I scripted most of them myself in an old version of PE, but the new version hasn't been so nice to me and I want to conserve some time (and frustration) and reach out to the forum for some help.

Most of the scripts were simple enough for me to come up with myself, so if you already mastered the new version of PE then they should be pretty easy to come up with:

Move #1 - A move that does regular damage with the added effect of putting the target to sleep the next turn (Yawn)

Move#2 - A move that does regular damage with the added effect of badly poisoning the target the next turn (Poison Arrow)

Move#3 - A move that does regular damage with the added effect of burning the target the next turn (Blaze Arrow)

Move#4 - A move that sharply raises Attack & Special Attack, but drops Defense and Special Defense by 1 stage

Move#5 - A move that causes recoil damage and has an added effect of possibly poisoning the target.

Move#6 - A move that drastically increases Special Defense

Move#7 - A move that does regular damage with the added effect of raising Attack & Special Attack by 1 stage

Move#8 - A move that does regular damage and drops Accuracy by 2 stages

Move#9 - A Water-type move that does added Electric-type damage (doesn't affect Ground types)

Move#10 - A move that does regular damage and disables the last move used by the target

Move#11 - A move that does regular damage and switches items with the target. If the target has an item but the user does not, the target loses the item and the user gains it. If the user has an item but the target does not, the user loses the item and the target gains it. If both the user and the target have no items then this move just does regular damage.

Move #11 is probably the only hard one, but I'll keep working it myself and would appreciate some feedback from anybody

Thank You!!

Vendily

Female
Seen 7 Hours Ago
Posted 6 Days Ago
1,349 posts
5.7 Years
Former Fan Games Staff Post
<Snipped>
Hey tyranitar28, I moved your thread here, to the Pokemon Essentials Forum.
This is the place to ask questions about Essentials!
Male
Seen 2 Weeks Ago
Posted March 8th, 2021
140 posts
6.5 Years
A lot of the moves appear to be damaging versions of some status moves. It's a good rule of thumb to include the following line to the pbEffect function of your custom moves to allow the ability for them to do damage:
return super(attacker,opponent,hitnum,alltargets,showanimation) if @basedamage>0
Move #1:
################################################################################
# Damaging version of Yawn
################################################################################
class PokeBattle_Move_nnn < PokeBattle_Move # change nnn to a custom function code
  def pbAdditionalEffect(attacker,opponent)
    return false if !opponent.pbCanSleep?(true) || opponent.effects[PBEffects::Yawn]>0
    pbShowAnimation(@id,attacker,opponent,hitnum,alltargets,showanimation)
    opponent.effects[PBEffects::Yawn]=2
    @battle.pbDisplay(_INTL("{1} made {2} drowsy!",attacker.pbThis,opponent.pbThis(true)))
    return true
  end
end
PokeBattle_Move subclasses that have the pbAdditionalEffect function allow you to define a probability of those effects occurring in the PBS file and are affected by abilities such as Huge Power.

For Moves #2 and #3, you'll need to create and define new PBEffects to act as countdowns similar in function to the Yawn effect and decrease their values at the same time as the Yawn effect's value. The code for Move #1 can be changed to badly poison or burn the opponent instead of putting them to sleep.

Move #4 is simple to implement and based on Shell Smash:
################################################################################
# Increases the user's Attack and Special Attack by 1 stage
# and decreases the user's Defense and Special Defense by 1 stage.
################################################################################
class PokeBattle_Move_nnn < PokeBattle_Move # change nnn to a custom function code
  def pbEffect(attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
    ret = @basedamage>0 ? super(attacker,opponent,hitnum,alltargets,showanimation) : 0
    pbShowAnimation(@id,attacker,nil,hitnum,alltargets,showanimation) if ret==0
    if !attacker.pbCanIncreaseStatStage?(PBStats::ATTACK,false) &&
       !attacker.pbCanIncreaseStatStage?(PBStats::SPATK,false)
      @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",attacker.pbThis))
      return ret==0 ? -1 : ret
    end
    showanim=true
    if attacker.pbCanIncreaseStatStage?(PBStats::ATTACK,false)
      attacker.pbIncreaseStat(PBStats::ATTACK,2,false,showanim)
      showanim=false
    end
    if attacker.pbCanIncreaseStatStage?(PBStats::SPATK,false)
      attacker.pbIncreaseStat(PBStats::SPATK,2,false,showanim)
      showanim=false
    end
    if !attacker.pbCanReduceStatStage?(PBStats::DEFENSE,false) &&
       !attacker.pbCanReduceStatStage?(PBStats::SPDEF,false)
      @battle.pbDisplay(_INTL("{1}'s stats won't go any lower!",attacker.pbThis))
      return ret==0 ? -1 : ret
    end
    showanim=true
    if attacker.pbCanReduceStatStage?(PBStats::DEFENSE,false,true)
      attacker.pbReduceStat(PBStats::DEFENSE,1,false,showanim,true)
      showanim=false
    end
    if attacker.pbCanReduceStatStage?(PBStats::SPDEF,false,true)
      attacker.pbReduceStat(PBStats::SPDEF,1,false,showanim,true)
      showanim=false
    end
    return ret
  end
end
Move #5 is simply copy/pasting the recoil move pbEffect (depending if the user should take 1/4, 1/3 or 1/2 the damage dealt as recoil damage) and adding the pbAdditionalEffect from function code 005.

Move #6 is based on function code 021:
################################################################################
# Increases the user's Special Defense by 3 stages.
################################################################################
class PokeBattle_Move_nnn < PokeBattle_Move # change nnn to a custom function code
  def pbEffect(attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
    return -1 if !attacker.pbCanIncreaseStatStage?(PBStats::SPDEF,true)
    pbShowAnimation(@id,attacker,nil,hitnum,alltargets,showanimation)
    ret=attacker.pbIncreaseStat(PBStats::SPDEF,3,false)
    return ret ? 0 : -1
  end
end
Move #7 is a tweaking of the code I suggested for Move #4:
################################################################################
# Increases the user's Attack and Special Attack by 1 stage
################################################################################
class PokeBattle_Move_nnn < PokeBattle_Move # change nnn to a custom function code
  def pbAdditionalEffect(attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
    if !attacker.pbCanIncreaseStatStage?(PBStats::ATTACK,false) &&
       !attacker.pbCanIncreaseStatStage?(PBStats::SPATK,false)
      @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",attacker.pbThis))
      return false
    end
    showanim=true
    if attacker.pbCanIncreaseStatStage?(PBStats::ATTACK,false)
      attacker.pbIncreaseStat(PBStats::ATTACK,2,false,showanim)
      showanim=false
    end
    if attacker.pbCanIncreaseStatStage?(PBStats::SPATK,false)
      attacker.pbIncreaseStat(PBStats::SPATK,2,false,showanim)
      showanim=false
    end
    return true
  end
end
Move #8 is based on the code for moves like Sand Attack:
################################################################################
# Decreases the user's accuracy by 1 stage.
################################################################################
class PokeBattle_Move_nnn < PokeBattle_Move # change nnn to a custom function code
  def pbEffect(attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
    return super(attacker,opponent,hitnum,alltargets,showanimation) if @basedamage>0
    return -1 if !attacker.pbCanReduceStatStage?(PBStats::ACCURACY,true,true)
    pbShowAnimation(@id,attacker,nil,hitnum,alltargets,showanimation)
    ret=attacker.pbReduceStat(PBStats::ACCURACY,2,false,true)
    return ret ? 0 : -1
  end

  def pbAdditionalEffect(attacker,opponent)
    if attacker.pbCanReduceStatStage?(PBStats::ACCURACY,false,true)
      attacker.pbReduceStat(PBStats::ACCURACY,2,false,true)
    end
    return true
  end
end
Move #9 is a little complicated as it's similar in functionality to Flying Press. How much extra Electric-type damage does the user inflict relative to the move's base power?

For Move #10, you can simply tweak function code 0B9 to allow for damaging versions of moves using that function and then define your move in the PBS file:
################################################################################
# For 5 rounds, disables the last move the target used.
################################################################################
class PokeBattle_Move_0B9 < PokeBattle_Move
  def pbEffect(attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
    ret = @basedamage>0 ? super(attacker,opponent,hitnum,alltargets,showanimation) : 0
    return ret if opponent.effects[PBEffects::Disable]>0
    for i in opponent.moves
      if i.id>0 && i.id==opponent.lastMoveUsed && (i.pp>0 || i.totalpp==0)
        pbShowAnimation(@id,attacker,opponent,hitnum,alltargets,showanimation)
        opponent.effects[PBEffects::Disable]=4
        opponent.effects[PBEffects::DisableMove]=opponent.lastMoveUsed
        @battle.pbDisplay(_INTL("{1}'s {2} was disabled!",opponent.pbThis,i.name))
        return ret
      end
    end
    @battle.pbDisplay(_INTL("But it failed!")) if ret==0
    return ret
  end
end
Seen 1 Week Ago
Posted March 7th, 2021
24 posts
3 Years
Thanks, most of these should be easy to implement, but I'm still stuck on Poison Arrow & Blaze Arrow. The poison and burn status effects can't simply be replaced with the sleep status effect in the code since I need to account for different abilities.

Might need to go back to them in the Recruitment phase

But once again, thanks for your input!
Male
Seen 2 Weeks Ago
Posted March 8th, 2021
140 posts
6.5 Years
To clarify as to why, you can actually replace the sleep status effect with poison and burn. You just need to create and define new PBEffects and new check functions.

Script PBEffects:
begin
  module PBEffects
    #===========================================================================
    # These effects apply to a battler
    #===========================================================================
    AquaRing            = 0
    Attract             = 1
    BanefulBunker       = 2
    # ...
    WaterSport          = 111
    WeightChange        = 112
    Yawn                = 113
    PoisonArrow         = 114
    BlazeArrow          = 115
  end
Script Battler_Initialize:
  def pbInitEffects(batonPass)
    if batonPass
      # These effects are passed on if Baton Pass is used, but they need to be
      # reapplied
      @effects[PBEffects::LaserFocus] = (@effects[PBEffects::LaserFocus]>0) ? 2 : 0
      @effects[PBEffects::LockOn]     = (@effects[PBEffects::LockOn]>0) ? 2 : 0
      if @effects[PBEffects::PowerTrick]
        @attack,@defense = @defense,@attack
      end
      # These effects are passed on if Baton Pass is used, but they need to be
      # cancelled in certain circumstances anyway
      @effects[PBEffects::Telekinesis] = 0 if isSpecies?(:GENGAR) && mega?
      @effects[PBEffects::GastroAcid]  = false if unstoppableAbility?
    else
      # These effects are passed on if Baton Pass is used
      @stages[PBStats::ATTACK]   = 0
      @stages[PBStats::DEFENSE]  = 0
      @stages[PBStats::SPEED]    = 0
      @stages[PBStats::SPATK]    = 0
      @stages[PBStats::SPDEF]    = 0
      @stages[PBStats::EVASION]  = 0
      @stages[PBStats::ACCURACY] = 0
      @effects[PBEffects::AquaRing]          = false
      @effects[PBEffects::Confusion]         = 0
      @effects[PBEffects::Curse]             = false
      @effects[PBEffects::Embargo]           = 0
      @effects[PBEffects::FocusEnergy]       = 0
      @effects[PBEffects::GastroAcid]        = false
      @effects[PBEffects::HealBlock]         = 0
      @effects[PBEffects::Ingrain]           = false
      @effects[PBEffects::LaserFocus]        = 0
      @effects[PBEffects::LeechSeed]         = -1
      @effects[PBEffects::LockOn]            = 0
      @effects[PBEffects::LockOnPos]         = -1
      @effects[PBEffects::MagnetRise]        = 0
      @effects[PBEffects::PerishSong]        = 0
      @effects[PBEffects::PerishSongUser]    = -1
      @effects[PBEffects::PowerTrick]        = false
      @effects[PBEffects::Substitute]        = 0
      @effects[PBEffects::Telekinesis]       = 0
    end
    @fainted               = (@hp==0)
    @initialHP             = 0
    @lastAttacker          = []
    @lastFoeAttacker       = []
    @lastHPLost            = 0
    @lastHPLostFromFoe     = 0
    @tookDamage            = false
    @tookPhysicalHit       = false
    @lastMoveUsed          = -1
    @lastMoveUsedType      = -1
    @lastRegularMoveUsed   = -1
    @lastRegularMoveTarget = -1
    @lastRoundMoved        = -1
    @lastMoveFailed        = false
    @lastRoundMoveFailed   = false
    @movesUsed             = []
    @turnCount             = 0
    @effects[PBEffects::Attract]             = -1
    @battle.eachBattler do |b|   # Other battlers no longer attracted to self
      b.effects[PBEffects::Attract] = -1 if b.effects[PBEffects::Attract][email protected]
    end
    @effects[PBEffects::BanefulBunker]       = false
    @effects[PBEffects::BeakBlast]           = false
    @effects[PBEffects::Bide]                = 0
    @effects[PBEffects::BideDamage]          = 0
    @effects[PBEffects::BideTarget]          = -1
    @effects[PBEffects::BlazeArrow]          = 0 # new effect
    @effects[PBEffects::BurnUp]              = false
    @effects[PBEffects::Charge]              = 0
    @effects[PBEffects::ChoiceBand]          = -1
    @effects[PBEffects::Counter]             = -1
    @effects[PBEffects::CounterTarget]       = -1
    @effects[PBEffects::Dancer]              = false
    @effects[PBEffects::DefenseCurl]         = false
    @effects[PBEffects::DestinyBond]         = false
    @effects[PBEffects::DestinyBondPrevious] = false
    @effects[PBEffects::DestinyBondTarget]   = -1
    @effects[PBEffects::Disable]             = 0
    @effects[PBEffects::DisableMove]         = 0
    @effects[PBEffects::Electrify]           = false
    @effects[PBEffects::Encore]              = 0
    @effects[PBEffects::EncoreMove]          = 0
    @effects[PBEffects::Endure]              = false
    @effects[PBEffects::FirstPledge]         = 0
    @effects[PBEffects::FlashFire]           = false
    @effects[PBEffects::Flinch]              = false
    @effects[PBEffects::FocusPunch]          = false
    @effects[PBEffects::FollowMe]            = 0
    @effects[PBEffects::Foresight]           = false
    @effects[PBEffects::FuryCutter]          = 0
    @effects[PBEffects::GemConsumed]         = 0
    @effects[PBEffects::Grudge]              = false
    @effects[PBEffects::HelpingHand]         = false
    @effects[PBEffects::HyperBeam]           = 0
    @effects[PBEffects::Illusion]            = nil
    if hasActiveAbility?(:ILLUSION)
      idxLastParty = @battle.pbLastInTeam(@index)
      if [email protected]
        @effects[PBEffects::Illusion]        = @battle.pbParty(@index)[idxLastParty]
      end
    end
    @effects[PBEffects::Imprison]            = false
    @effects[PBEffects::Instruct]            = false
    @effects[PBEffects::Instructed]          = false
    @effects[PBEffects::KingsShield]         = false
    @battle.eachBattler do |b|   # Other battlers lose their lock-on against self
      next if b.effects[PBEffects::LockOn]==0
      next if b.effects[PBEffects::LockOnPos][email protected]
      b.effects[PBEffects::LockOn]    = 0
      b.effects[PBEffects::LockOnPos] = -1
    end
    @effects[PBEffects::MagicBounce]         = false
    @effects[PBEffects::MagicCoat]           = false
    @effects[PBEffects::MeanLook]            = -1
    @battle.eachBattler do |b|   # Other battlers no longer blocked by self
      b.effects[PBEffects::MeanLook] = -1 if b.effects[PBEffects::MeanLook][email protected]
    end
    @effects[PBEffects::MeFirst]             = false
    @effects[PBEffects::Metronome]           = 0
    @effects[PBEffects::MicleBerry]          = false
    @effects[PBEffects::Minimize]            = false
    @effects[PBEffects::MiracleEye]          = false
    @effects[PBEffects::MirrorCoat]          = -1
    @effects[PBEffects::MirrorCoatTarget]    = -1
    @effects[PBEffects::MoveNext]            = false
    @effects[PBEffects::MudSport]            = false
    @effects[PBEffects::Nightmare]           = false
    @effects[PBEffects::Outrage]             = 0
    @effects[PBEffects::ParentalBond]        = 0
    @effects[PBEffects::PickupItem]          = 0
    @effects[PBEffects::PickupUse]           = 0
    @effects[PBEffects::Pinch]               = false
    @effects[PBEffects::PoisonArrow]         = 0 # new effect
    @effects[PBEffects::Powder]              = false
    @effects[PBEffects::Prankster]           = false
    @effects[PBEffects::PriorityAbility]     = false
    @effects[PBEffects::PriorityItem]        = false
    @effects[PBEffects::Protect]             = false
    @effects[PBEffects::ProtectRate]         = 1
    @effects[PBEffects::Pursuit]             = false
    @effects[PBEffects::Quash]               = 0
    @effects[PBEffects::Rage]                = false
    @effects[PBEffects::RagePowder]          = false
    @effects[PBEffects::Revenge]             = 0
    @effects[PBEffects::Rollout]             = 0
    @effects[PBEffects::Roost]               = false
    @effects[PBEffects::SkyDrop]             = -1
    @battle.eachBattler do |b|   # Other battlers no longer Sky Dropped by self
      b.effects[PBEffects::SkyDrop] = -1 if b.effects[PBEffects::SkyDrop][email protected]
    end
    @effects[PBEffects::SlowStart]           = 0
    @effects[PBEffects::SmackDown]           = false
    @effects[PBEffects::Snatch]              = 0
    @effects[PBEffects::SpikyShield]         = false
    @effects[PBEffects::Spotlight]           = 0
    @effects[PBEffects::Stockpile]           = 0
    @effects[PBEffects::StockpileDef]        = 0
    @effects[PBEffects::StockpileSpDef]      = 0
    @effects[PBEffects::Taunt]               = 0
    @effects[PBEffects::ThroatChop]          = 0
    @effects[PBEffects::Torment]             = false
    @effects[PBEffects::Toxic]               = 0
    @effects[PBEffects::Transform]           = false
    @effects[PBEffects::TransformSpecies]    = 0
    @effects[PBEffects::Trapping]            = 0
    @effects[PBEffects::TrappingMove]        = 0
    @effects[PBEffects::TrappingUser]        = -1
    @battle.eachBattler do |b|   # Other battlers no longer trapped by self
      next if b.effects[PBEffects::TrappingUser][email protected]
      b.effects[PBEffects::Trapping]     = 0
      b.effects[PBEffects::TrappingUser] = -1
    end
    @effects[PBEffects::Truant]              = false
    @effects[PBEffects::TwoTurnAttack]       = 0
    @effects[PBEffects::Type3]               = -1
    @effects[PBEffects::Unburden]            = false
    @effects[PBEffects::Uproar]              = 0
    @effects[PBEffects::WaterSport]          = false
    @effects[PBEffects::WeightChange]        = 0
    @effects[PBEffects::Yawn]                = 0
  end
Script Battler_Statuses:
  # after def pbCanBurnSynchronize?
  def pbCanBurnBlazeArrow?
    return false if self.status!=PBStatuses::NONE
    if affectedByTerrain?
      return false if @battle.field.terrain==PBBattleTerrains::Misty
    end
    if BattleHandlers.triggerStatusImmunityAbilityNonIgnorable(@ability,self,PBStatuses::BURN)
      return false
    end
    if abilityActive? && BattleHandlers.triggerStatusImmunityAbility(@ability,self,PBStatuses::BURN)
      return false
    end
    eachAlly do |b|
      next if !b.abilityActive?
      next if !BattleHandlers.triggerStatusImmunityAllyAbility(b.ability,self,PBStatuses::BURN)
      return false
    end
    return false if pbOwnSide.effects[PBEffects::Safeguard]>0
    return true
  end

  # after def pbCanPoisonSynchronize?
  def pbCanPoisonPoisonArrow?
    return false if self.status!=PBStatuses::NONE
    if affectedByTerrain?
      return false if @battle.field.terrain==PBBattleTerrains::Misty
    end
    if BattleHandlers.triggerStatusImmunityAbilityNonIgnorable(@ability,self,PBStatuses::POISON)
      return false
    end
    if abilityActive? && BattleHandlers.triggerStatusImmunityAbility(@ability,self,PBStatuses::POISON)
      return false
    end
    eachAlly do |b|
      next if !b.abilityActive?
      next if !BattleHandlers.triggerStatusImmunityAllyAbility(b.ability,self,PBStatuses::POISON)
      return false
    end
    return false if pbOwnSide.effects[PBEffects::Safeguard]>0
    return true
  end
In Battle_Phase_EndOfRound:
    # Yawn
    pbEORCountDownBattlerEffect(priority,PBEffects::Yawn) { |battler|
      if battler.pbCanSleepYawn?
        PBDebug.log("[Lingering effect] #{battler.pbThis} fell asleep because of Yawn")
        battler.pbSleep
      end
    }
    # Blaze Arrow
    pbEORCountDownBattlerEffect(priority,PBEffects::BlazeArrow) { |battler|
      if battler.pbCanBurnBlazeArrow?
        PBDebug.log("[Lingering effect] #{battler.pbThis} got burned because of Blaze Arrow")
        battler.pbBurn
      end
    }
    # Poison Arrow
    pbEORCountDownBattlerEffect(priority,PBEffects::PoisonArrow) { |battler|
      if battler.pbCanPoisonPoisonArrow?
        PBDebug.log("[Lingering effect] #{battler.pbThis} got badly poisoned because of Poison Arrow")
        battler.pbPoison(nil,nil,true)
      end
    }
It might also be a good idea when introducing new function codes to include them in the script AI_Move_EffectScores so that a skilled AI can decide better whether to use those moves or not.