Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #===============================================================================
- # Simple battler class for the wild Pokémon in a Safari Zone battle
- #===============================================================================
- class PokeBattle_FakeBattler
- attr_reader :battle
- attr_reader :index
- attr_reader :pokemon
- attr_reader :owned
- def initialize(battle,index)
- @battle = battle
- @pokemon = battle.party2[0]
- @index = index
- end
- def pokemonIndex; return 0; end
- def species; return @pokemon.species; end
- def gender; return @pokemon.gender; end
- def status; return @pokemon.status; end
- def hp; return @pokemon.hp; end
- def level; return @pokemon.level; end
- def name; return @pokemon.name; end
- def totalhp; return @pokemon.totalhp; end
- def displayGender; return @pokemon.gender; end
- def shiny?; return @pokemon.shiny?; end
- def square_shiny?; return @pokemon.square_shiny?; end
- alias isShiny? shiny?
- def isSpecies?(check_species)
- return @pokemon && @pokemon.isSpecies?(check_species)
- end
- def fainted?; return false; end
- alias isFainted? fainted?
- def shadowPokemon?; return false; end
- alias isShadow? shadowPokemon?
- def hasMega?; return false; end
- def mega?; return false; end
- alias isMega? mega?
- def hasPrimal?; return false; end
- def primal?; return false; end
- alias isPrimal? primal?
- def captured; return false; end
- def captured=(value); end
- def owned?
- return $Trainer.owned?(pokemon.species)
- end
- def pbThis(lowerCase=false)
- return (lowerCase) ? _INTL("the wild {1}",name) : _INTL("The wild {1}",name)
- end
- def opposes?(i)
- i = i.index if i.is_a?(PokeBattle_FakeBattler)
- return (@index&1)!=(i&1)
- end
- def pbReset; end
- end
- #===============================================================================
- # Data box for safari battles
- #===============================================================================
- class SafariDataBox < SpriteWrapper
- attr_accessor :selected
- def initialize(battle,viewport=nil)
- super(viewport)
- @selected = 0
- @battle = battle
- @databox = AnimatedBitmap.new("Graphics/Pictures/Battle/databox_safari")
- self.x = Graphics.width - 232
- self.y = Graphics.height - 184
- @contents = BitmapWrapper.new(@databox.width,@databox.height)
- self.bitmap = @contents
- self.visible = false
- self.z = 50
- pbSetSystemFont(self.bitmap)
- refresh
- end
- def refresh
- self.bitmap.clear
- self.bitmap.blt(0,0,@databox.bitmap,Rect.new(0,0,@databox.width,@databox.height))
- base = Color.new(72,72,72)
- shadow = Color.new(184,184,184)
- textpos = []
- textpos.push([_INTL("Safari Balls"),30,2,false,base,shadow])
- textpos.push([_INTL("Left: {1}",@battle.ballCount),30,32,false,base,shadow])
- pbDrawTextPositions(self.bitmap,textpos)
- end
- def update(frameCounter=0)
- super()
- end
- end
- #===============================================================================
- # Shows the player throwing bait at a wild Pokémon in a Safari battle.
- #===============================================================================
- class ThrowBaitAnimation < PokeBattle_Animation
- include PokeBattle_BallAnimationMixin
- def initialize(sprites,viewport,battler)
- @battler = battler
- @trainer = battler.battle.pbGetOwnerFromBattlerIndex(battler.index)
- super(sprites,viewport)
- end
- def createProcesses
- # Calculate start and end coordinates for battler sprite movement
- batSprite = @sprites["pokemon_#{@battler.index}"]
- traSprite = @sprites["player_1"]
- ballPos = PokeBattle_SceneConstants.pbBattlerPosition(@battler.index,batSprite.sideSize)
- ballStartX = traSprite.x
- ballStartY = traSprite.y-traSprite.bitmap.height/2
- ballMidX = 0 # Unused in arc calculation
- ballMidY = 122
- ballEndX = ballPos[0]-40
- ballEndY = ballPos[1]-4
- # Set up trainer sprite
- trainer = addSprite(traSprite,PictureOrigin::Bottom)
- # Set up bait sprite
- ball = addNewSprite(ballStartX,ballStartY,
- "Graphics/Battle animations/safari_bait",PictureOrigin::Center)
- ball.setZ(0,batSprite.z+1)
- # Trainer animation
- if traSprite.bitmap.width>=traSprite.bitmap.height*2
- ballStartX, ballStartY = trainerThrowingFrames(ball,trainer,traSprite)
- end
- delay = ball.totalDuration # 0 or 7
- # Bait arc animation
- ball.setSE(delay,"Battle throw")
- createBallTrajectory(ball,delay,12,
- ballStartX,ballStartY,ballMidX,ballMidY,ballEndX,ballEndY)
- ball.setZ(9,batSprite.z+1)
- delay = ball.totalDuration
- ball.moveOpacity(delay+8,2,0)
- ball.setVisible(delay+10,false)
- # Set up battler sprite
- battler = addSprite(batSprite,PictureOrigin::Bottom)
- # Show Pokémon jumping before eating the bait
- delay = ball.totalDuration+3
- 2.times do
- battler.setSE(delay,"player jump")
- battler.moveDelta(delay,3,0,-16)
- battler.moveDelta(delay+4,3,0,16)
- delay = battler.totalDuration+1
- end
- # Show Pokémon eating the bait
- delay = battler.totalDuration+3
- 2.times do
- battler.moveAngle(delay,7,5)
- battler.moveDelta(delay,7,0,6)
- battler.moveAngle(delay+7,7,0)
- battler.moveDelta(delay+7,7,0,-6)
- delay = battler.totalDuration
- end
- end
- end
- #===============================================================================
- # Shows the player throwing a rock at a wild Pokémon in a Safari battle.
- #===============================================================================
- class ThrowRockAnimation < PokeBattle_Animation
- include PokeBattle_BallAnimationMixin
- def initialize(sprites,viewport,battler)
- @battler = battler
- @trainer = battler.battle.pbGetOwnerFromBattlerIndex(battler.index)
- super(sprites,viewport)
- end
- def createProcesses
- # Calculate start and end coordinates for battler sprite movement
- batSprite = @sprites["pokemon_#{@battler.index}"]
- traSprite = @sprites["player_1"]
- ballStartX = traSprite.x
- ballStartY = traSprite.y-traSprite.bitmap.height/2
- ballMidX = 0 # Unused in arc calculation
- ballMidY = 122
- ballEndX = batSprite.x
- ballEndY = batSprite.y-batSprite.bitmap.height/2
- # Set up trainer sprite
- trainer = addSprite(traSprite,PictureOrigin::Bottom)
- # Set up bait sprite
- ball = addNewSprite(ballStartX,ballStartY,
- "Graphics/Battle animations/safari_rock",PictureOrigin::Center)
- ball.setZ(0,batSprite.z+1)
- # Trainer animation
- if traSprite.bitmap.width>=traSprite.bitmap.height*2
- ballStartX, ballStartY = trainerThrowingFrames(ball,trainer,traSprite)
- end
- delay = ball.totalDuration # 0 or 7
- # Bait arc animation
- ball.setSE(delay,"Battle throw")
- createBallTrajectory(ball,delay,12,
- ballStartX,ballStartY,ballMidX,ballMidY,ballEndX,ballEndY)
- ball.setZ(9,batSprite.z+1)
- delay = ball.totalDuration
- ball.setSE(delay,"Battle damage weak")
- ball.moveOpacity(delay+2,2,0)
- ball.setVisible(delay+4,false)
- # Set up anger sprite
- anger = addNewSprite(ballEndX-42,ballEndY-36,
- "Graphics/Battle animations/safari_anger",PictureOrigin::Center)
- anger.setVisible(0,false)
- anger.setZ(0,batSprite.z+1)
- # Show anger appearing
- delay = ball.totalDuration+5
- 2.times do
- anger.setSE(delay,"Player jump")
- anger.setVisible(delay,true)
- anger.moveZoom(delay,3,130)
- anger.moveZoom(delay+3,3,100)
- anger.setVisible(delay+6,false)
- anger.setDelta(delay+6,96,-16)
- delay = anger.totalDuration+3
- end
- end
- end
- #===============================================================================
- # Safari Zone battle scene (the visuals of the battle)
- #===============================================================================
- class PokeBattle_Scene
- def pbSafariStart
- @briefMessage = false
- @sprites["dataBox_0"] = SafariDataBox.new(@battle,@viewport)
- dataBoxAnim = DataBoxAppearAnimation.new(@sprites,@viewport,0)
- loop do
- dataBoxAnim.update
- pbUpdate
- break if dataBoxAnim.animDone?
- end
- dataBoxAnim.dispose
- pbRefresh
- end
- def pbSafariCommandMenu(index)
- pbCommandMenuEx(index,[
- _INTL("What will\n{1} throw?",@battle.pbPlayer.name),
- _INTL("Ball"),
- _INTL("Bait"),
- _INTL("Rock"),
- _INTL("Run")
- ],3)
- end
- def pbThrowBait
- @briefMessage = false
- baitAnim = ThrowBaitAnimation.new(@sprites,@viewport,@battle.battlers[1])
- loop do
- baitAnim.update
- pbUpdate
- break if baitAnim.animDone?
- end
- baitAnim.dispose
- end
- def pbThrowRock
- @briefMessage = false
- rockAnim = ThrowRockAnimation.new(@sprites,@viewport,@battle.battlers[1])
- loop do
- rockAnim.update
- pbUpdate
- break if rockAnim.animDone?
- end
- rockAnim.dispose
- end
- alias __safari__pbThrowSuccess pbThrowSuccess
- def pbThrowSuccess
- __safari__pbThrowSuccess
- pbWildBattleSuccess if @battle.is_a?(PokeBattle_SafariZone)
- end
- end
- #===============================================================================
- # Safari Zone battle class
- #===============================================================================
- class PokeBattle_SafariZone
- attr_reader :battlers # Array of fake battler objects
- attr_accessor :sideSizes # Array of number of battlers per side
- attr_accessor :backdrop # Filename fragment used for background graphics
- attr_accessor :backdropBase # Filename fragment used for base graphics
- attr_accessor :time # Time of day (0=day, 1=eve, 2=night)
- attr_accessor :environment # Battle surroundings (for mechanics purposes)
- attr_reader :weather
- attr_reader :player
- attr_accessor :party2
- attr_accessor :canRun # True if player can run from battle
- attr_accessor :canLose # True if player won't black out if they lose
- attr_accessor :switchStyle # Switch/Set "battle style" option
- attr_accessor :showAnims # "Battle scene" option (show anims)
- attr_accessor :expGain # Whether Pokémon can gain Exp/EVs
- attr_accessor :moneyGain # Whether the player can gain/lose money
- attr_accessor :rules
- attr_accessor :ballCount
- include PokeBattle_BattleCommon
- def pbRandom(x); return rand(x); end
- #=============================================================================
- # Initialize the battle class
- #=============================================================================
- def initialize(scene,player,party2)
- @scene = scene
- @peer = PokeBattle_BattlePeer.create()
- @backdrop = ""
- @backdropBase = nil
- @time = 0
- @environment = :None # e.g. Tall grass, cave, still water
- @weather = :None
- @decision = 0
- @caughtPokemon = []
- @player = [player]
- @party2 = party2
- @sideSizes = [1,1]
- @battlers = [
- PokeBattle_FakeBattler.new(self,0),
- PokeBattle_FakeBattler.new(self,1)
- ]
- @rules = {}
- @ballCount = 0
- end
- def defaultWeather=(value); @weather = value; end
- def defaultTerrain=(value); end
- #=============================================================================
- # Information about the type and size of the battle
- #=============================================================================
- def wildBattle?; return true; end
- def trainerBattle?; return false; end
- def setBattleMode(mode); end
- def pbSideSize(index)
- return @sideSizes[index%2]
- end
- #=============================================================================
- # Trainers and owner-related
- #=============================================================================
- def pbPlayer; return @player[0]; end
- def opponent; return nil; end
- def pbGetOwnerFromBattlerIndex(idxBattler); return pbPlayer; end
- #=============================================================================
- # Get party info (counts all teams on the same side)
- #=============================================================================
- def pbParty(idxBattler)
- return (opposes?(idxBattler)) ? @party2 : nil
- end
- def pbAllFainted?(idxBattler=0); return false; end
- #=============================================================================
- # Battler-related
- #=============================================================================
- def opposes?(idxBattler1,idxBattler2=0)
- idxBattler1 = idxBattler1.index if idxBattler1.respond_to?("index")
- idxBattler2 = idxBattler2.index if idxBattler2.respond_to?("index")
- return (idxBattler1&1)!=(idxBattler2&1)
- end
- def pbRemoveFromParty(idxBattler,idxParty); end
- def pbGainExp; end
- #=============================================================================
- # Messages and animations
- #=============================================================================
- def pbDisplay(msg,&block)
- @scene.pbDisplayMessage(msg,&block)
- end
- def pbDisplayPaused(msg,&block)
- @scene.pbDisplayPausedMessage(msg,&block)
- end
- def pbDisplayBrief(msg)
- @scene.pbDisplayMessage(msg,true)
- end
- def pbDisplayConfirm(msg)
- return @scene.pbDisplayConfirmMessage(msg)
- end
- #=============================================================================
- # Pokedex Registration
- #=============================================================================
- def pbSetBattled(battler)
- return if !battler || !@internalBattle
- if battler.respond_to?(:opposes?)
- return if battler.opposes?
- pbPlayer.pokedex.register_battled(battler.displaySpecies)
- else
- pbPlayer.pokedex.register_battled(battler.species)
- end
- end
- class BattleAbortedException < Exception; end
- def pbAbort
- raise BattleAbortedException.new("Battle aborted")
- end
- #=============================================================================
- # Safari battle-specific methods
- #=============================================================================
- def pbEscapeRate(catch_rate)
- return 125 if catch_rate <= 45 # Escape factor 9 (45%)
- return 100 if catch_rate <= 60 # Escape factor 7 (35%)
- return 75 if catch_rate <= 120 # Escape factor 5 (25%)
- return 50 if catch_rate <= 250 # Escape factor 3 (15%)
- return 25 # Escape factor 2 (10%)
- end
- def pbStartBattle
- begin
- pkmn = @party2[0]
- self.pbPlayer.pokedex.register(pkmn)
- @scene.pbStartBattle(self)
- pbDisplayPaused(_INTL("Wild {1} appeared!",pkmn.name))
- @scene.pbSafariStart
- weather_data = GameData::BattleWeather.try_get(@weather)
- @scene.pbCommonAnimation(weather_data.animation) if weather_data
- safariBall = GameData::Item.get(:SAFARIBALL).id
- catch_rate = pkmn.species_data.catch_rate
- catchFactor = (catch_rate*100)/1275
- catchFactor = [[catchFactor,3].max,20].min
- escapeFactor = (pbEscapeRate(catch_rate)*100)/1275
- escapeFactor = [[escapeFactor,2].max,20].min
- loop do
- cmd = @scene.pbSafariCommandMenu(0)
- case cmd
- when 0 # Ball
- if pbBoxesFull?
- pbDisplay(_INTL("The boxes are full! You can't catch any more Pokémon!"))
- next
- end
- @ballCount -= 1
- @scene.pbRefresh
- rare = (catchFactor*1275)/100
- if safariBall
- pbThrowPokeBall(1,safariBall,rare,true)
- if @caughtPokemon.length>0
- pbRecordAndStoreCaughtPokemon
- @decision = 4
- end
- end
- when 1 # Bait
- pbDisplayBrief(_INTL("{1} threw some bait at the {2}!",self.pbPlayer.name,pkmn.name))
- @scene.pbThrowBait
- catchFactor /= 2 if pbRandom(100)<90 # Harder to catch
- escapeFactor /= 2 # Less likely to escape
- when 2 # Rock
- pbDisplayBrief(_INTL("{1} threw a rock at the {2}!",self.pbPlayer.name,pkmn.name))
- @scene.pbThrowRock
- catchFactor *= 2 # Easier to catch
- escapeFactor *= 2 if pbRandom(100)<90 # More likely to escape
- when 3 # Run
- pbSEPlay("Battle flee")
- pbDisplayPaused(_INTL("You got away safely!"))
- @decision = 3
- end
- catchFactor = [[catchFactor,3].max,20].min
- escapeFactor = [[escapeFactor,2].max,20].min
- # End of round
- if @decision==0
- if @ballCount<=0
- pbDisplay(_INTL("PA: You have no Safari Balls left! Game over!"))
- @decision = 2
- elsif pbRandom(100)<5*escapeFactor
- pbSEPlay("Battle flee")
- pbDisplay(_INTL("{1} fled!",pkmn.name))
- @decision = 3
- elsif cmd==1 # Bait
- pbDisplay(_INTL("{1} is eating!",pkmn.name))
- elsif cmd==2 # Rock
- pbDisplay(_INTL("{1} is angry!",pkmn.name))
- else
- pbDisplay(_INTL("{1} is watching carefully!",pkmn.name))
- end
- # Weather continues
- weather_data = GameData::BattleWeather.try_get(@weather)
- @scene.pbCommonAnimation(weather_data.animation) if weather_data
- end
- break if @decision > 0
- end
- @scene.pbEndBattle(@decision)
- rescue BattleAbortedException
- @decision = 0
- @scene.pbEndBattle(@decision)
- end
- return @decision
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement