diff --git a/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb b/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb index f64c1962c..3befdb8ae 100644 --- a/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb +++ b/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb @@ -228,6 +228,12 @@ class PokeBattle_Battler @effects[PBEffects::MoveNext] = false @effects[PBEffects::MudSport] = false @effects[PBEffects::Nightmare] = false + @effects[PBEffects::NoRetreat] = false + @effects[PBEffects::Obstruct] = false + @effects[PBEffects::Octolock] = -1 + @battle.eachBattler do |b| # Other battlers no longer locked by self + b.effects[PBEffects::Octolock] = -1 if b.effects[PBEffects::Octolock] == @index + end @effects[PBEffects::Outrage] = 0 @effects[PBEffects::ParentalBond] = 0 @effects[PBEffects::PickupItem] = nil @@ -257,6 +263,7 @@ class PokeBattle_Battler @effects[PBEffects::Stockpile] = 0 @effects[PBEffects::StockpileDef] = 0 @effects[PBEffects::StockpileSpDef] = 0 + @effects[PBEffects::TarShot] = false @effects[PBEffects::Taunt] = 0 @effects[PBEffects::ThroatChop] = 0 @effects[PBEffects::Torment] = false diff --git a/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb b/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb index c3cd1a6df..ae2762df7 100644 --- a/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb +++ b/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb @@ -91,7 +91,7 @@ class PokeBattle_Battler def pbChangeTargets(move,user,targets) target_data = move.pbTarget(user) return targets if @battle.switching # For Pursuit interrupting a switch - return targets if move.cannotRedirect? + return targets if move.cannotRedirect? || move.targetsPosition? return targets if !target_data.can_target_one_foe? || targets.length != 1 priority = @battle.pbPriority(true) nearOnly = !target_data.can_choose_distant_target? @@ -162,7 +162,7 @@ class PokeBattle_Battler # Register target #============================================================================= def pbAddTarget(targets,user,target,move,nearOnly=true,allowUser=false) - return false if !target || (target.fainted? && !move.cannotRedirect?) + return false if !target || (target.fainted? && !move.targetsPosition?) return false if !(allowUser && user==target) && nearOnly && !user.near?(target) targets.each { |b| return true if b.index==target.index } # Already added targets.push(target) diff --git a/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb b/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb index 33e23c676..47a824ba0 100644 --- a/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb +++ b/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb @@ -375,6 +375,19 @@ class PokeBattle_Battler end return false end + # Obstruct + if target.effects[PBEffects::Obstruct] && move.damagingMove? + @battle.pbCommonAnimation("Obstruct",target) + @battle.pbDisplay(_INTL("{1} protected itself!", target.pbThis)) + target.damageState.protected = true + @battle.successStates[user.index].protected = true + if move.pbContactMove?(user) && user.affectedByContactEffect? + if user.pbCanLowerStatStage?(:DEFENSE) + user.pbLowerStatStage(:DEFENSE, 2, nil) + end + end + return false + end # Mat Block if target.pbOwnSide.effects[PBEffects::MatBlock] && move.damagingMove? # NOTE: Confirmed no common animation for this effect. diff --git a/Data/Scripts/011_Battle/001_PBEffects.rb b/Data/Scripts/011_Battle/001_PBEffects.rb index d78d1d849..1ee764156 100644 --- a/Data/Scripts/011_Battle/001_PBEffects.rb +++ b/Data/Scripts/011_Battle/001_PBEffects.rb @@ -67,6 +67,9 @@ begin MoveNext = 61 MudSport = 62 Nightmare = 63 + NoRetreat = 990 + Obstruct = 992 + Octolock = 993 Outrage = 64 ParentalBond = 65 PerishSong = 66 @@ -98,6 +101,7 @@ begin StockpileDef = 92 StockpileSpDef = 93 Substitute = 94 + TarShot = 991 Taunt = 95 Telekinesis = 96 ThroatChop = 97 diff --git a/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb b/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb index 964c48e06..4a0c83de5 100644 --- a/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb +++ b/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb @@ -106,7 +106,8 @@ class PokeBattle_Move 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 targetsPosition?; return false; end # For Future Sight/Doom Desire + def cannotRedirect?; return false; end # For Snipe Shot def worksWithNoTargets?; return false; end # For Explosion def damageReducedByBurn?; return true; end # For Facade def triggersHyperMode?; return false; end diff --git a/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb b/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb index f17b3bc78..5ebe46f1c 100644 --- a/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb +++ b/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb @@ -79,6 +79,7 @@ class PokeBattle_Move # Multiply all effectivenesses together ret = 1 typeMods.each { |m| ret *= m } + ret *= 2 if target.effects[PBEffects::TarShot] && moveType == :FIRE return ret end diff --git a/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb b/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb index 8ea217e87..cda47acc8 100644 --- a/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb +++ b/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb @@ -408,7 +408,7 @@ end # Attacks 2 rounds in the future. (Doom Desire, Future Sight) #=============================================================================== class PokeBattle_Move_111 < PokeBattle_Move - def cannotRedirect?; return true; end + def targetsPosition?; return true; end def pbDamagingMove? # Stops damage being dealt in the setting-up turn return false if !@battle.futureSight diff --git a/Data/Scripts/011_Battle/002_Move/008_Move_Effects_Gen8.rb b/Data/Scripts/011_Battle/002_Move/008_Move_Effects_Gen8.rb index 0de1f5e08..17fcb090f 100644 --- a/Data/Scripts/011_Battle/002_Move/008_Move_Effects_Gen8.rb +++ b/Data/Scripts/011_Battle/002_Move/008_Move_Effects_Gen8.rb @@ -35,7 +35,45 @@ Flip Turn - 0EE # if it is a physical move. Has a different animation depending on the move's # category. (Shell Side Arm) #=============================================================================== -class PokeBattle_Move_176 < PokeBattle_UnimplementedMove +class PokeBattle_Move_176 < PokeBattle_PoisonMove + def initialize(battle, move) + super + @calcCategory = 1 + end + + def physicalMove?(thisType = nil); return (@calcCategory == 0); end + def specialMove?(thisType = nil); return (@calcCategory == 1); end + def contactMove?; return physicalMove?; end + + def pbOnStartUse(user, targets) + target = targets[0] + 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] + # Calculate user's effective attacking values + attack_stage = user.stages[:ATTACK] + 6 + real_attack = (user.attack.to_f * stageMul[attack_stage] / stageDiv[attack_stage]).floor + special_attack_stage = user.stages[:SPECIAL_ATTACK] + 6 + real_special_attack = (user.spatk.to_f * stageMul[special_attack_stage] / stageDiv[special_attack_stage]).floor + # Calculate target's effective defending values + defense_stage = target.stages[:DEFENSE] + 6 + real_defense = (target.defense.to_f * stageMul[defense_stage] / stageDiv[defense_stage]).floor + special_defense_stage = target.stages[:SPECIAL_DEFENSE] + 6 + real_special_defense = (target.spdef.to_f * stageMul[special_defense_stage] / stageDiv[special_defense_stage]).floor + # Perform simple damage calculation + physical_damage = real_attack.to_f / real_defense + special_damage = real_special_attack.to_f / real_special_defense + # Determine move's category + if physical_damage == special_damage + @calcCategry = @battle.pbRandom(2) + else + @calcCategory = (physical_damage > special_damage) ? 0 : 1 + end + end + + def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) + hitNum = 1 if physicalMove? + super + end end #=============================================================================== @@ -74,7 +112,25 @@ end # still switch out if holding Shed Shell or Eject Button, or if affected by a # Red Card. (No Retreat) #=============================================================================== -class PokeBattle_Move_179 < PokeBattle_UnimplementedMove +class PokeBattle_Move_179 < PokeBattle_Move_02D + def pbMoveFailed?(user, targets) + if user.effects[PBEffects::NoRetreat] + @battle.pbDisplay(_INTL("But it failed!")) + return true + end + return super + end + + def pbEffectGeneral(user) + super + if battler.effects[PBEffects::Trapping] == 0 && + battler.effects[PBEffects::MeanLook] < 0 && + !battler.effects[PBEffects::Ingrain] && + @field.effects[PBEffects::FairyLock] == 0 + user.effects[PBEffects::NoRetreat] = true + @battle.pbDisplay(_INTL("{1} can no longer escape because it used {2}!", user.pbThis, @name)) + end + end end #=============================================================================== @@ -114,13 +170,36 @@ end # protections, including Crafty Shield. Fails if there is no ally. (Coaching) #=============================================================================== class PokeBattle_Move_17B < PokeBattle_UnimplementedMove + # TODO: Needs a new targeting option. Otherwise, see Magnetic Flux. end #=============================================================================== -# Increases the target's Attack and Special Attack by 2 stages each. Bypasses -# some protections. (Decorate) +# Increases the target's Attack and Special Attack by 2 stages each. (Decorate) #=============================================================================== -class PokeBattle_Move_17C < PokeBattle_UnimplementedMove +class PokeBattle_Move_17C < PokeBattle_Move + def pbMoveFailed?(user, targets) + failed = true + targets.each do |b| + next if !b.pbCanRaiseStatStage?(:ATTACK, user, self) && + !b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) + failed = false + break + end + if failed + @battle.pbDisplay(_INTL("But it failed!")) + return true + end + return false + end + + def pbEffectAgainstTarget(user, target) + if target.pbCanRaiseStatStage?(:ATTACK, user, self) + target.pbRaiseStatStage(:ATTACK, 2, user) + end + if target.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) + target.pbRaiseStatStage(:SPECIAL_ATTACK, 2, user) + end + end end #=============================================================================== @@ -139,7 +218,19 @@ end # Fire moves used against the target (this effect does not stack). Fails if # neither of these effects can be applied. (Tar Shot) #=============================================================================== -class PokeBattle_Move_17E < PokeBattle_UnimplementedMove +class PokeBattle_Move_17E < PokeBattle_Move_044 + def pbFailsAgainstTarget?(user, target) + return super if target.effects[PBEffects::TarShot] + return false + end + + def pbEffectAgainstTarget(user, target) + super + if !target.effects[PBEffects::TarShot] + target.effects[PBEffects::TarShot] = true + @battle.pbDisplay(_INTL("{1} became weaker to fire!", target.pbThis)) + end + end end #=============================================================================== @@ -264,15 +355,20 @@ end # For the rest of this round, the user avoids all damaging moves that would hit # it. If a move that makes contact is stopped by this effect, decreases the # Defense of the Pokémon using that move by 2 stages. Contributes to Protect's -# counter. (Very similar to King's Shield.) (Obstruct) +# counter. (Obstruct) #=============================================================================== -class PokeBattle_Move_186 < PokeBattle_UnimplementedMove +class PokeBattle_Move_186 < PokeBattle_ProtectMove + def initialize(battle,move) + super + @effect = PBEffects::Obstruct + end end #=============================================================================== # Unaffected by moves and abilities that would redirect this move. (Snipe Shot) #=============================================================================== -class PokeBattle_Move_187 < PokeBattle_UnimplementedMove +class PokeBattle_Move_187 < PokeBattle_Move + def cannotRedirect?; return true; end end #=============================================================================== @@ -309,7 +405,29 @@ end # Hits 2-5 times in a row. If the move does not fail, increases the user's Speed # by 1 stage and decreases the user's Defense by 1 stage. (Scale Shot) #=============================================================================== -class PokeBattle_Move_18A < PokeBattle_UnimplementedMove +class PokeBattle_Move_18A < PokeBattle_Move + def multiHitMove?; return true; end + + def pbNumHits(user, targets) + hitChances = [ + 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, + 5, 5, 5] + r = @battle.pbRandom(hitChances.length) + r = hitChances.length - 1 if user.hasActiveAbility?(:SKILLLINK) + return hitChances[r] + end + + def pbEffectAfterAllHits(user, target) + return if target.damageState.unaffected + if user.pbCanLowerStatStage?(:DEFENSE, user, self) + user.pbLowerStatStage(:DEFENSE, 1, user) + end + if user.pbCanRaiseStatStage?(:SPEED, user, self) + user.pbRaiseStatStage(:SPEED, 1, user) + end + end end #=============================================================================== @@ -419,11 +537,29 @@ class PokeBattle_Move_18E < PokeBattle_Move_0E0 end #=============================================================================== -# The target can no longer switch out or flee. At the end of each round, the -# target's Defense and Special Defense are lowered by 1 stage each. (Does this -# only apply while the user remains in battle?) (Octolock) +# The target can no longer switch out or flee, while the user remains in battle. +# At the end of each round, the target's Defense and Special Defense are lowered +# by 1 stage each. (Octolock) +# TODO: Can the user lock multiple other Pokémon at once? #=============================================================================== -class PokeBattle_Move_18F < PokeBattle_UnimplementedMove +class PokeBattle_Move_18F < PokeBattle_Move + def pbFailsAgainstTarget?(user, target) + return false if damagingMove? + if target.effects[PBEffects::Octolock] >= 0 + @battle.pbDisplay(_INTL("But it failed!")) + return true + end + if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST) + @battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true))) + return true + end + return false + end + + def pbEffectAgainstTarget(user, target) + target.effects[PBEffects::Octolock] = user.index + @battle.pbDisplay(_INTL("{1} can no longer escape because of {2}!", target.pbThis, @name)) + end end #=============================================================================== diff --git a/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb b/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb index e1ce075b6..7654d8725 100644 --- a/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb +++ b/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb @@ -588,6 +588,7 @@ class PokeBattle_Battle PBEffects::LockOnPos, PBEffects::MeanLook, PBEffects::MirrorCoatTarget, + PBEffects::Octolock, PBEffects::SkyDrop, PBEffects::TrappingUser] eachBattler do |b| diff --git a/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb b/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb index 87bc6bfb3..6acd10c18 100644 --- a/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb +++ b/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb @@ -68,7 +68,9 @@ class PokeBattle_Battle # Other certain trapping effects if battler.effects[PBEffects::Trapping]>0 || battler.effects[PBEffects::MeanLook]>=0 || + battler.effects[PBEffects::Octolock]>=0 || battler.effects[PBEffects::Ingrain] || + battler.effects[PBEffects::NoRetreat] || @field.effects[PBEffects::FairyLock]>0 partyScene.pbDisplay(_INTL("{1} can't be switched out!",battler.pbThis)) if partyScene return false diff --git a/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb b/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb index 815090e61..da01bd650 100644 --- a/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb +++ b/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb @@ -13,7 +13,9 @@ class PokeBattle_Battle BattleHandlers.triggerRunFromBattleItem(battler.item,battler) return false if battler.effects[PBEffects::Trapping]>0 || battler.effects[PBEffects::MeanLook]>=0 || + battler.effects[PBEffects::Octolock]>=0 || battler.effects[PBEffects::Ingrain] || + battler.effects[PBEffects::NoRetreat] || @field.effects[PBEffects::FairyLock]>0 eachOtherSideBattler(idxBattler) do |b| return false if b.abilityActive? && @@ -101,7 +103,9 @@ class PokeBattle_Battle # Other certain trapping effects if battler.effects[PBEffects::Trapping]>0 || battler.effects[PBEffects::MeanLook]>=0 || + battler.effects[PBEffects::Octolock]>=0 || battler.effects[PBEffects::Ingrain] || + battler.effects[PBEffects::NoRetreat] || @field.effects[PBEffects::FairyLock]>0 pbDisplayPaused(_INTL("You can't escape!")) return 0 diff --git a/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb b/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb index ab90bcf9e..a522fea6c 100644 --- a/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb +++ b/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb @@ -428,6 +428,13 @@ class PokeBattle_Battle end end end + # Octolock + priority.each do |b| + next if b.fainted? || b.effects[PBEffects::Octolock] < 0 + pbCommonAnimation("Octolock", b) + b.pbLowerStatStage(:DEFENSE, 1, nil) if b.pbCanLowerStatStage?(:DEFENSE) + b.pbLowerStatStage(:SPECIAL_DEFENSE, 1, nil) if b.pbCanLowerStatStage?(:SPECIAL_DEFENSE) + end # Taunt pbEORCountDownBattlerEffect(priority,PBEffects::Taunt) { |battler| pbDisplay(_INTL("{1}'s taunt wore off!",battler.pbThis)) @@ -625,6 +632,7 @@ class PokeBattle_Battle b.effects[PBEffects::MagicCoat] = false b.effects[PBEffects::MirrorCoat] = -1 b.effects[PBEffects::MirrorCoatTarget] = -1 + b.effects[PBEffects::Obstruct] = false b.effects[PBEffects::Powder] = false b.effects[PBEffects::Prankster] = false b.effects[PBEffects::PriorityAbility] = false