• Do not use Discord to host any images you post, these links expire quickly! You can learn how to add images to your posts here.
  • Eevee Expo's webhost has been having technical issues since Nov. 20th and you might be unable to connect to our site. Staff are also facing issues connecting, so please send a DM to Cat on-site or through Discord directly for faster service!

Released Ability that affects ally's speed or deploys Tailwind (PEv20.1)

This project has a release available. The full version is still a work in progress.

Desperado

Novice
Member
Joined
Jan 22, 2024
Posts
14
Here's the code for an ability that deploys Tailwind when the ability user enters battle:
Battle::AbilityEffects::OnSwitchIn.add(:COMPANION,
proc { |ability, battler, battle, switch_in|
battle.pbShowAbilitySplash(battler)
battler.pbOwnSide.effects[PBEffects::Tailwind] = 3
battle.pbDisplay(_INTL("A wind blows to your back!"))
battle.pbHideAbilitySplash(battler)
}
)

As a bonus, here's the code for an ability that activates Magnet Rise on the ability user upon entering battle:
Battle::AbilityEffects::OnSwitchIn.add(:CONVERGENCE,
proc { |ability, battler, battle, switch_in|
battle.pbShowAbilitySplash(battler)
battler.effects[PBEffects::MagnetRise] = 2
battle.pbDisplay(_INTL("Magnetism causes the user to hover!"))
battle.pbHideAbilitySplash(battler)
}
)

I'm using Pokémon Essentials v20.1. I'm trying to create at least one of two ability effects. If one of them is too complicated or difficult to create, I'm fine with only using the other. If neither is possible, I'll come up with something different to use in my project.

I'm not very knowledgeable on programming in general but I've been making some simple move and ability effects by copying and slightly revising effects that already exist, such as variations of Lightning Rod (redirect single target move of specified type to self + user gets a boost to one stat) where one ability has several components with different locations in the script editor to make the ability work correctly.

I've also created abilities that combine aspects of multiple different simple abilities, such as Wonder Skin (affects all foes) with Heatproof (mults[:base_damage_multiplier] /= 2 if type == :FIRE) with Friend Guard (DamageCalcFromTargetAlly) to create abilities that cut in half the base power of all foes' moves of a certain type when dealing damage to either the ability user or the user's ally.

The first ability effect I want to create is similar to Sand Rush, but instead of multiplying the speed of the ability user, would multiply the speed of the user's allies. If I want this ability to also multiply the user's speed I could simply copy the code for Sand Rush and change the ability tag.

I've attempted to create this ability by searching for instances of "AccuracyCalcFromAlly" from Victory Star and trying to replicate it with "SpeedCalcFromAlly" under instances of "SpeedCalc" (for the ability user). Here's what I added:

First addition: [[ Battle ]] > [[ Battler ]] > Battle_Battler > line 248:
Ruby:
Expand Collapse Copy
    if abilityActive?
      speedMult = Battle::AbilityEffects.triggerSpeedCalc(self.ability, self, speedMult)
    end
# Below is what I wrote:
    user.allAllies.each do |b|
      next if !b.abilityActive?
      Battle::AbilityEffects.triggerSpeedCalcFromAlly(
        b.ability, modifiers, user, target, self, @calcType
      )
    end 
# Below this continues with "if itemActive?"
# When I try to test the ability I gave this effect, I think the error message that pops up is caused with this first part.
Second addition: [[ Battle ]] > [[ Other battle code ]] > Battle_AbilityEffects > line 5:
Ruby:
Expand Collapse Copy
  SpeedCalc                        = AbilityHandlerHash.new
# Below is what I wrote:
  SpeedCalcFromAlly                = AbilityHandlerHash.new
# Below this is "WeightCalc"
Third addition: [[ Battle ]] > [[ Other battle code ]] > Battle_AbilityEffects > line 78:
Ruby:
Expand Collapse Copy
  def self.triggerSpeedCalc(ability, battler, mult)
    return trigger(SpeedCalc, ability, battler, mult, ret: mult)
  end
# Below is what I wrote:
  def self.triggerSpeedCalcFromAlly(ability, mods, user, target, move, type)
    SpeedCalcFromAlly.trigger(ability, mods, user, target, move, type)
  end
# Below this continues with "def self.triggerWeightCalc"
Fourth addition: [[ Battle ]] > [[ Other battle code ]] > Battle_AbilityEffects > at the bottom where my custom abilities are:
Ruby:
Expand Collapse Copy
# Companion is the name of the ability.
Battle::AbilityEffects::SpeedCalcFromAlly.add(:COMPANION,
  proc { |ability, battler, mult|
    next mult *= 1.5
  }
)
Those are the only places I've added or changed anything involving this ability effect.

