mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-10 14:44:58 +00:00
Rearranged some script files
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
class PokeBattle_Move
|
||||
attr_reader :battle
|
||||
attr_reader :realMove
|
||||
attr_accessor :id
|
||||
attr_reader :name
|
||||
attr_reader :function
|
||||
attr_reader :baseDamage
|
||||
attr_reader :type
|
||||
attr_reader :category
|
||||
attr_reader :accuracy
|
||||
attr_accessor :pp
|
||||
attr_writer :totalpp
|
||||
attr_reader :addlEffect
|
||||
attr_reader :target
|
||||
attr_reader :priority
|
||||
attr_reader :flags
|
||||
attr_accessor :calcType
|
||||
attr_accessor :powerBoost
|
||||
attr_accessor :snatched
|
||||
|
||||
def to_int; return @id; end
|
||||
|
||||
#=============================================================================
|
||||
# Creating a move
|
||||
#=============================================================================
|
||||
def initialize(battle,move)
|
||||
@battle = battle
|
||||
@realMove = move
|
||||
@id = move.id
|
||||
@name = PBMoves.getName(@id) # Get the move's name
|
||||
# Get data on the move
|
||||
moveData = pbGetMoveData(@id)
|
||||
@function = moveData[MOVE_FUNCTION_CODE]
|
||||
@baseDamage = moveData[MOVE_BASE_DAMAGE]
|
||||
@type = moveData[MOVE_TYPE]
|
||||
@category = moveData[MOVE_CATEGORY]
|
||||
@accuracy = moveData[MOVE_ACCURACY]
|
||||
@pp = move.pp # Can be changed with Mimic/Transform
|
||||
@addlEffect = moveData[MOVE_EFFECT_CHANCE]
|
||||
@target = moveData[MOVE_TARGET]
|
||||
@priority = moveData[MOVE_PRIORITY]
|
||||
@flags = moveData[MOVE_FLAGS]
|
||||
@calcType = -1
|
||||
@powerBoost = false # For Aerilate, Pixilate, Refrigerate, Galvanize
|
||||
@snatched = false
|
||||
end
|
||||
|
||||
# This is the code actually used to generate a PokeBattle_Move object. The
|
||||
# object generated is a subclass of this one which depends on the move's
|
||||
# function code (found in the script section PokeBattle_MoveEffect).
|
||||
def PokeBattle_Move.pbFromPBMove(battle,move)
|
||||
move = PBMove.new(0) if !move
|
||||
moveFunction = pbGetMoveData(move.id,MOVE_FUNCTION_CODE) || "000"
|
||||
className = sprintf("PokeBattle_Move_%s",moveFunction)
|
||||
if Object.const_defined?(className)
|
||||
return Object.const_get(className).new(battle,move)
|
||||
end
|
||||
return PokeBattle_UnimplementedMove.new(battle,move)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# About the move
|
||||
#=============================================================================
|
||||
def pbTarget(user); return @target; end
|
||||
|
||||
def totalpp
|
||||
return @totalpp if @totalpp && @totalpp>0 # Usually undefined
|
||||
return @realMove.totalpp if @realMove
|
||||
return 0
|
||||
end
|
||||
|
||||
# NOTE: This method is only ever called while using a move (and also by the
|
||||
# AI), so using @calcType here is acceptable.
|
||||
def physicalMove?(thisType=nil)
|
||||
return (@category==0) if MOVE_CATEGORY_PER_MOVE
|
||||
thisType ||= @calcType if @calcType>=0
|
||||
thisType = @type if !thisType
|
||||
return !PBTypes.isSpecialType?(thisType)
|
||||
end
|
||||
|
||||
# NOTE: This method is only ever called while using a move (and also by the
|
||||
# AI), so using @calcType here is acceptable.
|
||||
def specialMove?(thisType=nil)
|
||||
return (@category==1) if MOVE_CATEGORY_PER_MOVE
|
||||
thisType ||= @calcType if @calcType>=0
|
||||
thisType = @type if !thisType
|
||||
return PBTypes.isSpecialType?(thisType)
|
||||
end
|
||||
|
||||
def damagingMove?; return @category!=2; end
|
||||
def statusMove?; return @category==2; end
|
||||
|
||||
def usableWhenAsleep?; return false; end
|
||||
def unusableInGravity?; return false; end
|
||||
def healingMove?; return false; end
|
||||
def recoilMove?; return false; end
|
||||
def flinchingMove?; return false; end
|
||||
def callsAnotherMove?; return false; end
|
||||
# Whether the move can/will hit more than once in the same turn (including
|
||||
# Beat Up which may instead hit just once). Not the same as pbNumHits>1.
|
||||
def multiHitMove?; return false; end
|
||||
def chargingTurnMove?; return false; end
|
||||
def successCheckPerHit?; return false; end
|
||||
def hitsFlyingTargets?; return false; end
|
||||
def hitsDiggingTargets?; return false; end
|
||||
def hitsDivingTargets?; return false; end
|
||||
def ignoresReflect?; return false; end # For Brick Break
|
||||
def cannotRedirect?; return false; end # For Future Sight/Doom Desire
|
||||
def worksWithNoTargets?; return false; end # For Explosion
|
||||
def damageReducedByBurn?; return true; end # For Facade
|
||||
def triggersHyperMode?; return false; end
|
||||
|
||||
def contactMove?; return @flags[/a/]; end
|
||||
def canProtectAgainst?; return @flags[/b/]; end
|
||||
def canMagicCoat?; return @flags[/c/]; end
|
||||
def canSnatch?; return @flags[/d/]; end
|
||||
def canMirrorMove?; return @flags[/e/]; end
|
||||
def canKingsRock?; return @flags[/f/]; end
|
||||
def thawsUser?; return @flags[/g/]; end
|
||||
def highCriticalRate?; return @flags[/h/]; end
|
||||
def bitingMove?; return @flags[/i/]; end
|
||||
def punchingMove?; return @flags[/j/]; end
|
||||
def soundMove?; return @flags[/k/]; end
|
||||
def powderMove?; return @flags[/l/]; end
|
||||
def pulseMove?; return @flags[/m/]; end
|
||||
def bombMove?; return @flags[/n/]; end
|
||||
def danceMove?; return @flags[/o/]; end
|
||||
|
||||
# Causes perfect accuracy (param=1) and double damage (param=2).
|
||||
def tramplesMinimize?(param=1); return false; end
|
||||
def nonLethal?(user,target); return false; end # For False Swipe
|
||||
|
||||
def ignoresSubstitute?(user) # user is the Pokémon using this move
|
||||
if NEWEST_BATTLE_MECHANICS
|
||||
return true if soundMove?
|
||||
return true if user && user.hasActiveAbility?(:INFILTRATOR)
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -1,350 +0,0 @@
|
||||
class PokeBattle_Move
|
||||
#=============================================================================
|
||||
# Effect methods per move usage
|
||||
#=============================================================================
|
||||
def pbCanChooseMove?(user,commandPhase,showMessages); return true; end # For Belch
|
||||
def pbDisplayChargeMessage(user); end # For Focus Punch/shell Trap/Beak Blast
|
||||
def pbOnStartUse(user,targets); end
|
||||
def pbAddTarget(targets,user); end # For Counter, etc. and Bide
|
||||
|
||||
# Reset move usage counters (child classes can increment them).
|
||||
def pbChangeUsageCounters(user,specialUsage)
|
||||
user.effects[PBEffects::FuryCutter] = 0
|
||||
user.effects[PBEffects::ParentalBond] = 0
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.field.effects[PBEffects::FusionBolt] = false
|
||||
@battle.field.effects[PBEffects::FusionFlare] = false
|
||||
end
|
||||
|
||||
def pbDisplayUseMessage(user)
|
||||
@battle.pbDisplayBrief(_INTL("{1} used {2}!",user.pbThis,@name))
|
||||
end
|
||||
|
||||
def pbMissMessage(user,target); return false; end
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
#=============================================================================
|
||||
# Whether the move is currently in the "charging" turn of a two turn attack.
|
||||
# Is false if Power Herb or another effect lets a two turn move charge and
|
||||
# attack in the same turn.
|
||||
# user.effects[PBEffects::TwoTurnAttack] is set to the move's ID during the
|
||||
# charging turn, and is 0 during the attack turn.
|
||||
def pbIsChargingTurn?(user); return false; end
|
||||
def pbDamagingMove?; return damagingMove?; end
|
||||
|
||||
def pbContactMove?(user)
|
||||
return false if user.hasActiveAbility?(:LONGREACH)
|
||||
return contactMove?
|
||||
end
|
||||
|
||||
# The maximum number of hits in a round this move will actually perform. This
|
||||
# can be 1 for Beat Up, and can be 2 for any moves affected by Parental Bond.
|
||||
def pbNumHits(user,targets)
|
||||
if user.hasActiveAbility?(:PARENTALBOND) && pbDamagingMove? &&
|
||||
!chargingTurnMove? && targets.length==1
|
||||
# Record that Parental Bond applies, to weaken the second attack
|
||||
user.effects[PBEffects::ParentalBond] = 3
|
||||
return 2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Effect methods per hit
|
||||
#=============================================================================
|
||||
def pbOverrideSuccessCheckPerHit(user,target); return false; end
|
||||
def pbCrashDamage(user); end
|
||||
def pbInitialEffect(user,targets,hitNum); end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
return if !showAnimation
|
||||
if user.effects[PBEffects::ParentalBond]==1
|
||||
@battle.pbCommonAnimation("ParentalBond",user,targets)
|
||||
else
|
||||
@battle.pbAnimation(id,user,targets,hitNum)
|
||||
end
|
||||
end
|
||||
|
||||
def pbSelfKO(user); end
|
||||
def pbEffectWhenDealingDamage(user,target); end
|
||||
def pbEffectAgainstTarget(user,target); end
|
||||
def pbEffectGeneral(user); end
|
||||
def pbAdditionalEffect(user,target); end
|
||||
def pbEffectAfterAllHits(user,target); end # Move effects that occur after all hits
|
||||
def pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers); end
|
||||
def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers); end
|
||||
|
||||
#=============================================================================
|
||||
# Check if target is immune to the move because of its ability
|
||||
#=============================================================================
|
||||
def pbImmunityByAbility(user,target)
|
||||
return false if @battle.moldBreaker
|
||||
ret = false
|
||||
if target.abilityActive?
|
||||
ret = BattleHandlers.triggerMoveImmunityTargetAbility(target.ability,
|
||||
user,target,self,@calcType,@battle)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Move failure checks
|
||||
#=============================================================================
|
||||
# Check whether the move fails completely due to move-specific requirements.
|
||||
def pbMoveFailed?(user,targets); return false; end
|
||||
# Checks whether the move will be ineffective against the target.
|
||||
def pbFailsAgainstTarget?(user,target); return false; end
|
||||
|
||||
def pbMoveFailedLastInRound?(user)
|
||||
unmoved = false
|
||||
@battle.eachBattler do |b|
|
||||
next if b.index==user.index
|
||||
next if @battle.choices[b.index][0]!=:UseMove && @battle.choices[b.index][0]!=:Shift
|
||||
next if b.movedThisRound?
|
||||
unmoved = true
|
||||
break
|
||||
end
|
||||
if !unmoved
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbMoveFailedTargetAlreadyMoved?(target)
|
||||
if (@battle.choices[target.index][0]!=:UseMove &&
|
||||
@battle.choices[target.index][0]!=:Shift) || target.movedThisRound?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbMoveFailedAromaVeil?(user,target,showMessage=true)
|
||||
return false if @battle.moldBreaker
|
||||
if target.hasActiveAbility?(:AROMAVEIL)
|
||||
if showMessage
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!",
|
||||
target.pbThis,target.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
target.eachAlly do |b|
|
||||
next if !b.hasActiveAbility?(:AROMAVEIL)
|
||||
if showMessage
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} is unaffected because of {2}'s {3}!",
|
||||
target.pbThis,b.pbThis(true),b.abilityName))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Weaken the damage dealt (doesn't actually change a battler's HP)
|
||||
#=============================================================================
|
||||
def pbCheckDamageAbsorption(user,target)
|
||||
# Substitute will take the damage
|
||||
if target.effects[PBEffects::Substitute]>0 && !ignoresSubstitute?(user) &&
|
||||
(!user || user.index!=target.index)
|
||||
target.damageState.substitute = true
|
||||
return
|
||||
end
|
||||
# Disguise will take the damage
|
||||
if !@battle.moldBreaker && isConst?(target.species,PBSpecies,:MIMIKYU) &&
|
||||
target.form==0 && isConst?(target.ability,PBAbilities,:DISGUISE)
|
||||
target.damageState.disguise = true
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def pbReduceDamage(user,target)
|
||||
damage = target.damageState.calcDamage
|
||||
# Substitute takes the damage
|
||||
if target.damageState.substitute
|
||||
damage = target.effects[PBEffects::Substitute] if damage>target.effects[PBEffects::Substitute]
|
||||
target.damageState.hpLost = damage
|
||||
target.damageState.totalHPLost += damage
|
||||
return
|
||||
end
|
||||
# Disguise takes the damage
|
||||
return if target.damageState.disguise
|
||||
# Target takes the damage
|
||||
if damage>=target.hp
|
||||
damage = target.hp
|
||||
# Survive a lethal hit with 1 HP effects
|
||||
if nonLethal?(user,target)
|
||||
damage -= 1
|
||||
elsif target.effects[PBEffects::Endure]
|
||||
target.damageState.endured = true
|
||||
damage -= 1
|
||||
elsif damage==target.totalhp
|
||||
if target.hasActiveAbility?(:STURDY) && !@battle.moldBreaker
|
||||
target.damageState.sturdy = true
|
||||
damage -= 1
|
||||
elsif target.hasActiveItem?(:FOCUSSASH) && target.hp==target.totalhp
|
||||
target.damageState.focusSash = true
|
||||
damage -= 1
|
||||
elsif target.hasActiveItem?(:FOCUSBAND) && @battle.pbRandom(100)<10
|
||||
target.damageState.focusBand = true
|
||||
damage -= 1
|
||||
end
|
||||
end
|
||||
end
|
||||
damage = 0 if damage<0
|
||||
target.damageState.hpLost = damage
|
||||
target.damageState.totalHPLost += damage
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Change the target's HP by the amount calculated above
|
||||
#=============================================================================
|
||||
def pbInflictHPDamage(target)
|
||||
if target.damageState.substitute
|
||||
target.effects[PBEffects::Substitute] -= target.damageState.hpLost
|
||||
else
|
||||
target.hp -= target.damageState.hpLost
|
||||
end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Animate the damage dealt, including lowering the HP
|
||||
#=============================================================================
|
||||
# Animate being damaged and losing HP (by a move)
|
||||
def pbAnimateHitAndHPLost(user,targets)
|
||||
# Animate allies first, then foes
|
||||
animArray = []
|
||||
for side in 0...2 # side here means "allies first, then foes"
|
||||
targets.each do |b|
|
||||
next if b.damageState.unaffected || b.damageState.hpLost==0
|
||||
next if (side==0 && b.opposes?(user)) || (side==1 && !b.opposes?(user))
|
||||
oldHP = b.hp+b.damageState.hpLost
|
||||
PBDebug.log("[Move damage] #{b.pbThis} lost #{b.damageState.hpLost} HP (#{oldHP}=>#{b.hp})")
|
||||
effectiveness = 0
|
||||
if PBTypes.resistant?(b.damageState.typeMod); effectiveness = 1
|
||||
elsif PBTypes.superEffective?(b.damageState.typeMod); effectiveness = 2
|
||||
end
|
||||
animArray.push([b,oldHP,effectiveness])
|
||||
end
|
||||
if animArray.length>0
|
||||
@battle.scene.pbHitAndHPLossAnimation(animArray)
|
||||
animArray.clear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Messages upon being hit
|
||||
#=============================================================================
|
||||
def pbEffectivenessMessage(user,target,numTargets=1)
|
||||
return if target.damageState.disguise
|
||||
if PBTypes.superEffective?(target.damageState.typeMod)
|
||||
if numTargets>1
|
||||
@battle.pbDisplay(_INTL("It's super effective on {1}!",target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("It's super effective!"))
|
||||
end
|
||||
elsif PBTypes.notVeryEffective?(target.damageState.typeMod)
|
||||
if numTargets>1
|
||||
@battle.pbDisplay(_INTL("It's not very effective on {1}...",target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("It's not very effective..."))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbHitEffectivenessMessages(user,target,numTargets=1)
|
||||
return if target.damageState.disguise
|
||||
if target.damageState.substitute
|
||||
@battle.pbDisplay(_INTL("The substitute took damage for {1}!",target.pbThis(true)))
|
||||
end
|
||||
if target.damageState.critical
|
||||
if numTargets>1
|
||||
@battle.pbDisplay(_INTL("A critical hit on {1}!",target.pbThis(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("A critical hit!"))
|
||||
end
|
||||
end
|
||||
# Effectiveness message, for moves with 1 hit
|
||||
if !multiHitMove? && user.effects[PBEffects::ParentalBond]==0
|
||||
pbEffectivenessMessage(user,target,numTargets)
|
||||
end
|
||||
if target.damageState.substitute && target.effects[PBEffects::Substitute]==0
|
||||
target.effects[PBEffects::Substitute] = 0
|
||||
@battle.pbDisplay(_INTL("{1}'s substitute faded!",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
def pbEndureKOMessage(target)
|
||||
if target.damageState.disguise
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("Its disguise served it as a decoy!"))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1}'s disguise served it as a decoy!",target.pbThis))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
target.pbChangeForm(1,_INTL("{1}'s disguise was busted!",target.pbThis))
|
||||
elsif target.damageState.endured
|
||||
@battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis))
|
||||
elsif target.damageState.sturdy
|
||||
@battle.pbShowAbilitySplash(target)
|
||||
if PokeBattle_SceneConstants::USE_ABILITY_SPLASH
|
||||
@battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} hung on with Sturdy!",target.pbThis))
|
||||
end
|
||||
@battle.pbHideAbilitySplash(target)
|
||||
elsif target.damageState.focusSash
|
||||
@battle.pbCommonAnimation("UseItem",target)
|
||||
@battle.pbDisplay(_INTL("{1} hung on using its Focus Sash!",target.pbThis))
|
||||
target.pbConsumeItem
|
||||
elsif target.damageState.focusBand
|
||||
@battle.pbCommonAnimation("UseItem",target)
|
||||
@battle.pbDisplay(_INTL("{1} hung on using its Focus Band!",target.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
# Used by Counter/Mirror Coat/Metal Burst/Revenge/Focus Punch/Bide/Assurance.
|
||||
def pbRecordDamageLost(user,target)
|
||||
damage = target.damageState.hpLost
|
||||
# NOTE: In Gen 3 where a move's category depends on its type, Hidden Power
|
||||
# is for some reason countered by Counter rather than Mirror Coat,
|
||||
# regardless of its calculated type. Hence the following two lines of
|
||||
# code.
|
||||
moveType = nil
|
||||
moveType = getID(PBTypes,:NORMAL) if @function=="090" # Hidden Power
|
||||
if physicalMove?(moveType)
|
||||
target.effects[PBEffects::Counter] = damage
|
||||
target.effects[PBEffects::CounterTarget] = user.index
|
||||
elsif specialMove?(moveType)
|
||||
target.effects[PBEffects::MirrorCoat] = damage
|
||||
target.effects[PBEffects::MirrorCoatTarget] = user.index
|
||||
end
|
||||
if target.effects[PBEffects::Bide]>0
|
||||
target.effects[PBEffects::BideDamage] += damage
|
||||
target.effects[PBEffects::BideTarget] = user.index
|
||||
end
|
||||
target.damageState.fainted = true if target.fainted?
|
||||
target.lastHPLost = damage # For Focus Punch
|
||||
target.tookDamage = true if damage>0 # For Assurance
|
||||
target.lastAttacker.push(user.index) # For Revenge
|
||||
if target.opposes?(user)
|
||||
target.lastHPLostFromFoe = damage # For Metal Burst
|
||||
target.lastFoeAttacker.push(user.index) # For Metal Burst
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,491 +0,0 @@
|
||||
class PokeBattle_Move
|
||||
#=============================================================================
|
||||
# Move's type calculation
|
||||
#=============================================================================
|
||||
def pbBaseType(user)
|
||||
ret = @type
|
||||
return ret if !ret || ret<0
|
||||
if user.abilityActive?
|
||||
ret = BattleHandlers.triggerMoveBaseTypeModifierAbility(user.ability,user,self,ret)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbCalcType(user)
|
||||
@powerBoost = false
|
||||
ret = pbBaseType(user)
|
||||
return ret if !ret || ret<0
|
||||
if hasConst?(PBTypes,:ELECTRIC)
|
||||
if @battle.field.effects[PBEffects::IonDeluge] && isConst?(ret,PBTypes,:NORMAL)
|
||||
ret = getConst(PBTypes,:ELECTRIC)
|
||||
@powerBoost = false
|
||||
end
|
||||
if user.effects[PBEffects::Electrify]
|
||||
ret = getConst(PBTypes,:ELECTRIC)
|
||||
@powerBoost = false
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Type effectiveness calculation
|
||||
#=============================================================================
|
||||
def pbCalcTypeModSingle(moveType,defType,user,target)
|
||||
ret = PBTypes.getEffectiveness(moveType,defType)
|
||||
# Ring Target
|
||||
if target.hasActiveItem?(:RINGTARGET)
|
||||
ret = PBTypeEffectiveness::NORMAL_EFFECTIVE_ONE if PBTypes.ineffective?(moveType,defType)
|
||||
end
|
||||
# Foresight
|
||||
if user.hasActiveAbility?(:SCRAPPY) || target.effects[PBEffects::Foresight]
|
||||
ret = PBTypeEffectiveness::NORMAL_EFFECTIVE_ONE if isConst?(defType,PBTypes,:GHOST) &&
|
||||
PBTypes.ineffective?(moveType,defType)
|
||||
end
|
||||
# Miracle Eye
|
||||
if target.effects[PBEffects::MiracleEye]
|
||||
ret = PBTypeEffectiveness::NORMAL_EFFECTIVE_ONE if isConst?(defType,PBTypes,:DARK) &&
|
||||
PBTypes.ineffective?(moveType,defType)
|
||||
end
|
||||
# Delta Stream's weather
|
||||
if @battle.pbWeather==PBWeather::StrongWinds
|
||||
ret = PBTypeEffectiveness::NORMAL_EFFECTIVE_ONE if isConst?(defType,PBTypes,:FLYING) &&
|
||||
PBTypes.superEffective?(moveType,defType)
|
||||
end
|
||||
# Grounded Flying-type Pokémon become susceptible to Ground moves
|
||||
if !target.airborne?
|
||||
ret = PBTypeEffectiveness::NORMAL_EFFECTIVE_ONE if isConst?(defType,PBTypes,:FLYING) &&
|
||||
isConst?(moveType,PBTypes,:GROUND)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbCalcTypeMod(moveType,user,target)
|
||||
return PBTypeEffectiveness::NORMAL_EFFECTIVE if moveType<0
|
||||
return PBTypeEffectiveness::NORMAL_EFFECTIVE if isConst?(moveType,PBTypes,:GROUND) &&
|
||||
target.pbHasType?(:FLYING) && target.hasActiveItem?(:IRONBALL)
|
||||
# Determine types
|
||||
tTypes = target.pbTypes(true)
|
||||
# Get effectivenesses
|
||||
typeMods = [PBTypeEffectiveness::NORMAL_EFFECTIVE_ONE] * 3 # 3 types max
|
||||
tTypes.each_with_index do |type,i|
|
||||
typeMods[i] = pbCalcTypeModSingle(moveType,type,user,target)
|
||||
end
|
||||
# Multiply all effectivenesses together
|
||||
ret = 1
|
||||
typeMods.each { |m| ret *= m }
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Accuracy check
|
||||
#=============================================================================
|
||||
def pbBaseAccuracy(user,target); return @accuracy; end
|
||||
|
||||
# Accuracy calculations for one-hit KO moves and "always hit" moves are
|
||||
# handled elsewhere.
|
||||
def pbAccuracyCheck(user,target)
|
||||
# "Always hit" effects and "always hit" accuracy
|
||||
return true if target.effects[PBEffects::Telekinesis]>0
|
||||
return true if target.effects[PBEffects::Minimize] && tramplesMinimize?(1)
|
||||
baseAcc = pbBaseAccuracy(user,target)
|
||||
return true if baseAcc==0
|
||||
# Calculate all multiplier effects
|
||||
modifiers = []
|
||||
modifiers[BASE_ACC] = baseAcc
|
||||
modifiers[ACC_STAGE] = user.stages[PBStats::ACCURACY]
|
||||
modifiers[EVA_STAGE] = target.stages[PBStats::EVASION]
|
||||
modifiers[ACC_MULT] = 0x1000
|
||||
modifiers[EVA_MULT] = 0x1000
|
||||
pbCalcAccuracyModifiers(user,target,modifiers)
|
||||
# Check if move can't miss
|
||||
return true if modifiers[BASE_ACC]==0
|
||||
# Calculation
|
||||
accStage = [[modifiers[ACC_STAGE],-6].max,6].min + 6
|
||||
evaStage = [[modifiers[EVA_STAGE],-6].max,6].min + 6
|
||||
stageMul = [3,3,3,3,3,3, 3, 4,5,6,7,8,9]
|
||||
stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3]
|
||||
accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage]
|
||||
evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage]
|
||||
accuracy = (accuracy * modifiers[ACC_MULT] / 0x1000).round
|
||||
evasion = (evasion * modifiers[EVA_MULT] / 0x1000).round
|
||||
evasion = 1 if evasion<1
|
||||
# Calculation
|
||||
return @battle.pbRandom(100) < modifiers[BASE_ACC] * accuracy / evasion
|
||||
end
|
||||
|
||||
def pbCalcAccuracyModifiers(user,target,modifiers)
|
||||
# Ability effects that alter accuracy calculation
|
||||
if user.abilityActive?
|
||||
BattleHandlers.triggerAccuracyCalcUserAbility(user.ability,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
user.eachAlly do |b|
|
||||
next if !b.abilityActive?
|
||||
BattleHandlers.triggerAccuracyCalcUserAllyAbility(b.ability,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
if target.abilityActive? && !@battle.moldBreaker
|
||||
BattleHandlers.triggerAccuracyCalcTargetAbility(target.ability,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
# Item effects that alter accuracy calculation
|
||||
if user.itemActive?
|
||||
BattleHandlers.triggerAccuracyCalcUserItem(user.item,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
if target.itemActive?
|
||||
BattleHandlers.triggerAccuracyCalcTargetItem(target.item,
|
||||
modifiers,user,target,self,@calcType)
|
||||
end
|
||||
# Other effects, inc. ones that set ACC_MULT or EVA_STAGE to specific values
|
||||
if @battle.field.effects[PBEffects::Gravity]>0
|
||||
modifiers[ACC_MULT] = (modifiers[ACC_MULT]*5/3).round
|
||||
end
|
||||
if user.effects[PBEffects::MicleBerry]
|
||||
user.effects[PBEffects::MicleBerry] = false
|
||||
modifiers[ACC_MULT] = (modifiers[ACC_MULT]*1.2).round
|
||||
end
|
||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::Foresight] && modifiers[EVA_STAGE]>0
|
||||
modifiers[EVA_STAGE] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[EVA_STAGE]>0
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Critical hit check
|
||||
#=============================================================================
|
||||
# Return values:
|
||||
# -1: Never a critical hit.
|
||||
# 0: Calculate normally.
|
||||
# 1: Always a critical hit.
|
||||
def pbCritialOverride(user,target); return 0; end
|
||||
|
||||
# Returns whether the move will be a critical hit.
|
||||
def pbIsCritical?(user,target)
|
||||
return false if target.pbOwnSide.effects[PBEffects::LuckyChant]>0
|
||||
# Set up the critical hit ratios
|
||||
ratios = (NEWEST_BATTLE_MECHANICS) ? [24,8,2,1] : [16,8,4,3,2]
|
||||
c = 0
|
||||
# Ability effects that alter critical hit rate
|
||||
if c>=0 && user.abilityActive?
|
||||
c = BattleHandlers.triggerCriticalCalcUserAbility(user.ability,user,target,c)
|
||||
end
|
||||
if c>=0 && target.abilityActive? && !@battle.moldBreaker
|
||||
c = BattleHandlers.triggerCriticalCalcTargetAbility(target.ability,user,target,c)
|
||||
end
|
||||
# Item effects that alter critical hit rate
|
||||
if c>=0 && user.itemActive?
|
||||
c = BattleHandlers.triggerCriticalCalcUserItem(user.item,user,target,c)
|
||||
end
|
||||
if c>=0 && target.itemActive?
|
||||
c = BattleHandlers.triggerCriticalCalcTargetItem(target.item,user,target,c)
|
||||
end
|
||||
return false if c<0
|
||||
# Move-specific "always/never a critical hit" effects
|
||||
case pbCritialOverride(user,target)
|
||||
when 1; return true
|
||||
when -1; return false
|
||||
end
|
||||
# Other effects
|
||||
return true if c>50 # Merciless
|
||||
return true if user.effects[PBEffects::LaserFocus]>0
|
||||
c += 1 if highCriticalRate?
|
||||
c += user.effects[PBEffects::FocusEnergy]
|
||||
c += 1 if user.inHyperMode? && isConst?(@type,PBTypes,:SHADOW)
|
||||
c = ratios.length-1 if c>=ratios.length
|
||||
# Calculation
|
||||
return @battle.pbRandom(ratios[c])==0
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Damage calculation
|
||||
#=============================================================================
|
||||
def pbBaseDamage(baseDmg,user,target); return baseDmg; end
|
||||
def pbBaseDamageMultiplier(damageMult,user,target); return damageMult; end
|
||||
def pbModifyDamage(damageMult,user,target); return damageMult; end
|
||||
|
||||
def pbGetAttackStats(user,target)
|
||||
if specialMove?
|
||||
return user.spatk, user.stages[PBStats::SPATK]+6
|
||||
end
|
||||
return user.attack, user.stages[PBStats::ATTACK]+6
|
||||
end
|
||||
|
||||
def pbGetDefenseStats(user,target)
|
||||
if specialMove?
|
||||
return target.spdef, target.stages[PBStats::SPDEF]+6
|
||||
end
|
||||
return target.defense, target.stages[PBStats::DEFENSE]+6
|
||||
end
|
||||
|
||||
def pbCalcDamage(user,target,numTargets=1)
|
||||
return if statusMove?
|
||||
if target.damageState.disguise
|
||||
target.damageState.calcDamage = 1
|
||||
return
|
||||
end
|
||||
stageMul = [2,2,2,2,2,2, 2, 3,4,5,6,7,8]
|
||||
stageDiv = [8,7,6,5,4,3, 2, 2,2,2,2,2,2]
|
||||
# Get the move's type
|
||||
type = @calcType # -1 is treated as physical
|
||||
# Calculate whether this hit deals critical damage
|
||||
target.damageState.critical = pbIsCritical?(user,target)
|
||||
# Calcuate base power of move
|
||||
baseDmg = pbBaseDamage(@baseDamage,user,target)
|
||||
# Calculate user's attack stat
|
||||
atk, atkStage = pbGetAttackStats(user,target)
|
||||
if !target.hasActiveAbility?(:UNAWARE) || @battle.moldBreaker
|
||||
atkStage = 6 if target.damageState.critical && atkStage<6
|
||||
atk = (atk.to_f*stageMul[atkStage]/stageDiv[atkStage]).floor
|
||||
end
|
||||
# Calculate target's defense stat
|
||||
defense, defStage = pbGetDefenseStats(user,target)
|
||||
if !user.hasActiveAbility?(:UNAWARE)
|
||||
defStage = 6 if target.damageState.critical && defStage>6
|
||||
defense = (defense.to_f*stageMul[defStage]/stageDiv[defStage]).floor
|
||||
end
|
||||
# Calculate all multiplier effects
|
||||
multipliers = [0x1000,0x1000,0x1000,0x1000]
|
||||
pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers)
|
||||
# Main damage calculation
|
||||
baseDmg = [(baseDmg * multipliers[BASE_DMG_MULT] / 0x1000).round,1].max
|
||||
atk = [(atk * multipliers[ATK_MULT] / 0x1000).round,1].max
|
||||
defense = [(defense * multipliers[DEF_MULT] / 0x1000).round,1].max
|
||||
damage = (((2.0*user.level/5+2).floor*baseDmg*atk/defense).floor/50).floor+2
|
||||
damage = [(damage * multipliers[FINAL_DMG_MULT] / 0x1000).round,1].max
|
||||
target.damageState.calcDamage = damage
|
||||
end
|
||||
|
||||
def pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers)
|
||||
# Global abilities
|
||||
if (@battle.pbCheckGlobalAbility(:DARKAURA) && isConst?(type,PBTypes,:DARK)) ||
|
||||
(@battle.pbCheckGlobalAbility(:FAIRYAURA) && isConst?(type,PBTypes,:FAIRY))
|
||||
if @battle.pbCheckGlobalAbility(:AURABREAK)
|
||||
multipliers[BASE_DMG_MULT] *= 2/3.0
|
||||
else
|
||||
multipliers[BASE_DMG_MULT] *= 4/3.0
|
||||
end
|
||||
end
|
||||
# Ability effects that alter damage
|
||||
if user.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcUserAbility(user.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
if !@battle.moldBreaker
|
||||
# NOTE: It's odd that the user's Mold Breaker prevents its partner's
|
||||
# beneficial abilities (i.e. Flower Gift boosting Atk), but that's
|
||||
# how it works.
|
||||
user.eachAlly do |b|
|
||||
next if !b.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcUserAllyAbility(b.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
if target.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcTargetAbility(target.ability,
|
||||
user,target,self,multipliers,baseDmg,type) if !@battle.moldBreaker
|
||||
BattleHandlers.triggerDamageCalcTargetAbilityNonIgnorable(target.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
target.eachAlly do |b|
|
||||
next if !b.abilityActive?
|
||||
BattleHandlers.triggerDamageCalcTargetAllyAbility(b.ability,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
end
|
||||
# Item effects that alter damage
|
||||
if user.itemActive?
|
||||
BattleHandlers.triggerDamageCalcUserItem(user.item,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
if target.itemActive?
|
||||
BattleHandlers.triggerDamageCalcTargetItem(target.item,
|
||||
user,target,self,multipliers,baseDmg,type)
|
||||
end
|
||||
# Parental Bond's second attack
|
||||
if user.effects[PBEffects::ParentalBond]==1
|
||||
multipliers[BASE_DMG_MULT] /= 4
|
||||
end
|
||||
# Other
|
||||
if user.effects[PBEffects::MeFirst]
|
||||
multipliers[BASE_DMG_MULT] = (multipliers[BASE_DMG_MULT]*1.5).round
|
||||
end
|
||||
if user.effects[PBEffects::HelpingHand] && !self.is_a?(PokeBattle_Confusion)
|
||||
multipliers[BASE_DMG_MULT] = (multipliers[BASE_DMG_MULT]*1.5).round
|
||||
end
|
||||
if user.effects[PBEffects::Charge]>0 && isConst?(type,PBTypes,:ELECTRIC)
|
||||
multipliers[BASE_DMG_MULT] *= 2
|
||||
end
|
||||
# Mud Sport
|
||||
if isConst?(type,PBTypes,:ELECTRIC)
|
||||
@battle.eachBattler do |b|
|
||||
next if !b.effects[PBEffects::MudSport]
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
break
|
||||
end
|
||||
if @battle.field.effects[PBEffects::MudSportField]>0
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
end
|
||||
end
|
||||
# Water Sport
|
||||
if isConst?(type,PBTypes,:FIRE)
|
||||
@battle.eachBattler do |b|
|
||||
next if !b.effects[PBEffects::WaterSport]
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
break
|
||||
end
|
||||
if @battle.field.effects[PBEffects::WaterSportField]>0
|
||||
multipliers[BASE_DMG_MULT] /= 3
|
||||
end
|
||||
end
|
||||
# Terrain moves
|
||||
if user.affectedByTerrain?
|
||||
case @battle.field.terrain
|
||||
when PBBattleTerrains::Electric
|
||||
if isConst?(type,PBTypes,:ELECTRIC)
|
||||
multipliers[BASE_DMG_MULT] = (multipliers[BASE_DMG_MULT]*1.5).round
|
||||
end
|
||||
when PBBattleTerrains::Grassy
|
||||
if isConst?(type,PBTypes,:GRASS)
|
||||
multipliers[BASE_DMG_MULT] = (multipliers[BASE_DMG_MULT]*1.5).round
|
||||
end
|
||||
when PBBattleTerrains::Psychic
|
||||
if isConst?(type,PBTypes,:PSYCHIC)
|
||||
multipliers[BASE_DMG_MULT] = (multipliers[BASE_DMG_MULT]*1.5).round
|
||||
end
|
||||
end
|
||||
end
|
||||
if @battle.field.terrain==PBBattleTerrains::Misty && target.affectedByTerrain? &&
|
||||
isConst?(type,PBTypes,:DRAGON)
|
||||
multipliers[BASE_DMG_MULT] /= 2
|
||||
end
|
||||
# Badge multipliers
|
||||
if @battle.internalBattle
|
||||
if user.pbOwnedByPlayer?
|
||||
if physicalMove? && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_ATTACK
|
||||
multipliers[ATK_MULT] = (multipliers[ATK_MULT]*1.1).round
|
||||
elsif specialMove? && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_SPATK
|
||||
multipliers[ATK_MULT] = (multipliers[ATK_MULT]*1.1).round
|
||||
end
|
||||
end
|
||||
if target.pbOwnedByPlayer?
|
||||
if physicalMove? && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_DEFENSE
|
||||
multipliers[DEF_MULT] = (multipliers[DEF_MULT]*1.1).round
|
||||
elsif specialMove? && @battle.pbPlayer.numbadges>=NUM_BADGES_BOOST_SPDEF
|
||||
multipliers[DEF_MULT] = (multipliers[DEF_MULT]*1.1).round
|
||||
end
|
||||
end
|
||||
end
|
||||
# Multi-targeting attacks
|
||||
if numTargets>1
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*0.75).round
|
||||
end
|
||||
# Weather
|
||||
case @battle.pbWeather
|
||||
when PBWeather::Sun, PBWeather::HarshSun
|
||||
if isConst?(type,PBTypes,:FIRE)
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*1.5).round
|
||||
elsif isConst?(type,PBTypes,:WATER)
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
end
|
||||
when PBWeather::Rain, PBWeather::HeavyRain
|
||||
if isConst?(type,PBTypes,:FIRE)
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
elsif isConst?(type,PBTypes,:WATER)
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*1.5).round
|
||||
end
|
||||
when PBWeather::Sandstorm
|
||||
if target.pbHasType?(:ROCK) && specialMove? && @function!="122" # Psyshock
|
||||
multipliers[DEF_MULT] = (multipliers[DEF_MULT]*1.5).round
|
||||
end
|
||||
end
|
||||
# Critical hits
|
||||
if target.damageState.critical
|
||||
if NEWEST_BATTLE_MECHANICS
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*1.5).round
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
end
|
||||
end
|
||||
# Random variance
|
||||
if !self.is_a?(PokeBattle_Confusion)
|
||||
random = 85+@battle.pbRandom(16)
|
||||
multipliers[FINAL_DMG_MULT] *= random/100.0
|
||||
end
|
||||
# STAB
|
||||
if type>=0 && user.pbHasType?(type)
|
||||
if user.hasActiveAbility?(:ADAPTABILITY)
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*1.5).round
|
||||
end
|
||||
end
|
||||
# Type effectiveness
|
||||
multipliers[FINAL_DMG_MULT] *= target.damageState.typeMod.to_f/PBTypeEffectiveness::NORMAL_EFFECTIVE
|
||||
multipliers[FINAL_DMG_MULT] = multipliers[FINAL_DMG_MULT].round
|
||||
# Burn
|
||||
if user.status==PBStatuses::BURN && physicalMove? && damageReducedByBurn? &&
|
||||
!user.hasActiveAbility?(:GUTS)
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
end
|
||||
# Aurora Veil, Reflect, Light Screen
|
||||
if !ignoresReflect? && !target.damageState.critical &&
|
||||
!user.hasActiveAbility?(:INFILTRATOR)
|
||||
if target.pbOwnSide.effects[PBEffects::AuroraVeil]>0
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*2/3).round
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::Reflect]>0 && physicalMove?
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*2/3).round
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
end
|
||||
elsif target.pbOwnSide.effects[PBEffects::LightScreen]>0 && specialMove?
|
||||
if @battle.pbSideBattlerCount(target)>1
|
||||
multipliers[FINAL_DMG_MULT] = (multipliers[FINAL_DMG_MULT]*2/3).round
|
||||
else
|
||||
multipliers[FINAL_DMG_MULT] /= 2
|
||||
end
|
||||
end
|
||||
end
|
||||
# Minimize
|
||||
if target.effects[PBEffects::Minimize] && tramplesMinimize?(2)
|
||||
multipliers[FINAL_DMG_MULT] *= 2
|
||||
end
|
||||
# Move-specific base damage modifiers
|
||||
multipliers[BASE_DMG_MULT] = pbBaseDamageMultiplier(multipliers[BASE_DMG_MULT],user,target)
|
||||
# Move-specific final damage modifiers
|
||||
multipliers[FINAL_DMG_MULT] = pbModifyDamage(multipliers[FINAL_DMG_MULT],user,target)
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Additional effect chance
|
||||
#=============================================================================
|
||||
def pbAdditionalEffectChance(user,target,effectChance=0)
|
||||
return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker
|
||||
ret = (effectChance>0) ? effectChance : @addlEffect
|
||||
if NEWEST_BATTLE_MECHANICS || @function!="0A4" # Secret Power
|
||||
ret *= 2 if user.hasActiveAbility?(:SERENEGRACE) ||
|
||||
user.pbOwnSide.effects[PBEffects::Rainbow]>0
|
||||
end
|
||||
ret = 100 if $DEBUG && Input.press?(Input::CTRL)
|
||||
return ret
|
||||
end
|
||||
|
||||
# NOTE: Flinching caused by a move's effect is applied in that move's code,
|
||||
# not here.
|
||||
def pbFlinchChance(user,target)
|
||||
return 0 if flinchingMove?
|
||||
return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker
|
||||
ret = 0
|
||||
if user.hasActiveAbility?(:STENCH,true)
|
||||
ret = 10
|
||||
elsif user.hasActiveItem?([:KINGSROCK,:RAZORFANG],true)
|
||||
ret = 10
|
||||
end
|
||||
ret *= 2 if user.hasActiveAbility?(:SERENEGRACE) ||
|
||||
user.pbOwnSide.effects[PBEffects::Rainbow]>0
|
||||
return ret
|
||||
end
|
||||
end
|
||||
@@ -1,714 +0,0 @@
|
||||
#===============================================================================
|
||||
# Superclass that handles moves using a non-existent function code.
|
||||
# Damaging moves just do damage with no additional effect.
|
||||
# Status moves always fail.
|
||||
#===============================================================================
|
||||
class PokeBattle_UnimplementedMove < PokeBattle_Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
if statusMove?
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Pseudomove for confusion damage.
|
||||
#===============================================================================
|
||||
class PokeBattle_Confusion < PokeBattle_Move
|
||||
def initialize(battle,move)
|
||||
@battle = battle
|
||||
@realMove = move
|
||||
@id = 0
|
||||
@name = ""
|
||||
@function = "000"
|
||||
@baseDamage = 40
|
||||
@type = -1
|
||||
@category = 0
|
||||
@accuracy = 100
|
||||
@pp = -1
|
||||
@target = 0
|
||||
@priority = 0
|
||||
@flags = ""
|
||||
@addlEffect = 0
|
||||
@calcType = -1
|
||||
@powerBoost = false
|
||||
@snatched = false
|
||||
end
|
||||
|
||||
def physicalMove?(thisType=nil); return true; end
|
||||
def specialMove?(thisType=nil); return false; end
|
||||
def pbCritialOverride(user,target); return -1; end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Implements the move Struggle.
|
||||
# For cases where the real move named Struggle is not defined.
|
||||
#===============================================================================
|
||||
class PokeBattle_Struggle < PokeBattle_Move
|
||||
def initialize(battle,move)
|
||||
@battle = battle
|
||||
@realMove = nil # Not associated with a move
|
||||
@id = (move) ? move.id : -1 # Doesn't work if 0
|
||||
@name = (move) ? PBMoves.getName(@id) : _INTL("Struggle")
|
||||
@function = "002"
|
||||
@baseDamage = 50
|
||||
@type = -1
|
||||
@category = 0
|
||||
@accuracy = 0
|
||||
@pp = -1
|
||||
@target = 0
|
||||
@priority = 0
|
||||
@flags = ""
|
||||
@addlEffect = 0
|
||||
@calcType = -1
|
||||
@powerBoost = false
|
||||
@snatched = false
|
||||
end
|
||||
|
||||
def physicalMove?(thisType=nil); return true; end
|
||||
def specialMove?(thisType=nil); return false; end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if target.damageState.unaffected
|
||||
user.pbReduceHP((user.totalhp/4.0).round,false)
|
||||
@battle.pbDisplay(_INTL("{1} is damaged by recoil!",user.pbThis))
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Generic status problem-inflicting classes.
|
||||
#===============================================================================
|
||||
class PokeBattle_SleepMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanSleep?(user,true,self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbSleep
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbSleep if target.pbCanSleep?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_PoisonMove < PokeBattle_Move
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@toxic = false
|
||||
end
|
||||
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanPoison?(user,true,self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbPoison(user,nil,@toxic)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbPoison(user,nil,@toxic) if target.pbCanPoison?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_ParalysisMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanParalyze?(user,true,self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbParalyze(user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbParalyze(user) if target.pbCanParalyze?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_BurnMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanBurn?(user,true,self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbBurn(user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbBurn(user) if target.pbCanBurn?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_FreezeMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanFreeze?(user,true,self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbFreeze
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbFreeze if target.pbCanFreeze?(user,false,self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Other problem-causing classes.
|
||||
#===============================================================================
|
||||
class PokeBattle_FlinchMove < PokeBattle_Move
|
||||
def flinchingMove?; return true; end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbFlinch(user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
target.pbFlinch(user)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_ConfuseMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanConfuse?(user,true,self)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbConfuse
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
return if !target.pbCanConfuse?(user,false,self)
|
||||
target.pbConfuse
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Generic user's stat increase/decrease classes.
|
||||
#===============================================================================
|
||||
class PokeBattle_StatUpMove < PokeBattle_Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
return false if damagingMove?
|
||||
return !user.pbCanRaiseStatStage?(@statUp[0],user,self,true)
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
return if damagingMove?
|
||||
user.pbRaiseStatStage(@statUp[0],@statUp[1],user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
if user.pbCanRaiseStatStage?(@statUp[0],user,self)
|
||||
user.pbRaiseStatStage(@statUp[0],@statUp[1],user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_MultiStatUpMove < PokeBattle_Move
|
||||
def pbMoveFailed?(user,targets)
|
||||
return false if damagingMove?
|
||||
failed = true
|
||||
for i in 0...@statUp.length/2
|
||||
next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self)
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
return if damagingMove?
|
||||
showAnim = true
|
||||
for i in 0...@statUp.length/2
|
||||
next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self)
|
||||
if user.pbRaiseStatStage(@statUp[i*2],@statUp[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
showAnim = true
|
||||
for i in 0...@statUp.length/2
|
||||
next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self)
|
||||
if user.pbRaiseStatStage(@statUp[i*2],@statUp[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_StatDownMove < PokeBattle_Move
|
||||
def pbEffectWhenDealingDamage(user,target)
|
||||
return if @battle.pbAllFainted?(target.idxOwnSide)
|
||||
showAnim = true
|
||||
for i in 0...@statDown.length/2
|
||||
next if !user.pbCanLowerStatStage?(@statDown[i*2],user,self)
|
||||
if user.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Generic target's stat increase/decrease classes.
|
||||
#===============================================================================
|
||||
class PokeBattle_TargetStatDownMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
return !target.pbCanLowerStatStage?(@statDown[0],user,self,true)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
target.pbLowerStatStage(@statDown[0],@statDown[1],user)
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
return if !target.pbCanLowerStatStage?(@statDown[0],user,self)
|
||||
target.pbLowerStatStage(@statDown[0],@statDown[1],user)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PokeBattle_TargetMultiStatDownMove < PokeBattle_Move
|
||||
def pbFailsAgainstTarget?(user,target)
|
||||
return false if damagingMove?
|
||||
failed = true
|
||||
for i in 0...@statDown.length/2
|
||||
next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self)
|
||||
failed = false
|
||||
break
|
||||
end
|
||||
if failed
|
||||
# NOTE: It's a bit of a faff to make sure the appropriate failure message
|
||||
# is shown here, I know.
|
||||
canLower = false
|
||||
if target.hasActiveAbility?(:CONTRARY) && !@battle.moldBreaker
|
||||
for i in 0...@statDown.length/2
|
||||
next if target.statStageAtMax?(@statDown[i*2])
|
||||
canLower = true
|
||||
break
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis)) if !canLower
|
||||
else
|
||||
for i in 0...@statDown.length/2
|
||||
next if target.statStageAtMin?(@statDown[i*2])
|
||||
canLower = true
|
||||
break
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1}'s stats won't go any lower!",user.pbThis)) if !canLower
|
||||
end
|
||||
if canLower
|
||||
target.pbCanLowerStatStage?(@statDown[0],user,self,true)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
return if damagingMove?
|
||||
showAnim = true
|
||||
for i in 0...@statDown.length/2
|
||||
next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self)
|
||||
if target.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbAdditionalEffect(user,target)
|
||||
return if target.damageState.substitute
|
||||
showAnim = true
|
||||
for i in 0...@statDown.length/2
|
||||
next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self)
|
||||
if target.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim)
|
||||
showAnim = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Fixed damage-inflicting move.
|
||||
#===============================================================================
|
||||
class PokeBattle_FixedDamageMove < PokeBattle_Move
|
||||
def pbFixedDamage(user,target); return 1; end
|
||||
|
||||
def pbCalcDamage(user,target,numTargets=1)
|
||||
target.damageState.critical = false
|
||||
target.damageState.calcDamage = pbFixedDamage(user,target)
|
||||
target.damageState.calcDamage = 1 if target.damageState.calcDamage<1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Two turn move.
|
||||
#===============================================================================
|
||||
class PokeBattle_TwoTurnMove < PokeBattle_Move
|
||||
def chargingTurnMove?; return true; end
|
||||
|
||||
# user.effects[PBEffects::TwoTurnAttack] is set to the move's ID if this
|
||||
# method returns true, or 0 if false.
|
||||
# Non-zero means the charging turn. 0 means the attacking turn.
|
||||
def pbIsChargingTurn?(user)
|
||||
@powerHerb = false
|
||||
@chargingTurn = false # Assume damaging turn by default
|
||||
@damagingTurn = true
|
||||
# 0 at start of charging turn, move's ID at start of damaging turn
|
||||
if user.effects[PBEffects::TwoTurnAttack]==0
|
||||
@powerHerb = user.hasActiveItem?(:POWERHERB)
|
||||
@chargingTurn = true
|
||||
@damagingTurn = @powerHerb
|
||||
end
|
||||
return !@damagingTurn # Deliberately not "return @chargingTurn"
|
||||
end
|
||||
|
||||
def pbDamagingMove? # Stops damage being dealt in the first (charging) turn
|
||||
return false if !@damagingTurn
|
||||
return super
|
||||
end
|
||||
|
||||
def pbAccuracyCheck(user,target)
|
||||
return true if !@damagingTurn
|
||||
return super
|
||||
end
|
||||
|
||||
def pbInitialEffect(user,targets,hitNum)
|
||||
pbChargingTurnMessage(user,targets) if @chargingTurn
|
||||
if @chargingTurn && @damagingTurn # Move only takes one turn to use
|
||||
pbShowAnimation(@id,user,targets,1) # Charging anim
|
||||
targets.each { |b| pbChargingTurnEffect(user,b) }
|
||||
if @powerHerb
|
||||
# Moves that would make the user semi-invulnerable will hide the user
|
||||
# after the charging animation, so the "UseItem" animation shouldn't show
|
||||
# for it
|
||||
if !["0C9","0CA","0CB","0CC","0CD","0CE","14D"].include?(@function)
|
||||
@battle.pbCommonAnimation("UseItem",user)
|
||||
end
|
||||
@battle.pbDisplay(_INTL("{1} became fully charged due to its Power Herb!",user.pbThis))
|
||||
user.pbConsumeItem
|
||||
end
|
||||
end
|
||||
pbAttackingTurnMessage(user,targets) if @damagingTurn
|
||||
end
|
||||
|
||||
def pbChargingTurnMessage(user,targets)
|
||||
@battle.pbDisplay(_INTL("{1} began charging up!",user.pbThis))
|
||||
end
|
||||
|
||||
def pbAttackingTurnMessage(user,targets)
|
||||
end
|
||||
|
||||
def pbChargingTurnEffect(user,target)
|
||||
# Skull Bash/Sky Drop are the only two-turn moves with an effect here, and
|
||||
# the latter just records the target is being Sky Dropped
|
||||
end
|
||||
|
||||
def pbAttackingTurnEffect(user,target)
|
||||
end
|
||||
|
||||
def pbEffectAgainstTarget(user,target)
|
||||
if @damagingTurn; pbAttackingTurnEffect(user,target)
|
||||
elsif @chargingTurn; pbChargingTurnEffect(user,target)
|
||||
end
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
hitNum = 1 if @chargingTurn && !@damagingTurn # Charging anim
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Healing move.
|
||||
#===============================================================================
|
||||
class PokeBattle_HealingMove < PokeBattle_Move
|
||||
def healingMove?; return true; end
|
||||
def pbHealAmount(user); return 1; end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if user.hp==user.totalhp
|
||||
@battle.pbDisplay(_INTL("{1}'s HP is full!",user.pbThis))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
amt = pbHealAmount(user)
|
||||
user.pbRecoverHP(amt)
|
||||
@battle.pbDisplay(_INTL("{1}'s HP was restored.",user.pbThis))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Recoil move.
|
||||
#===============================================================================
|
||||
class PokeBattle_RecoilMove < PokeBattle_Move
|
||||
def recoilMove?; return true; end
|
||||
def pbRecoilDamage(user,target); return 1; end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if target.damageState.unaffected
|
||||
return if !user.takesIndirectDamage?
|
||||
return if user.hasActiveAbility?(:ROCKHEAD)
|
||||
amt = pbRecoilDamage(user,target)
|
||||
amt = 1 if amt<1
|
||||
user.pbReduceHP(amt,false)
|
||||
@battle.pbDisplay(_INTL("{1} is damaged by recoil!",user.pbThis))
|
||||
user.pbItemHPHealCheck
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Protect move.
|
||||
#===============================================================================
|
||||
class PokeBattle_ProtectMove < PokeBattle_Move
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@sidedEffect = false
|
||||
end
|
||||
|
||||
def pbChangeUsageCounters(user,specialUsage)
|
||||
oldVal = user.effects[PBEffects::ProtectRate]
|
||||
super
|
||||
user.effects[PBEffects::ProtectRate] = oldVal
|
||||
end
|
||||
|
||||
def pbMoveFailed?(user,targets)
|
||||
if @sidedEffect
|
||||
if user.pbOwnSide.effects[@effect]
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
elsif user.effects[@effect]
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
if !(@sidedEffect && NEWEST_BATTLE_MECHANICS) &&
|
||||
user.effects[PBEffects::ProtectRate]>1 &&
|
||||
@battle.pbRandom(user.effects[PBEffects::ProtectRate])!=0
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
if pbMoveFailedLastInRound?(user)
|
||||
user.effects[PBEffects::ProtectRate] = 1
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
if @sidedEffect
|
||||
user.pbOwnSide.effects[@effect] = true
|
||||
else
|
||||
user.effects[@effect] = true
|
||||
end
|
||||
user.effects[PBEffects::ProtectRate] *= (NEWEST_BATTLE_MECHANICS) ? 3 : 2
|
||||
pbProtectMessage(user)
|
||||
end
|
||||
|
||||
def pbProtectMessage(user)
|
||||
if @sidedEffect
|
||||
@battle.pbDisplay(_INTL("{1} protected {2}!",@name,user.pbTeam(true)))
|
||||
else
|
||||
@battle.pbDisplay(_INTL("{1} protected itself!",user.pbThis))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Weather-inducing move.
|
||||
#===============================================================================
|
||||
class PokeBattle_WeatherMove < PokeBattle_Move
|
||||
def initialize(battle,move)
|
||||
super
|
||||
@weatherType = PBWeather::None
|
||||
end
|
||||
def pbMoveFailed?(user,targets)
|
||||
case @battle.field.weather
|
||||
when PBWeather::HarshSun
|
||||
@battle.pbDisplay(_INTL("The extremely harsh sunlight was not lessened at all!"))
|
||||
return true
|
||||
when PBWeather::HeavyRain
|
||||
@battle.pbDisplay(_INTL("There is no relief from this heavy rain!"))
|
||||
return true
|
||||
when PBWeather::StrongWinds
|
||||
@battle.pbDisplay(_INTL("The mysterious air current blows on regardless!"))
|
||||
return true
|
||||
when @weatherType
|
||||
@battle.pbDisplay(_INTL("But it failed!"))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
@battle.pbStartWeather(user,@weatherType,true,false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Pledge move.
|
||||
#===============================================================================
|
||||
class PokeBattle_PledgeMove < PokeBattle_Move
|
||||
def pbOnStartUse(user,targets)
|
||||
@pledgeSetup = false; @pledgeCombo = false; @pledgeOtherUser = nil
|
||||
@comboEffect = nil; @overrideType = nil; @overrideAnim = nil
|
||||
# Check whether this is the use of a combo move
|
||||
@combos.each do |i|
|
||||
next if i[0]!=user.effects[PBEffects::FirstPledge]
|
||||
@battle.pbDisplay(_INTL("The two moves have become one! It's a combined move!"))
|
||||
@pledgeCombo = true
|
||||
@comboEffect = i[1]; @overrideType = i[2]; @overrideAnim = i[3]
|
||||
break
|
||||
end
|
||||
return if @pledgeCombo
|
||||
# Check whether this is the setup of a combo move
|
||||
user.eachAlly do |b|
|
||||
next if @battle.choices[b.index][0]!=:UseMove || b.movedThisRound?
|
||||
move = @battle.choices[b.index][2]
|
||||
next if !move || move.id<=0
|
||||
@combos.each do |i|
|
||||
next if i[0]!=move.function
|
||||
@pledgeSetup = true
|
||||
@pledgeOtherUser = b
|
||||
break
|
||||
end
|
||||
break if @pledgeSetup
|
||||
end
|
||||
end
|
||||
|
||||
def pbDamagingMove?
|
||||
return false if @pledgeSetup
|
||||
return super
|
||||
end
|
||||
|
||||
def pbBaseType(user)
|
||||
return @overrideType if @overrideType!=nil
|
||||
return super
|
||||
end
|
||||
|
||||
def pbBaseDamage(baseDmg,user,target)
|
||||
baseDmg *= 2 if @pledgeCombo
|
||||
return baseDmg
|
||||
end
|
||||
|
||||
def pbEffectGeneral(user)
|
||||
user.effects[PBEffects::FirstPledge] = 0
|
||||
return if !@pledgeSetup
|
||||
@battle.pbDisplay(_INTL("{1} is waiting for {2}'s move...",
|
||||
user.pbThis,@pledgeOtherUser.pbThis(true)))
|
||||
@pledgeOtherUser.effects[PBEffects::FirstPledge] = @function
|
||||
@pledgeOtherUser.effects[PBEffects::MoveNext] = true
|
||||
user.lastMoveFailed = true # Treated as a failure for Stomping Tantrum
|
||||
end
|
||||
|
||||
def pbEffectAfterAllHits(user,target)
|
||||
return if !@pledgeCombo
|
||||
msg = nil; animName = nil
|
||||
case @comboEffect
|
||||
when :SeaOfFire # Grass + Fire
|
||||
if user.pbOpposingSide.effects[PBEffects::SeaOfFire]==0
|
||||
user.pbOpposingSide.effects[PBEffects::SeaOfFire] = 4
|
||||
msg = _INTL("A sea of fire enveloped {1}!",user.pbOpposingTeam(true))
|
||||
animName = (user.opposes?) ? "SeaOfFire" : "SeaOfFireOpp"
|
||||
end
|
||||
when :Rainbow # Fire + Water
|
||||
if user.pbOwnSide.effects[PBEffects::Rainbow]==0
|
||||
user.pbOwnSide.effects[PBEffects::Rainbow] = 4
|
||||
msg = _INTL("A rainbow appeared in the sky on {1}'s side!",user.pbTeam(true))
|
||||
animName = (user.opposes?) ? "RainbowOpp" : "Rainbow"
|
||||
end
|
||||
when :Swamp # Water + Grass
|
||||
if user.pbOpposingSide.effects[PBEffects::Swamp]==0
|
||||
user.pbOpposingSide.effects[PBEffects::Swamp] = 4
|
||||
msg = _INTL("A swamp enveloped {1}!",user.pbOpposingTeam(true))
|
||||
animName = (user.opposes?) ? "Swamp" : "SwampOpp"
|
||||
end
|
||||
end
|
||||
@battle.pbDisplay(msg) if msg
|
||||
@battle.pbCommonAnimation(animName) if animName
|
||||
end
|
||||
|
||||
def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true)
|
||||
return if @pledgeSetup # No animation for setting up
|
||||
id = @overrideAnim if @overrideAnim!=nil
|
||||
return super
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user