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

[Scripting Question] Simple (hopefully) scripts for some custom moves

29
Posts
6
Years
    • Seen Feb 8, 2024
    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!!
     
    188
    Posts
    9
    Years
    • Seen Jan 21, 2024
    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:
    Code:
    return super(attacker,opponent,hitnum,alltargets,showanimation) if @basedamage>0

    Move #1:
    Code:
    ################################################################################
    # 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:
    Code:
    ################################################################################
    # 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:
    Code:
    ################################################################################
    # 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:
    Code:
    ################################################################################
    # 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:
    Code:
    ################################################################################
    # 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:
    Code:
    ################################################################################
    # 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
     
    Last edited:
    29
    Posts
    6
    Years
    • Seen Feb 8, 2024
    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!
     
    188
    Posts
    9
    Years
    • Seen Jan 21, 2024
    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:
    Code:
    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:
    Code:
      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]==@index
        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 idxLastParty!=@pokemonIndex
            @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]!=@index
          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]==@index
        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]==@index
        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]!=@index
          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:
    Code:
      # 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:
    Code:
        # 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.
     
    Last edited:
    Back
    Top