When I'm using the Pokémon with this ability in my party against a trainer while running the game through debug mode, here's the error message:
[Pokémon Essentials version 20.1]
[v20.1 Hotfixes 1.0.7]
[EBDX v1.4.2 (E20)]

Script error in event 85 (coords 50,3), map 32 (Developer Room)
Exception: NameError
Message: undefined local variable or method `user' for #<Battle::Battler>

***Full script:
TrainerBattle.start(:BIKER,"Test One")
Backtrace:
160:Battle_Battler:252:in `pbSpeed'
150:Battle_ActionAttacksPriority:152:in `block in pbCalculatePriority'
150:Battle_ActionAttacksPriority:147:in `each'
150:Battle_ActionAttacksPriority:147:in `pbCalculatePriority'
151:Battle_ActionSwitching:303:in `pbOnAllBattlersEnteringBattle'
148:Battle_StartAndEnd:312:in `pbStartBattleCore'
148:Battle_StartAndEnd:270:in `pbStartBattle'
242:Overworld_BattleStarting:513:in `block (2 levels) in start_core'
[Elite Battle: DX] Scene Battle.rb:437:in `pbSceneStandby'
242:Overworld_BattleStarting:512:in `block in start_core'
I don't know how to fix this since I'm not simply copying pre-existing functions.

This should be a lot easier to create. I thought it already existed, but apparently not for PE v20.1. The idea is to have an ability that deploys Tailwind, Magnet Rise, Light Screen, or similar effects when the ability user enters battle.

My first attempt at creating this ability was to copy code from another fangame, Pokémon Pathways, for a custom created ability that sets up gravity when the user enters battle:
Ruby:
Expand Collapse Copy
BattleHandlers::AbilityOnSwitchIn.add(:GRAVITYSURGE,
  proc { |ability,battler,battle|
    next if battle.field.effects[PBEffects::Gravity]>0
    battle.pbShowAbilitySplash(battler)
    battler.hasActiveItem?(:GRAVITYEXTENDER) ? battle.field.effects[PBEffects::Gravity] = 8 : battle.field.effects[PBEffects::Gravity] = 5
    battle.pbDisplay(_INTL("Gravity intensified!"))
    battle.eachBattler do |b|
   
      if b.effects[PBEffects::MagnetRise]>0 || b.effects[PBEffects::Telekinesis]>0 || b.effects[PBEffects::SkyDrop]>=0
        b.effects[PBEffects::MagnetRise]  = 0
        b.effects[PBEffects::Telekinesis] = 0
        b.effects[PBEffects::SkyDrop]     = -1
      end
   
      if b.inTwoTurnAttack?("0C9","0CC","0CE")   # Fly/Bounce/Sky Drop
        b.effects[PBEffects::TwoTurnAttack] = nil
        battle.pbClearChoice(b.index) if !b.movedThisRound?
      elsif b.airborne?
        battle.pbDisplay(_INTL("{1} couldn't stay airborne because of gravity!", b.pbThis)) if showMessage
      end
   
    end
 
    battle.pbHideAbilitySplash(battler)
  }
)
What I did first while trying to create a Tailwind version of this ability is trim out the "if" branches related to gravity, then change the tag from PBEffects::Gravity to PBEffects::Tailwind.

Ruby:
Expand Collapse Copy
BattleHandlers::AbilityOnSwitchIn.add(:COMPANION,
  proc { |ability,battler,battle|
    next if battle.field.effects[PBEffects::Tailwind]>0
    battle.pbShowAbilitySplash(battler)
 battle.field.effects[PBEffects::Tailwind] = 5
    battle.pbDisplay(_INTL("A wind blows to your back!"))
    battle.eachBattler do |b|
   
    end
 
    battle.pbHideAbilitySplash(battler)
  }
)
This one didn't work so I edited the setup a bit to more closely resemble the formatting of other abilities:
Ruby:
Expand Collapse Copy
Battle::AbilityEffects::OnSwitchIn.add(:COMPANION,
  proc { |ability,battler,battle|
    next if battle.field.effects[PBEffects::Tailwind]>0
    battle.pbShowAbilitySplash(battler)
 battle.field.effects[PBEffects::Tailwind] = 5
    battle.pbDisplay(_INTL("A wind blows to your back!"))
    battle.eachBattler do |b|
   
    end
 
    battle.pbHideAbilitySplash(battler)
  }
)
When I test this one the text pops up but the effect doesn't activate. It was hard to test so I tried making a nearly identical version with Magnet Rise, which should cause the ability user to temporarily evade ground-type moves:

Ruby:
Expand Collapse Copy
Battle::AbilityEffects::OnSwitchIn.add(:CONVERGENCE,
  proc { |ability,battler,battle|
    next if battle.field.effects[PBEffects::MagnetRise]>0
    battle.pbShowAbilitySplash(battler)
 battle.field.effects[PBEffects::MagnetRise] = 5
    battle.pbDisplay(_INTL("Magnetism causes the user to hover!"))
    battle.eachBattler do |b|
   
    end
 
    battle.pbHideAbilitySplash(battler)
  }
)
With this ability, I test it with a double battle where the ally of the ability user which doesn't have an ability that would ignore anything (such as Moldbreaker) uses a ground type attack on the ability user. The text appears upon the ability user entering the field. The ally's ground type attack still hits the supposedly hovering ability user.

Unlike my attempts with the first ability effect that passively boosts ally speed, I think my issue with these abilities that deploy Tailwind or similar effects is something as simple as using correct formatting with the line:

"next if battle.field.effects[PBEffects::Tailwind]>0"
Thanks in advance for any help.
 
Last edited:

Penelope

Trainer
Member
Joined
Sep 15, 2023
Posts
94
1.
Ruby:
Expand Collapse Copy
# Below is what I wrote:
allAllies.each do |b|
  next unless b.abilityActive?
  speedMult = Battle::AbilityEffects.triggerSpeedCalcFromAlly(b.ability, b, self, speedMult)
end

# Below is what I wrote:
def self.triggerSpeedCalcFromAlly(ability, battler, ally, mult)
  return trigger(SpeedCalcFromAlly, ability, battler, ally, mult, ret: mult)
end

Battle::AbilityEffects::SpeedCalcFromAlly.add(:COMPANION,
  proc { |ability, battler, ally, mult|
    next mult *= 1.5
  }
)
Untested.

2.Tailwind is a side effect, not a field effect.
 

Desperado

Novice
Member
Joined
Jan 22, 2024
Posts
14
1.
Ruby:
Expand Collapse Copy
# Below is what I wrote:
allAllies.each do |b|
  next unless b.abilityActive?
  speedMult = Battle::AbilityEffects.triggerSpeedCalcFromAlly(b.ability, b, self, speedMult)
end

# Below is what I wrote:
def self.triggerSpeedCalcFromAlly(ability, battler, ally, mult)
  return trigger(SpeedCalcFromAlly, ability, battler, ally, mult, ret: mult)
end

Battle::AbilityEffects::SpeedCalcFromAlly.add(:COMPANION,
  proc { |ability, battler, ally, mult|
    next mult *= 1.5
  }
)
Untested.

2.Tailwind is a side effect, not a field effect.
Where do I put that code? Do I insert it where the many other things have been placed, or simply at the bottom of the abilities page? Also, what do you think of the many different lines I wrote trying to define "SpeedCalcFromAlly"?

For Tailwind I'll try again, looking at the code for the move Tailwind and revising it again. First I look at the code for the move Tailwind located at:
[[ Battle ]] > [[ Move ]] > MoveEffects_BattlerStats > lines 1888~1906
Ruby:
Expand Collapse Copy
class Battle::Move::StartUserSideDoubleSpeed < Battle::Move
  def canSnatch?; return true; end

  def pbMoveFailed?(user, targets)
    if [B]user.pbOwnSide.effects[/B][PBEffects::Tailwind] > 0
      @battle.pbDisplay(_INTL("But it failed!"))
      return true
    end
    return false
  end

  def pbEffectGeneral(user)
    [B]user.pbOwnSide.effects[/B][PBEffects::Tailwind] = 4
    @battle.pbDisplay(_INTL("The Tailwind blew from behind {1}!", user.pbTeam(true)))
  end
end
In the code I've been trying to write, I think I recognize the problem now. I'll replace battle.field.effects with user.pbOwnSide.effects and have a separate ability for deploying Tailwind apart from the ability that passively multiplies the ally's speed.

I'll also try that with the ability I've been trying to make that deploys Magnet Rise on the user, but that one needs user.effects instead.

I'm not sure what the user.pbTeam(true) part does for Tailwind as a move but since it's in the displayed text I assume I don't need it.

I overwrote what I had in the first, third, and fourth additions with your code. I don't get an error message from that. I'm getting the same error message as before:

[Pokémon Essentials version 20.1]
[v20.1 Hotfixes 1.0.7]
[EBDX v1.4.2 (E20)]

Script error in event 85 (coords 50,3), map 32 (Developer Room)
Exception: NameError
Message: undefined local variable or method `user' for #<Battle::Battler>

***Full script:
TrainerBattle.start(:BIKER,"Test Two")
Backtrace:
160:Battle_Battler:254:in `pbSpeed'
150:Battle_ActionAttacksPriority:152:in `block in pbCalculatePriority'
150:Battle_ActionAttacksPriority:147:in `each'
150:Battle_ActionAttacksPriority:147:in `pbCalculatePriority'
151:Battle_ActionSwitching:303:in `pbOnAllBattlersEnteringBattle'
148:Battle_StartAndEnd:312:in `pbStartBattleCore'
148:Battle_StartAndEnd:270:in `pbStartBattle'
242:Overworld_BattleStarting:513:in `block (2 levels) in start_core'
[Elite Battle: DX] Scene Battle.rb:437:in `pbSceneStandby'
242:Overworld_BattleStarting:512:in `block in start_core'
This happens regardless of the Pokémon used by either the player or the opponent and their abilities.
 
Last edited:

Desperado

Novice
Member
Joined
Jan 22, 2024
Posts
14
A little update: I've negated the lines for passively modifying the ally's speed. I'm giving up on that for now. I'm adding more to this thread in case I can get more help or if I possibly succeed with any of this.

I've been adjusting the code for the ability that deploys Tailwind, but every adjustment results gives a different error. Below is the best I've been able to make so far, along with the latest error message:
Ruby:
Expand Collapse Copy
Battle::AbilityEffects::OnSwitchIn.add(:COMPANION,
  proc { |ability, battler, battle, switch_in|
    battle.pbShowAbilitySplash(battler)
 user.pbOwnSide.effects[PBEffects::Tailwind] = 3
    battle.pbDisplay(_INTL("A wind blows to your back!"))
    battle.pbHideAbilitySplash(battler)
  }
)
Ruby:
Expand Collapse Copy
[Pokémon Essentials version 20.1]
[v20.1 Hotfixes 1.0.7]
[EBDX v1.4.2 (E20)]

Script error in event 85 (coords 50,3), map 32 (Developer Room)
Exception: NameError
Message: undefined local variable or method `user' for nil:NilClass

***Full script:
TrainerBattle.start(:BIKER,"Test Two")
Backtrace:
215:Battle_AbilityEffects:3754:in `block in <main>'
035:Event_Handlers:227:in `trigger'
215:Battle_AbilityEffects:275:in `triggerOnSwitchIn'
151:Battle_ActionSwitching:352:in `block in pbOnBattlerEnteringBattle'
151:Battle_ActionSwitching:331:in `each'
151:Battle_ActionSwitching:331:in `pbOnBattlerEnteringBattle'
151:Battle_ActionSwitching:306:in `pbOnAllBattlersEnteringBattle'
148:Battle_StartAndEnd:312:in `pbStartBattleCore'
148:Battle_StartAndEnd:270:in `pbStartBattle'
242:Overworld_BattleStarting:513:in `block (2 levels) in start_core'
Line 3754 is the one with user.pbOwnSide.effects[PBEffects::Tailwind] = 3 which I recognize the first line of the backtrace indicates.
I'm stubborn on making this ability that deploys Tailwind at least, so I'll keep working on it and share my work in progress here in case anyone else can either help or make use of what I've been able to do so far.
First I'll use the code for Sandstorm (move) compared to Sand Stream.
Ruby:
Expand Collapse Copy
#code for sandstorm (move)
class Battle::Move::StartSandstormWeather < Battle::Move::WeatherMove
  def initialize(battle, move)
    super
    @weatherType = :Sandstorm
  end
end

#code for sand stream (ability)
Battle::AbilityEffects::OnSwitchIn.add(:SANDSTREAM,
  proc { |ability, battler, battle, switch_in|
    battle.[B]pbStartWeatherAbility[/B](:Sandstorm, battler)
  }
)
When I search for pbStartWeatherAbility in the rest of the scripts, aside from other moves and abilities that initiate weather, here's what I found:
Ruby:
Expand Collapse Copy
  def pbStartWeatherAbility(new_weather, battler, ignore_primal = false)
    return if !ignore_primal && [:HarshSun, :HeavyRain, :StrongWinds].include?(@field.weather)
    return if @field.weather == new_weather
    pbShowAbilitySplash(battler)
    if !Scene::USE_ABILITY_SPLASH
      pbDisplay(_INTL("{1}'s {2} activated!", battler.pbThis, battler.abilityName))
    end
    fixed_duration = false
    fixed_duration = true if Settings::FIXED_DURATION_WEATHER_FROM_ABILITY &&
                             ![:HarshSun, :HeavyRain, :StrongWinds].include?(new_weather)
    pbStartWeather(battler, new_weather, fixed_duration)
    # NOTE: The ability splash is hidden again in def pbStartWeather.
  end

I'll also look at the code for Tailwind (move) to see if I'm missing an important line:
Ruby:
Expand Collapse Copy
class Battle::Move::StartUserSideDoubleSpeed < Battle::Move
  def canSnatch?; return true; end

  def pbMoveFailed?(user, targets)
    if user.pbOwnSide.effects[PBEffects::Tailwind] > 0
      @battle.pbDisplay(_INTL("But it failed!"))
      return true
    end
    return false
  end

  def pbEffectGeneral(user)
    user.pbOwnSide.effects[PBEffects::Tailwind] = 4
    @battle.pbDisplay(_INTL("The Tailwind blew from behind {1}!", user.pbTeam(true)))
  end
end
There's three def components that each conclude with end but I don't think I'll need the first two since you can't snatch an ability and I don't anticipate previous use of the move Tailwind before this ability user is on the field. The part I'm worried about is def pbEffectGeneral(user), especially the pbEffectGeneral since that is very similar to pbStartWeatherAbility which seems to handle how the effect is activated.

Here's the latest version in my attempts to create this ability:
Ruby:
Expand Collapse Copy
Battle::AbilityEffects::OnSwitchIn.add(:COMPANION,
  proc { |ability, battler, battle, switch_in|
    battle.pbShowAbilitySplash(battler)
  def pbEffectGeneral(user)
    user.pbOwnSide.effects[PBEffects::Tailwind] = 3
    battle.pbDisplay(_INTL("A wind blows to your back!")) 
  end
  battle.pbHideAbilitySplash(battler)
  }
)
This is the first version in my many attempts where no error message occurs, but the Tailwind doesn't activate and the "A wind blows to your back!" doesn't display. Instead what happens is that upon entry the ability user shows the ability splash with the Pokémon's name and ability very briefly and disappears.

I'm not sure if def pbEffectGeneral(user) is correct to use for activating an effect through an ability.
 

Penelope

Trainer
Member
Joined
Sep 15, 2023
Posts
94
about the best version you've made, why don't you change "user" to "battler"?
the error log has already told you the "user" is the problem.
there isn't an argument called "user".
 

Desperado

Novice
Member
Joined
Jan 22, 2024
Posts
14
about the best version you've made, why don't you change "user" to "battler"?
the error log has already told you the "user" is the problem.
there isn't an argument called "user".
I reverted the later changes I made and tried that. I tested it and I think it works. The text finally pops up correctly.
I set up a test 2v2 battle where I have one Pokémon with this ability, one that's slower than everything else on the field, and two opponents that are both faster than my slower Pokémon. My slower Pokémon ends up being faster than both opponents. The duration of tailwind ends with the displayed message of being petered out, as well as my slower Pokémon being slower than both opponents. In this test battle everything only has +0 priority moves.

There's no errors, crashes, or any apparent problems. I think we solved it. Here's the code for the ability:

Battle::AbilityEffects::OnSwitchIn.add(:COMPANION,
proc { |ability, battler, battle, switch_in|
battle.pbShowAbilitySplash(battler)
battler.pbOwnSide.effects[PBEffects::Tailwind] = 3
battle.pbDisplay(_INTL("A wind blows to your back!"))
battle.pbHideAbilitySplash(battler)
}
)

I'll use this to work on more abilities with similar effects. Thanks for your help. I'd like to also be able to set up abilities that modify the speed of Pokémon on the field other than the ability-user, but for now I'll stick with this.

Bonus: I made functional code for Magnet Rise to deploy on entry from an ability. Not directly related to the topic, but I wanted to share it. I tested it to make sure it works correctly.
Battle::AbilityEffects::OnSwitchIn.add(:CONVERGENCE,
proc { |ability, battler, battle, switch_in|
battle.pbShowAbilitySplash(battler)
battler.effects[PBEffects::MagnetRise] = 2
battle.pbDisplay(_INTL("Magnetism causes the user to hover!"))
battle.pbHideAbilitySplash(battler)
}
)
I was having trouble with the "battler.effects[PBEffects" line because I thought there had to be a different term between battler and effects.
 
Last edited:
Back
Top