Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- __END__
- # CREDITS:
- # - Mr. "Jteo" Gela
- # - Toxicroak
- # - angrybanana5000
- # - bobandbill
- # - Shauna
- # - Yusshin
- # - Team Rocket's Raichu
- # - April
- # - Team Fail
- # - IceCatraz
- # - kittikatt
- # - rizyq
- # - Sasuke
- # - steffyace
- # - Panfisha
- # - Glow Worm's Not Glowing
- # - chamo-chan
- # - billios
- # - little monster
- # - mastermack0
- # TODO:
- # #DONE# - Actual animation popups themselves when interacting
- # #DONE# - Support for Female overworld sprites
- # - Status condition tones? If that's an actual official thing?
- # #DONE# - Have the follower load at the correct angle/side upon loading the game
- # #DONE# - Seamless map transitions
- # #DONE# - Follower coming out upon map transition if it was retracted
- # - Crash upon toggling at map edge
- # - Move Routes
- # - When toggling follower on map edge it can cause instant/pop transition
- module Follower
- # Whether or not you want the follower overworld sprite to be animated or not
- # when the player is not moving.
- IdleAnimation = true
- # Has to be inside Graphics/Characters. This folder will contain all the pokemon
- # overworld sprites.
- PokemonFollowingSpritePath = "Graphics/Characters/Following Pokemon/Overworlds"
- end
- class Game_Event
- attr_accessor :event
- attr_accessor :page
- end
- class DependentEvents
- attr_accessor :realEvents
- # Overwrites [addEvent] to support a number of additional options:
- # - Walk Animation
- # - Step Animation
- # - Direction Fix
- # - Through
- # - Always On Top
- def addEvent(event, eventName = nil, commonEvent = nil)
- return unless event
- events = $PokemonGlobal.dependentEvents
- for i in 0...events.length
- if events[i] && events[i][0] == $game_map.map_id && events[i][1] == event.id
- return
- end
- end
- eventData = [
- $game_map.map_id, event.id, $game_map.map_id,
- event.x, event.y, event.direction,
- event.character_name.clone,
- event.character_hue, eventName, commonEvent,
- event.move_route, event.walk_anime, event.step_anime,
- event.direction_fix, event.through, event.always_on_top,
- event.special_list, event.special_graphic
- ]
- newEvent = createEvent(eventData)
- events.push(eventData)
- @realEvents.push(newEvent)
- @lastUpdate += 1
- event.erase if event.respond_to?(:erase)
- return @realEvents.index(newEvent)
- end
- # Overwrites [createEvent] to support a number of additional options:
- # - Walk Animation
- # - Step Animation
- # - Direction Fix
- # - Through
- # - Always On Top
- def createEvent(eventData)
- rpgEvent = RPG::Event.new(eventData[3],eventData[4])
- rpgEvent.id = eventData[1]
- rpgEvent.name = eventData[8]
- if eventData[9]
- # Must setup common event list here and now
- commonEvent = Game_CommonEvent.new(eventData[9])
- rpgEvent.pages[0].list = commonEvent.list
- elsif eventData[16]
- rpgEvent.pages[0].list = eventData[16]
- end
- rpgEvent.pages[0].move_route = eventData[10]
- rpgEvent.pages[0].walk_anime = eventData[11]
- rpgEvent.pages[0].step_anime = eventData[12]
- rpgEvent.pages[0].direction_fix = eventData[13]
- rpgEvent.pages[0].through = eventData[14]
- rpgEvent.pages[0].always_on_top = eventData[15]
- rpgEvent.pages[0].graphic = eventData[17] || rpgEvent.pages[0].graphic
- newEvent = Game_Event.new(eventData[0],rpgEvent,$MapFactory.getMap(eventData[2]))
- newEvent.character_name = eventData[6]
- newEvent.character_hue = eventData[7]
- case eventData[5] # direction
- when 2; newEvent.turn_down # down
- when 4; newEvent.turn_left # left
- when 6; newEvent.turn_right # right
- when 8; newEvent.turn_up # up
- end
- return newEvent
- end
- def pbEnsureEvent(event, newMapID)
- events = $PokemonGlobal.dependentEvents
- found = -1
- for i in 0...events.length
- # Check original map ID and original event ID
- if events[i][0] == event.map_id && events[i][1] == event.id
- # Change current map ID
- events[i][2] = newMapID
- newEvent = createEvent(events[i])
- # Replace event
- #for e in $scene.spritesetglobal.character_sprites
- # if e.character.__id__ == @realEvents[i].__id__
- # e.character = newEvent
- # end
- #end
- #for p in @realEvents[i].instance_variables
- # begin
- # p = p.to_s#.gsub('@',"")
- # old = @realEvents[i].instance_eval(p)
- # new = newEvent.instance_eval(p)
- # if old != new
- # p(p,old,new)
- # end
- # rescue
- # p(p,$!)
- # end
- #end
- #@realEvents[i] = newEvent
- @realEvents[i].instance_eval do
- @oldMap = newEvent.instance_eval { @oldMap }
- @map = newEvent.instance_eval { @map }
- @stop_count = 2#newEvent.instance_eval { @stop_count }
- @anime_count = newEvent.instance_eval { @anime_count }
- @move_speed = newEvent.instance_eval { @move_speed }
- @real_y = newEvent.instance_eval { @real_y }
- @y = newEvent.instance_eval { @y }
- @oldY = newEvent.instance_eval { @oldY }
- @pattern = newEvent.instance_eval { @pattern }
- end
- @lastUpdate += 1
- return i
- end
- end
- return -1
- end
- # Overwrites [updateDependentEvents] to continue the algorithm with a specially
- # given list too, rather than a common event
- def updateDependentEvents
- events = $PokemonGlobal.dependentEvents
- return if events.length == 0
- for i in 0...events.length
- event = @realEvents[i]
- next if !@realEvents[i]
- event.transparent = $game_player.transparent
- if (event.jumping? || event.moving?) || !($game_player.jumping? || $game_player.moving?) then
- event.update
- elsif !event.starting
- event.set_starting
- event.update
- event.clear_starting
- end
- events[i][3] = event.x
- events[i][4] = event.y
- events[i][5] = event.direction
- end
- # Check event triggers
- if Input.trigger?(Input::C) && !$game_temp.in_menu && !$game_temp.in_battle &&
- !$game_player.move_route_forcing && !$game_temp.message_window_showing &&
- !pbMapInterpreterRunning?
- # Get position of tile facing the player
- facingTile = $MapFactory.getFacingTile()
- self.eachEvent do |e, d|
- next if !d[9] && !d[16]
- if e.x == $game_player.x && e.y == $game_player.y
- # On same position
- if not e.jumping? && (!e.respond_to?(:over_trigger) || e.over_trigger?)
- if e.list.size > 1
- # Start event
- $game_map.refresh if $game_map.need_refresh
- e.lock
- pbMapInterpreter.setup(e.list,e.id,e.map.map_id)
- end
- end
- elsif facingTile && e.map.map_id == facingTile[0] &&
- e.x == facingTile[1] && e.y == facingTile[2]
- # On facing tile
- if not e.jumping? && (!e.respond_to?(:over_trigger) || !e.over_trigger?)
- if e.list.size > 1
- # Start event
- $game_map.refresh if $game_map.need_refresh
- e.lock
- pbMapInterpreter.setup(e.list,e.id,e.map.map_id)
- end
- end
- end
- end
- end
- end
- end
- class DependentEventSprites
- attr_accessor :sprites
- # Overwrites [refresh] to only call [erase] on the registered events if said
- # event objects actually have an [erase] method
- def refresh
- for sprite in @sprites
- sprite.dispose
- end
- @sprites.clear
- $PokemonTemp.dependentEvents.eachEvent do |event, data|
- if data[0] == @map.map_id # Check original map
- @map.events[data[1]].erase if @map.events[data[1]].respond_to?(:erase)
- end
- if data[2] == @map.map_id # Check current map
- next if $scene.spritesetglobal.character_sprites.any? { |e| e.character.name == "Pokemon Follower" }
- $scene.spritesetglobal.character_sprites.push(Sprite_Character.new(Spriteset_Map.viewport, event))
- end
- end
- end
- end
- class Game_Character
- attr_writer :x
- attr_writer :y
- attr_writer :real_x
- attr_writer :real_y
- attr_accessor :move_route
- attr_accessor :step_anime
- attr_accessor :direction_fix
- attr_accessor :always_on_top
- attr_accessor :special_list
- attr_accessor :special_graphic
- attr_accessor :direction
- # Same as [moveto], but removes the [triggerLeaveTile] call.
- def moveto_nocall(x, y)
- @x = x % self.map.width
- @y = y % self.map.height
- @real_x = @x * Game_Map.realResX
- @real_y = @y * Game_Map.realResY
- @prelock_direction = 0
- end
- end
- class Spriteset_Global
- attr_reader :character_sprites
- alias follower_initialize initialize
- def initialize
- follower_initialize
- @character_sprites = []
- end
- alias follower_dispose dispose
- def dispose
- for sprite in @character_sprites
- sprite.dispose unless sprite.disposed?
- end
- follower_dispose
- end
- end
- class Spriteset_Map
- attr_accessor :usersprites
- alias follower_update update
- def update
- for sprite in $scene.spritesetglobal.character_sprites
- if sprite.character.is_a?(Game_Event)
- if in_range?(sprite.character) || sprite.character.move_route_forcing ||
- sprite.character.trigger == 3 || sprite.character.trigger == 4
- sprite.update
- end
- else
- sprite.update
- end
- end
- follower_update
- end
- end
- class PokemonGlobalMetadata
- attr_accessor :follower_activated
- attr_accessor :follower_data
- attr_accessor :follower_visible
- end
- class PokemonTemp
- attr_accessor :follower_index
- attr_accessor :follower_coming_in
- attr_accessor :follower_coming_out
- end
- class Game_Player
- attr_accessor :wasmoving
- alias follower_update update
- def update
- follower_update
- Follower.update
- end
- end
- class Scene_Map
- alias follower_create_spritesets createSpritesets
- def createSpritesets
- follower_create_spritesets
- Follower.enable(false) if $PokemonGlobal.follower_activated
- end
- end
- # Compatibility with [getConstantName]
- module PBStatuses
- NONE = 0
- end
- module PBEmotions
- ANGRY = 0
- UPSET = 1
- NONE = 2
- HAPPY = 3
- VERYHAPPY = 4
- SAD = 5
- EXCLAIM = 6
- JINGLE = 7
- LOVE = 8
- QUESTION = 9
- POISONED = 10
- def self.getFile(emotion)
- return [
- "angry",
- "upset",
- "none",
- "happy",
- "very_happy",
- "sad",
- "exclaim",
- "jingle",
- "love",
- "question",
- "poisoned"
- ][emotion]
- end
- end
- # Not stored to the save file in any way; use $PokemonGlobal to keep track of
- # custom variables.
- module Follower
- module_function
- # Creates a new Follower object/sprite or reinitializes an old one if it already existed
- def enable(animation = true)
- unless (pbMarinUtility rescue false)
- raise RuntimeError.new(
- "You must have \"Marin's Utility Scripts\" installed to use the \"Marin's Pokemon Following\" resource!\n\nThe resource in question can most likely be found on Relic Castle (https://reliccastle.com/)."
- )
- end
- return unless pokemon
- return if event && sprite
- $PokemonGlobal.follower_activated = true
- if $PokemonGlobal.dependentEvents.size > 0 &&
- $PokemonGlobal.dependentEvents.any? { |e| e[8] == "Pokemon Follower" }
- # Dependent Event already exists, so fetch the object
- de = $PokemonGlobal.dependentEvents.find { |e| e[8] == "Pokemon Follower" }
- if de
- list = de[16]
- for i in 0...$PokemonTemp.dependentEvents.realEvents.size
- if $PokemonTemp.dependentEvents.realEvents[i].event &&
- $PokemonTemp.dependentEvents.realEvents[i].event.pages &&
- $PokemonTemp.dependentEvents.realEvents[i].event.pages.size > 0 &&
- $PokemonTemp.dependentEvents.realEvents[i].event.pages[0].list == list
- # Does a bunch of trickery (the majority of which likely redundant)
- # to get the follower in the last (x,y,dir) position as when last
- # saved.
- $PokemonTemp.follower_index = i
- nx, ny, nd = $PokemonGlobal.follower_data
- event.event.x = nx
- event.event.y = ny
- event.event.pages[0].graphic.direction = nd
- event.page.graphic.direction = nd
- event.moveto_nocall(nx, ny)
- event.page.graphic.direction = nd
- event.direction = nd
- # Updates $scene.spriteset so it corrects the event's facing direction
- # and (x,y) before it can actually display on-screen.
- pbUpdateSceneMap
- # If it should show an animation, it performs the animation here.
- if animation
- sprite.zoom_x = 0
- sprite.zoom_y = 0
- show
- end
- break
- end
- end
- end
- return
- end
- # Create a new follower with all properties and settings necessary to work
- # as it should.
- f = Game_Character.new($game_map)
- f.character_name = update_character_name(pokemon)
- f.x = $game_player.x + 1
- f.y = $game_player.y
- f.step_anime = Follower::IdleAnimation
- # This is the command list as you'd normally create in an event in RMXP.
- f.special_list = [
- # Script: Follower.interact
- RPG::EventCommand.new(355, 0, ["Follower.interact"]),
- # Empty (dummy) event command which is apparently necessary.
- RPG::EventCommand.new
- ]
- # Uses two custom properties for the sake of transferring this data easily.
- f.special_graphic = RPG::Event::Page::Graphic.new
- f.special_graphic.character_name = "[Dummy]"
- r = $PokemonTemp.dependentEvents.addEvent(f, "Pokemon Follower")
- $PokemonTemp.follower_index = r
- $scene.spriteset.usersprites.each do |e|
- e.refresh if e.is_a?(DependentEventSprites)
- end
- # Marks the follower as activated/obtained
- $PokemonGlobal.follower_activated = true
- # Marks the follower as invisible so it'll display the animation no matter what.
- $PokemonGlobal.follower_visible = false
- # If it should show an animation, it performs the animation here.
- if animation
- sprite.zoom_x = 0
- sprite.zoom_y = 0
- show
- end
- end
- def enabled?
- return $PokemonGlobal.follower_activated
- end
- def disabled?
- return !enabled?
- end
- # Disables the follower and the very ability to have a following Pokémon
- def disable(animation = true)
- # Hides the follower with an animation if such is specified
- hide if animation
- # Disposes the sprite and removes all references to it
- for i in 0...$scene.spritesetglobal.character_sprites.size
- s = $scene.spritesetglobal.character_sprites[i]
- if s.character == event
- s.dispose
- $scene.spritesetglobal.character_sprites.delete_at(i)
- break
- end
- end
- # Deletes the event and removes all references to it
- $PokemonTemp.dependentEvents.realEvents[$PokemonTemp.follower_index] = nil
- $PokemonTemp.dependentEvents.realEvents.delete_at($PokemonTemp.follower_index)
- $PokemonTemp.follower_index = nil
- for i in 0...$PokemonGlobal.dependentEvents.size
- if $PokemonGlobal.dependentEvents[i][8] == "Pokemon Follower"
- $PokemonGlobal.dependentEvents.delete_at(i)
- break
- end
- end
- $PokemonGlobal.follower_activated = false
- end
- # Determines the file name to use for the overworld based on a Pokémon object
- # Tests files in a very specific order based on:
- # - Shininess
- # - Form
- # - Female/Male
- def update_character_name(poke)
- base = poke.species.to_digits(3)
- path = PokemonFollowingSpritePath + "/" + base
- base = PokemonFollowingSpritePath.split('/')[2..-1].join('/') + '/' + base
- shiny = poke.isShiny?
- form = poke.form
- female = poke.isFemale?
- if shiny
- if form > 0
- if female
- # Shiny, Alternate form, Female
- # Tests files in this order:
- # 000sf_1
- # 000s_1
- # 000f_1
- # 000sf
- # 000sf_0
- # 000s
- # 000s_0
- # 000f
- # 000f_0
- # 000
- # 000_0
- if File.file?(path + "sf_#{form}.png")
- return base + "sf_#{form}"
- elsif File.file?(path + "s_#{form}.png")
- return base + "s_#{form}"
- elsif File.file?(path + "f_#{form}.png")
- return base + "f_#{form}"
- elsif File.file?(path + "sf.png")
- return base + "sf"
- elsif File.file?(path + "sf_0.png")
- return base + "sf_0"
- elsif File.file?(path + "s.png")
- return base + "s"
- elsif File.file?(path + "s_0.png")
- return base + "s_0"
- elsif File.file?(path + "f.png")
- return base + "f"
- elsif File.file?(path + "f_0.png")
- return base + "f_0"
- end
- else
- # Shiny, Alternate form, Male
- # Tests files in this order:
- # 000s_1
- # 000s
- # 000s_0
- # 000_1
- # 000
- # 000_0
- if File.file?(path + "s_#{form}.png")
- return base + "s_#{form}"
- elsif File.file?(path + "s.png")
- return base + "s"
- elsif File.file?(path + "s_0.png")
- return base + "s_0"
- elsif File.file?(path + "_#{form}.png")
- return base + "_#{form}"
- end
- end
- else
- if female
- # Shiny, Standard form, Female
- # Tests files in this order:
- # 000sf
- # 000sf_0
- # 000s
- # 000s_0
- # 000f
- # 000f_0
- # 000
- # 000_0
- if File.file?(path + "sf.png")
- return base + "sf"
- elsif File.file?(path + "sf_0.png")
- return base + "sf_0"
- elsif File.file?(path + "s.png")
- return base + "s"
- elsif File.file?(path + "s_0.png")
- return base + "s_0"
- elsif File.file?(path + "f.png")
- return base + "f"
- elsif File.file?(path + "f_0.png")
- return base + "f_0"
- end
- else
- # Shiny, Standard form, Male
- # Tests files in this order:
- # 000s
- # 000s_0
- # 000
- # 000_0
- if File.file?(path + "s.png")
- return base + "s"
- elsif File.file?(path + "s_0.png")
- return base + "s_0"
- end
- end
- end
- else
- if form > 0
- if female
- # Not Shiny, Alternate form, Female
- # Tests files in this order:
- # 000f_1
- # 000f
- # 000f_0
- # 000_1
- # 000
- # 000_0
- if File.file?(path + "f_#{form}.png")
- return base + "f_#{form}"
- elsif File.file?(path + "f.png")
- return base + "f"
- elsif File.file?(path + "f_0.png")
- return base + "f_0"
- elsif File.file?(path + "_#{form}.png")
- return base + "_#{form}"
- end
- else
- # Not Shiny, Alternate form, Male
- # Tests files in this order:
- # 000_1
- # 000
- # 000_0
- if File.file?(path + "_#{form}.png")
- return base + "_#{form}"
- end
- end
- else
- if female
- # Not Shiny, Standard form, Female
- # Tests files in this order:
- # 000f
- # 000f_0
- # 000
- # 000_0
- if File.file?(path + "f.png")
- return base + "f"
- elsif File.file?(path + "f_0.png")
- return base + "f_0"
- end
- else
- # Not Shiny, Standard form, Male
- # Tests files in this order:
- # 000
- # 000_0
- end
- end
- end
- return base if File.file?(path + ".png")
- return base + "_0" if File.file?(path + "_0.png")
- return nil
- end
- # The actual event object that refers to the follower
- def event
- return nil unless $PokemonTemp && $PokemonTemp.dependentEvents &&
- $PokemonTemp.dependentEvents.realEvents &&
- $PokemonTemp.follower_index
- return $PokemonTemp.dependentEvents.realEvents[$PokemonTemp.follower_index]
- end
- # The first Pokémon of the party that should be the follower - can be nil
- def pokemon
- return $Trainer.party.find { |e| e.hp > 0 && !e.egg? }
- end
- # Updates the used overworld sprite in case it changes (species, shiny value, form)
- def update
- return unless event && sprite
- if pokemon && (@last_id != pokemon.__id__ || @last_shiny != pokemon.isShiny? ||
- @last_form != pokemon.form || @last_female != pokemon.isFemale?)
- event.character_name = update_character_name(pokemon)
- for i in 0...$PokemonGlobal.dependentEvents.size
- if $PokemonGlobal.dependentEvents[i][8] == "Pokemon Follower"
- $PokemonGlobal.dependentEvents[i][6] = event.character_name
- break
- end
- end
- end
- @last_id = pokemon.__id__
- @last_shiny = pokemon.isShiny?
- @last_form = pokemon.form
- @last_female = pokemon.isFemale?
- end
- # The actual Sprite_Character object associated with the follower event
- def sprite
- return nil unless $scene && $scene.respond_to?(:spritesetglobal) &&
- $scene.spritesetglobal &&
- $scene.spritesetglobal.respond_to?(:character_sprites) &&
- $scene.spritesetglobal.character_sprites.is_a?(Array)
- return $scene.spritesetglobal.character_sprites.find { |e| e.character == event }
- #return nil unless $scene.respond_to?(:spriteset) &&
- # $scene.spriteset &&
- # $scene.spriteset.respond_to?(:usersprites) &&
- # $scene.spriteset.usersprites.is_a?(Array)
- #des = $scene.spriteset.usersprites.find { |e| e.is_a?(DependentEventSprites) }
- #return nil unless des#pacito
- #return nil unless event
- #return des.sprites.find { |e| e.character == event }
- end
- # Whether or not the follower is currently visible
- def visible?
- return $PokemonGlobal.follower_visible
- end
- # Whether or not the follower is currently invisible
- def hidden?
- return !visible?
- end
- # Called whenever you talk to the follower. Contains the interaction table
- # with messages it may choose from
- def interact
- return unless visible?
- name = pokemon.name
- speciesname = PBSpecies.getName(pokemon.species)
- type = getConstantName(PBTypes,pokemon.type1) # Primary type
- type = ":#{type}" if type
- species = getConstantName(PBSpecies,pokemon.species) # Species name
- species = ":#{species}" if species
- happy = pokemon.happiness
- status = getConstantName(PBStatuses,pokemon.status)
- status = ":#{status}" if status
- hp = pokemon.hp
- hp_fact = pokemon.hp / pokemon.totalhp.to_f
- weather = getConstantName(PBFieldWeather,$game_screen.weather_type)
- weather = ":#{weather.upcase}" if weather
- outside = pbGetMetadata($game_map.map_id, MetadataOutdoor)
- msg = []
- emote = proc do |emotion|
- msg.map! do |e|
- if e.is_a?(String)
- next [emotion, [e]]
- elsif e.is_a?(Array) && e[0].is_a?(String)
- next [emotion, e]
- else
- next e
- end
- end
- end
- if status != :NONE # If the Pokémon has one of the status conditions below
- if hp_fact < 0.25 # HP less than 25%
- msg << _INTL("[P] is dizzy.")
- msg << _INTL("[P] is going to fall down!")
- msg << _INTL("[P] seems about to fall over!")
- emote.call(PBEmotions::SAD)
- elsif hp_fact < 0.5 # HP less than 50%
- msg << _INTL("[P] is trying very hard to keep up with you...")
- msg << _INTL("[P] seems a little tired.")
- emote.call(PBEmotions::SAD)
- end
- if status == :BURN # Is burned
- msg << _INTL("[P]'s burn looks painful!")
- emote.call(PBEmotions::SAD)
- elsif status == :PARALYSIS # Has paralysis
- msg << _INTL("[P] is trying very hard to keep up with you...")
- emote.call(PBEmotions::SAD)
- elsif status == :POISON # Is poisoned
- msg << _INTL("[P] is shivering with the effects of being poisoned.")
- emote.call(PBEmotions::POISONED)
- elsif status == :FROZEN # Is frozen
- msg << [_INTL("[P] seems very cold...")]
- msg << _INTL("...Your Pokémon seems a little cold.")
- emote.call(PBEmotions::SAD)
- end
- end
- no_status_messages = msg.size == 0
- if happy < 50 || happy >= 100 # All emotions but UPSET (0-50, 100-255)
- if type == :FIRE && weather == :RAIN
- msg << _INTL("[P] is not happy.")
- msg << _INTL("[P] is stepping on your feet!")
- emote.call(PBEmotions::SAD)
- end
- end
- r = rand(100) + 1 # Random 1 - 100
- if happy >= 70 # Only if happiness is greater than or equal to 70 (default catch happiness)
- if r <= 15 # 15%
- msg << _INTL("[P] suddenly started walking closer!")
- if name.ends_with?('s') # ['s] vs [s']
- msg << _INTL("[P]' cheeks are becoming rosy!")
- else
- msg << _INTL("[P]'s cheeks are becoming rosy!")
- end
- msg << _INTL("Whoa! [P] suddenly hugged you!")
- msg << [_INTL("[P] nudged {1}, nudge back?", $Trainer.name), [
- ["Yes", _INTL("Your Pokémon is shouting happily!"), PBEmotions::EXCLAIM],
- ["No", _INTL("Your Pokémon seems a bit bored."), PBEmotions::NONE]
- ], 1]
- msg << _INTL("Whoa! [P] is suddenly playful!")
- msg << _INTL("[P] is rubbing against your legs!")
- msg << _INTL("[P] blushed.")
- msg << _INTL("Ah! [P] cuddled you!")
- msg << _INTL("[P] is regarding you with adoration!")
- msg << _INTL("[P] got closer to {1}!", $Trainer.name)
- msg << _INTL("[P] is keeping close to your feet.")
- emote.call(PBEmotions::LOVE)
- elsif r <= 25 # Another 10%
- msg << _INTL("[P] is showing off its agility!")
- msg << _INTL("[P] is moving around happily!")
- msg << _INTL("Whoa! [P] suddenly started dancing in happiness!")
- msg << _INTL("[P] is steadily keeping up with you!")
- msg << _INTL("[P] is happy skipping about.")
- msg << _INTL("[P] is singing and humming.")
- msg << _INTL("[P] is playfully nibbling at the ground")
- msg << _INTL("[P] is nipping at your feet!")
- msg << _INTL("[P] turned around and looked at you.")
- msg << _INTL("[P] is working hard to show off its mighty power!")
- msg << _INTL("Whoa! [P] suddenly danced in happiness!")
- msg << _INTL("[P] is cheeful!")
- msg << [_INTL("[P] is following you very closely! Do you want to give it a pat?"), [
- ["Yes", _INTL("Waah! Your Pokémon is acting very surprised!"), PBEmotions::EXCLAIM],
- ["No", _INTL("Your Pokémon is so very angry!"), PBEmotions::ANGRY]
- ], 1]
- msg << _INTL("[P] is jumping around in a carefree way!")
- if outside
- msg << _INTL("[P] is pulling out the grass")
- msg << _INTL("[P] is looking up at the sky.")
- msg << _INTL("[P] is clawing the grass!")
- msg << _INTL("[P] is rolling around in the grass.")
- msg << _INTL("[P] is playing around with a leaf.")
- msg << _INTL("[P] is noticing the scent of the grass.")
- msg << _INTL("[P] is playing around, plucking bits of grass.")
- msg << _INTL("[P] is happy to see what's outdoors!")
- if PBDayNight.isNight? # If at night
- msg << _INTL("Your Pokémon is staring spellbound at the night sky!")
- end
- else # Inside
- msg << _INTL("[P] is looking up at the ceiling.")
- end
- if weather == :RAIN # Is raining
- msg << _INTL("[P] is very happy about the rain.")
- msg << _INTL("[P] is playing in a puddle.")
- if ![:GROUND, :FIRE, :ROCK].include?(type)
- msg << _INTL("[P] seems to be happy about the rain!")
- end
- end
- emote.call(PBEmotions::JINGLE)
- elsif r <= 30 # Another 5%
- msg << _INTL("[P] is in danger of falling over!")
- msg << _INTL("[P] bumped into {1}!", $Trainer.name)
- msg << _INTL("[P] is perring down.")
- msg << _INTL("Your Pokémon stumbled and nearly fell!")
- msg << _INTL("[P] seems refreshed!")
- msg << _INTL("[P] seems to have found something!")
- msg << _INTL("[P] suddenly turned around and started barking!")
- msg << _INTL("[P] suddenly turned around!")
- msg << _INTL("Your Pokémon was surprised that you suddenly spoke to it!")
- msg << _INTL("[P] feels refreshed.")
- msg << _INTL("[P] is wobbling and seems about to fall over!")
- msg << _INTL("[P] is walking along cautiously.")
- msg << _INTL("[P] is getting tense with nervous energy!")
- msg << _INTL("[P] sensed something strange and was surprised!")
- msg << _INTL("[P] is scared and snuggled up to {1}!", $Trainer.name)
- msg << _INTL("[P] is feeling an unusual presence...")
- if pokemon.item > 0 # Is holding an item
- msg << _INTL("[P] almost forgot it was holding that {1}!", PBItems.getName(pokemon.item))
- end
- if weather == :RAIN # Is raining
- msg << _INTL("[P] seems to be very surprised that it is raining!")
- end
- if outside # Outside map
- msg << _INTL("[P] seems to have gotten caught in the clumps of grass!")
- msg << _INTL("[P] looked up at the sky and shouted loudly!")
- msg << _INTL("A cold wind suddenly blew by!")
- else # Indoor
- msg << _INTL("[P] slipped on the floor and seems likely to fall!")
- end
- if name != speciesname
- msg << _INTL("[P] doesn't seem to be used to its own name yet.")
- end
- emote.call(PBEmotions::EXCLAIM)
- elsif r <= 40 # Another 10%
- msg << _INTL("Your Pokémon is looking around restlessly for something.")
- msg << _INTL("Your Pokémon wasn't watching where it was going and ran into you!")
- msg << _INTL("Sniff, sniff! Is something nearby?")
- msg << [_INTL("[P] is holding something, do you want to take it?"), [
- ["Yes", _INTL("Oh! It seems just too important to let go!"), PBEmotions::ANGRY],
- ["No", _INTL("[P] seems happy to have found something!")]
- ], 1]
- msg << [_INTL("[P] is holding something, do you want to take it?"), [
- ["Yes", _INTL("[P] happily handed it over!"), PBEmotions::JINGLE],
- ["No", _INTL("[P] seems happy to have found something!")]
- ], 1]
- msg << _INTL("[P] is wandering around and searching for something...")
- msg << _INTL("[P] is sniffling at {1}.", $Trainer.name)
- msg << _INTL("[P] seems to be a little hesitant...")
- msg << [_INTL("[P] is heading your way with something in its mouth. Take the item out of its mouth?"), [
- ["Yes", _INTL("Your Pokémon seems sad..."), PBEmotions::SAD],
- ["No", _INTL("[P] seems happy to have found something!")]
- ], 1]
- if outside # Outside map
- msg << _INTL("[P] is rolling a pebble around.")
- end
- emote.call(PBEmotions::QUESTION)
- end
- end
- # If there aren't any messaged yet that would be displayed when you have
- # one of the status conditions defined above. This way, it will not
- # allow for happiness-related messages if you have one of the conditions.
- if no_status_messages
- case happy
- when 0...50
- msg << _INTL("[P] let out a roar!")
- msg << _INTL("[P] is making a face like it's angry!")
- msg << _INTL("[P] seems to be angry for some reason.")
- msg << [_INTL("Your Pokémon turned to face the other way, showing a defiant expression."),
- proc { event.direction = 10 - event.direction }
- ]
- msg << [_INTL("[P] chewed on your feet, scold it?"), [
- ["Yes", _INTL("Your Pokémon seems to be a bit dispondant...")],
- ["No", _INTL("Your Pokémon ate something that tasted bad and is trying to spit it out!"), PBEmotions::SAD]
- ], 1]
- msg << _INTL("[P] cried out!")
- emote.call(PBEmotions::ANGRY)
- when 50...100
- if type == :FIRE && weather == :RAIN && outside # Is Fire type and is raining
- msg << _INTL("[P] is taking shelter in the grass from the rain.")
- msg << _INTL("[P] is splashing around in the wet grass.")
- msg << _INTL("Your Pokémon doesn't like splashing around on the ground.")
- end
- msg << _INTL("[P] seems unhappy somehow...")
- msg << _INTL("[P] seems to feel a little claustrophobic.")
- msg << _INTL("[P] is a bit nervous about the narrow space!")
- msg << _INTL("[P] is making an unhappy face.")
- msg << _INTL("[P] seems uneasy and is poking {1}!", $Trainer.name)
- msg << [_INTL("[P] wants your attention now! Want to play along?"), [
- ["Yes", _INTL("Your Pokémon seems to be having fun!"), PBEmotions::JINGLE],
- ["No", _INTL("Your Pokémon is grumbling because it wants you to pay more attention to it!")]
- ], 1]
- msg << [_INTL("[P] seems a bit uneasy and is shuffling around nervously, say something?"), [
- ["Yes", _INTL("[P] feels safer just by seeing {1}'s face.", $Trainer.name)],
- ["No", _INTL("Oh! Your Pokémon seems about to fall...")],
- ], 1]
- emote.call(PBEmotions::UPSET)
- when 100...150
- msg << _INTL("[P] is looking down steadily.")
- msg << [_INTL("[P] is blankly staring in your direction... Do you want to call its name?"), [
- ["Yes", _INTL("Your Pokémon seems so happy!"), PBEmotions::VERYHAPPY],
- ["No", _INTL("Your Pokémon is in a daze."), PBEmotions::NONE]
- ], 1]
- msg << _INTL("[P] is surveying the area.")
- msg << _INTL("[P] is sniffling at the floor.")
- msg << _INTL("[P] is peering down.")
- msg << [_INTL("[P] is looking nervous. Would you like to say something?"), [
- ["Yes", _INTL("[P] seems shocked!"), PBEmotions::EXCLAIM],
- ["No", _INTL("Your Pokémon appears to be somewhat hardened and unable to move.")]
- ], 1]
- msg << _INTL("[P] seems to be wandering around.")
- msg << _INTL("[P] is looking around absentmindedly.")
- msg << _INTL("[P] yawned very loudly!")
- msg << _INTL("[P] is relaxing comfortably.")
- msg << _INTL("[P] is staring steadfastly at {1}'s face.", $Trainer.name)
- msg << _INTL("[P] is staring intently at {1}'s face.", $Trainer.name)
- msg << _INTL("[P] is focusing its attention on you.")
- msg << _INTL("[P] is staring into the depths.")
- msg << _INTL("Your Pokémon is staring intently at nothing.")
- msg << [_INTL("Your Pokémon turned to face the other way, showing a defiant expression."),
- proc { event.direction = 10 - event.direction }
- ]
- msg << _INTL("[P] focused with a sharp gaze!")
- msg << [_INTL("[P] seems a bit nervous, do you want to say something?"), [
- ["Yes", _INTL("Waah! Your Pokémon is acting very surprised!"), PBEmotions::EXCLAIM],
- ["No", _INTL("Your Pokémon appears to be somewhat hardened and unable to move.")]
- ], 1]
- msg << _INTL("[P] is concentrating.")
- msg << _INTL("[P] faced your way and nodded.")
- msg << _INTL("[P] seems a bit nervous...")
- msg << _INTL("[P] is looking at {1}'s footprints.", $Trainer.name)
- msg << _INTL("[P] is staring straight into {1}'s eyes.", $Trainer.name)
- msg << [_INTL("[P] seems to want to play and is gazing at you expectedly, will you give in?"), [
- ["Yes", _INTL("Your Pokémon is indescribably happy!"), PBEmotions::JINGLE],
- ["No", _INTL("Oh! Your Pokémon seems about to cry!"), PBEmotions::SAD]
- ], 1]
- msg << [_INTL("Your Pokémon is gazing restlessly at you as if it wants to play, will you give in?"), [
- ["Yes", _INTL("Your Pokémon jumped around happily!"), PBEmotions::JINGLE],
- ["No", _INTL("Oh! Your Pokémon seems about to cry!"), PBEmotions::SAD]
- ], 1]
- if outside # Outside map
- msg << _INTL("[P] seems to relax as it hears of rustling leaves...")
- msg << _INTL("[P] seems to be listening to the sound of rustling leaves...")
- end
- if type == :FIRE # Is a fire type
- msg << _INTL("[P] emitted fire and shouted!")
- end
- if status == :SLEEP # Is asleep
- msg << _INTL("[P] is somehow fighting off sleep...")
- end
- emote.call(PBEmotions::NONE)
- when 150...256
- msg << _INTL("[P] began poking you in the stomach!")
- msg << _INTL("[P] is happy but shy.")
- msg << _INTL("[P] is coming along happily.")
- msg << _INTL("[P] is composed!")
- msg << _INTL("[P] seems to be feeling great about walking with you!")
- msg << _INTL("[P] looks very happy!")
- msg << _INTL("[P] put in extra effort!")
- msg << _INTL("[P] is smelling the scents of the surrounding air.")
- msg << _INTL("[P] is jumping for joy!")
- msg << _INTL("[P] is still feeling great!")
- msg << _INTL("[P] is poking at your belly!")
- msg << _INTL("Your Pokémon stretched out its body and is relaxing.")
- msg << _INTL("[P] looks like it wants to lead!")
- msg << _INTL("[P] is doing its best to keep up with you!")
- msg << _INTL("[P] is happily cuddling up to you!")
- msg << _INTL("[P] seems to be very happy!")
- msg << _INTL("[P] is so happy that it can't stand still!")
- msg << _INTL("[P] nodded slowly.")
- msg << _INTL("[P] is wandering around and listening to the different sounds.")
- msg << _INTL("[P] looks very interested.")
- msg << _INTL("[P] gave you a sunny look!")
- msg << _INTL("[P] gave you a happy look and a smile!")
- msg << _INTL("[P] seems very happy to see you!")
- msg << _INTL("[P] faced your way and grinned.")
- msg << _INTL("[P] happily cuddled up to you!")
- if hp_fact >= 0.5 # More than 50% health
- msg << _INTL("[P] is glowing with health!")
- msg << _INTL("[P] is full of life!")
- else # LESS than 50% health
- msg << _INTL("[P] is somehow forcing itself to keep going.")
- end
- if weather != :RAIN # NOT raining
- msg << _INTL("Your Pokémon seems happy about the great weather.")
- end
- if outside # Outside map
- msg << _INTL("Your Pokémon is smelling the scent of flowers.")
- end
- emote.call([PBEmotions::HAPPY,PBEmotions::VERYHAPPY][rand(2)])
- end
- end
- r = rand(msg.size)
- msg = msg[r]
- e = msg[0]
- msg = msg[1]
- txt = msg[0].gsub(/\[P\]/, name)
- code = msg[1] if msg[1].is_a?(Proc)
- choices = msg[1] if msg[1].is_a?(Array)
- default = msg[2] if msg[2] && msg[2].is_a?(Numeric)
- if code
- code.call
- pbUpdateSceneMap
- end
- sprite.emotion(e)
- while sprite.emotion_playing?
- Graphics.update
- Input.update
- pbUpdateSceneMap
- end
- if choices
- idx = Kernel.pbMessage(txt, choices.map { |e| e[0] }, -1, nil, 0)
- idx = default if idx == -1
- txt = choices[idx][1].gsub(/\[P\]/, name)
- e = nil
- e = choices[idx][2] if choices[idx][2]
- sprite.emotion(e) if e
- while sprite.emotion_playing?
- Graphics.update
- Input.update
- pbUpdateSceneMap
- end
- Kernel.pbMessage(txt)
- else
- Kernel.pbMessage(txt)
- end
- end
- # Toggles the visibility of the follower
- def toggle
- return unless event && sprite && !$PokemonTemp.follower_coming_in &&
- !$PokemonTemp.follower_coming_out
- return if $game_player.moving? || $game_player.wasmoving
- if visible?
- hide
- else
- show
- end
- end
- # Hides the follower sprite (retraction, coming in)
- def hide
- return unless $PokemonGlobal.follower_visible
- $PokemonTemp.follower_coming_in = true
- ball = Sprite.new(sprite.viewport)
- ball.bitmap = Bitmap.new("Graphics/Characters/Following Pokemon/Balls/ball")
- ball.x = sprite.x
- ball.y = sprite.y + 8
- ball.ox = ball.bitmap.width / 2
- ball.oy = ball.bitmap.height
- ball.z = sprite.z - 1
- ball.opacity = 0
- n = 1
- 2.times do
- Graphics.update
- Input.update
- pbUpdateSceneMap
- sprite.zoom_x = 1
- sprite.zoom_y = 1
- ball.opacity += 128
- end
- 9.times do |i|
- Graphics.update
- Input.update
- pbUpdateSceneMap
- sprite.color = Color.new(255,255,255,255 * (i / 9.0))
- n -= 1 / 9.0
- if n == 3
- if sprite.respond_to?(:shadow) && sprite.shadow
- sprite.shadow.visible = false
- end
- end
- sprite.zoom_x = n
- sprite.zoom_y = n
- end
- sprite.visible = false
- ball.dispose
- sprite.visible = false
- $PokemonTemp.follower_coming_in = false
- $PokemonGlobal.follower_visible = false
- end
- # Shows the follower sprite (coming out)
- def show
- return if $PokemonGlobal.follower_visible
- $PokemonTemp.follower_coming_out = true
- ball = Sprite.new(sprite.viewport)
- ball.bmp("Graphics/Characters/Following Pokemon/Balls/ball")
- ball.x = sprite.x
- ball.y = sprite.y + 8
- ball.ox = ball.bmp.width / 2
- ball.oy = ball.bmp.height
- ball.z = sprite.z - 1
- ball.opacity = 0
- 2.times do
- Graphics.update
- Input.update
- pbUpdateSceneMap
- sprite.zoom_x = 0
- sprite.zoom_y = 0
- ball.opacity += 128
- end
- a = Sprite.new(sprite.viewport)
- a.bmp("Graphics/Characters/Following Pokemon/animation")
- a.src_rect.width = a.bmp.width / 4
- a.src_rect.x = -a.src_rect.width
- a.x = ball.x
- a.y = ball.y + 4
- a.ox = a.src_rect.width / 2
- a.oy = a.bmp.height
- a.z = sprite.z + 1
- n = 0
- 9.times do |i|
- Graphics.update
- Input.update
- pbUpdateSceneMap
- sprite.color = Color.new(255,255,255,255 * ((9 - i) / 9.0))
- n += 1 / 9.0
- sprite.zoom_x = n
- sprite.zoom_y = n
- if i > 0 && i % 2 == 0
- a.src_rect.x += a.src_rect.width
- end
- end
- 2.times do
- Graphics.update
- Input.update
- pbUpdateSceneMap
- ball.opacity -= 128
- end
- ball.dispose
- a.dispose
- sprite.visible = false
- $PokemonTemp.follower_coming_out = false
- $PokemonGlobal.follower_visible = true
- end
- end
- class Sprite_Character
- # Aliases [update] to allow for different [zoom_x] and [zoom_y] values
- alias follower_update update
- def update
- oldzx = self.zoom_x
- oldzy = self.zoom_y
- follower_update
- if Follower.event && @character == Follower.event && (oldzx != self.zoom_x ||
- oldzy != self.zoom_y)
- self.zoom_x = oldzx
- self.zoom_y = oldzy
- end
- # OW Shadows support
- @shadow.visible = false if @shadow && (self.zoom_x <= 0 || self.zoom_y <= 0)
- return unless @i
- case @i
- when 0...6
- @emotion.y -= 4
- when 6...10
- @emotion.y += 4
- @emotion.src_rect.x += @emotion.src_rect.width if @i == 9
- when 18
- @emotion.src_rect.x = 0
- when 26
- @emotion.src_rect.x += @emotion.src_rect.width
- when 46
- @emotion.dispose
- @emotion = nil
- @i = nil
- end
- @i += 1 if @i
- end
- # Plays the given emotion (PBEmotion, integer)
- def emotion(e)
- @emotion = Sprite.new(@viewport)
- @emotion.bmp("Graphics/Characters/Following Pokemon/Emotions/#{PBEmotions.getFile(e)}")
- @emotion.src_rect.width = 30
- @emotion.x = self.x
- @emotion.y = self.y - 46
- @emotion.z = self.z + 2
- @emotion.ox = @emotion.src_rect.width / 2
- @emotion.oy = @emotion.bmp.height
- @i = 0
- end
- # Returns whether or not the emotion is (still) playing
- def emotion_playing?
- return !@emotion.nil?
- end
- # Refreshes the direction value
- def refresh
- sx = @character.pattern * @cw
- sy = ((@character.direction - 2) / 2) * @ch
- self.src_rect.set(sx, sy, @cw, @ch)
- self.oy = (@spriteoffset rescue false) ? @ch - 16 : @ch
- self.oy -= @character.bob_height
- end
- end
- # Toggles the follower when pressing Control
- class << Input
- alias follower_update update
- def update
- follower_update
- # Same conditions as for moving the main player character - if you can't move,
- # you can't toggle your follower.
- return unless $game_player && $game_system && $PokemonTemp && $PokemonGlobal
- unless $game_player.moving? or $game_system.map_interpreter.running? or
- $game_player.move_route_forcing or $game_temp.message_window_showing or
- $PokemonTemp.miniupdate
- if Input.trigger?(Input::CTRL)
- Follower.toggle
- end
- end
- end
- end
- # Overwrites the save function to add some more data to the save file regarding
- # the follower's position/direction
- alias follower_save pbSave
- def pbSave(*args)
- e = Follower.event
- if e
- $PokemonGlobal.follower_data = [e.x, e.y, e.direction]
- nx, ny, nd = [e.x, e.y, e.direction]
- e.event.x = nx
- e.event.y = ny
- e.event.pages[0].graphic.direction = nd
- e.x, e.y, e.page.graphic.direction = nx, ny, nd
- end
- follower_save(*args)
- end
- #==============================================================================#
- # * PASSABILITY #
- #==============================================================================#
- class Game_Map
- alias follower_passable? passable?
- def passable?(x, y, d, self_event = nil)
- return follower_passable?(x, y, d, self_event)
- end
- alias follower_passableStrict? passableStrict?
- def passableStrict?(x, y, d, self_event = nil)
- return false if !valid?(x, y)
- # Implements bridges for the follower
- for i in [2, 1, 0]
- tile_id = data[x, y, i]
- tag = nil
- tag = @terrain_tags[tile_id] if tile_id
- if tag == PBTerrain::Bridge && self_event && self_event == Follower.event
- return true
- end
- end
- for event in events.values
- if event.tile_id >= 0 and event != self_event and
- event.x == x and event.y == y and not event.through
- if @terrain_tags[event.tile_id]!=PBTerrain::Neutral
- return false if @passages[event.tile_id] & 0x0f != 0
- return true if @priorities[event.tile_id] == 0
- end
- end
- end
- # Changed the regular passability check to support non-4-dir tile passabilities
- # as well (commonly used for bridges, for instance)
- bit = (1 << (d / 2 - 1)) & 0x0F
- for i in [2, 1, 0]
- tile_id = data[x, y, i]
- if @terrain_tags[tile_id] != PBTerrain::Neutral
- if @passages[tile_id] & bit != 0 ||
- @passages[tile_id] & 0x0f == 0x0f
- return false
- elsif @priorities[tile_id] == 0
- return true
- end
- end
- end
- return true
- end
- end
- class DependentEvents
- def pbFollowEventAcrossMaps(leader, follower, instant = false,
- leaderIsTrueLeader = true)
- d = leader.direction
- areConnected = $MapFactory.areConnected?(leader.map.map_id, follower.map.map_id)
- # Get the rear facing tile of leader
- facingDirection=[0,0,8,0,6,0,4,0,2][d]
- if !leaderIsTrueLeader && areConnected
- relativePos = $MapFactory.getThisAndOtherEventRelativePos(leader, follower)
- if (relativePos[1] == 0 && relativePos[0] == 2) # 2 spaces to the right of leader
- facingDirection = 6
- elsif (relativePos[1] == 0 && relativePos[0] == -2) # 2 spaces to the left of leader
- facingDirection = 4
- elsif relativePos[1] == -2 && relativePos[0] == 0 # 2 spaces above leader
- facingDirection = 8
- elsif relativePos[1] == 2 && relativePos[0] == 0 # 2 spaces below leader
- facingDirection = 2
- end
- end
- facings = [facingDirection] # Get facing from behind
- facings.push([0,0,4,0,8,0,2,0,6][d]) # Get right facing
- facings.push([0,0,6,0,2,0,8,0,4][d]) # Get left facing
- if !leaderIsTrueLeader
- facings.push([0,0,2,0,4,0,6,0,8][d]) # Get forward facing
- end
- mapTile = nil
- if areConnected
- bestRelativePos = -1
- oldthrough = follower.through
- follower.through = false
- for i in 0...facings.length
- facing = facings[i]
- tile = $MapFactory.getFacingTile(facing, leader)
- passable = tile && $MapFactory.isPassableStrict?(tile[0], tile[1], tile[2], follower)
- if i == 0 && !passable && tile &&
- PBTerrain.isLedge?($MapFactory.getTerrainTag(tile[0], tile[1], tile[2]))
- # If the tile isn't passable and the tile is a ledge,
- # get tile from further behind
- tile = $MapFactory.getFacingTileFromPos(tile[0], tile[1], tile[2], facing)
- passable = tile && $MapFactory.isPassableStrict?(tile[0], tile[1], tile[2], follower)
- end
- if passable
- relativePos = $MapFactory.getThisAndOtherPosRelativePos(follower,
- tile[0], tile[1], tile[2])
- distance = Math.sqrt(relativePos[0] ** 2 + relativePos[1] ** 2)
- if bestRelativePos == -1 || bestRelativePos > distance
- bestRelativePos = distance
- mapTile = tile
- end
- if i == 0 && distance <= 1 # Prefer behind if tile can move up to 1 space
- break
- end
- end
- end
- follower.through = oldthrough
- else
- tile = $MapFactory.getFacingTile(facings[0], leader)
- passable = tile && $MapFactory.isPassableStrict?(tile[0], tile[1], tile[2], follower)
- mapTile = passable ? mapTile : nil
- end
- if mapTile && follower.map.map_id == mapTile[0]
- # Follower is on same map
- newX = mapTile[1]
- newY = mapTile[2]
- deltaX = (d == 6 ? -1 : d == 4 ? 1 : 0)
- deltaY = (d == 2 ? -1 : d == 8 ? 1 : 0)
- posX = newX + deltaX
- posY = newY + deltaY
- follower.move_speed = leader.move_speed # sync movespeed
- if (follower.x - newX == -1 && follower.y == newY) ||
- (follower.x - newX == 1 && follower.y == newY) ||
- (follower.y - newY == -1 && follower.x == newX) ||
- (follower.y - newY == 1 && follower.x == newX)
- if instant
- follower.moveto(newX, newY)
- else
- pbFancyMoveTo(follower, newX, newY)
- end
- elsif (follower.x - newX == -2 && follower.y == newY) ||
- (follower.x - newX == 2 && follower.y == newY) ||
- (follower.y - newY == -2 && follower.x == newX) ||
- (follower.y - newY == 2 && follower.x == newX)
- if instant
- follower.moveto(newX, newY)
- else
- pbFancyMoveTo(follower, newX, newY)
- end
- elsif follower.x != posX || follower.y != posY
- if instant
- follower.moveto(newX, newY)
- else
- pbFancyMoveTo(follower, posX, posY)
- pbFancyMoveTo(follower, newX, newY)
- end
- end
- pbTurnTowardEvent(follower, leader)
- else
- if !mapTile
- # Make current position into leader's position
- mapTile = [leader.map.map_id, leader.x, leader.y]
- end
- if follower.map.map_id == mapTile[0]
- # Follower is on same map as leader
- follower.moveto(leader.x, leader.y)
- pbTurnTowardEvent(follower, leader)
- else
- # Follower will move to different map
- events = $PokemonGlobal.dependentEvents
- eventIndex = pbEnsureEvent(follower, mapTile[0])
- if eventIndex >= 0
- newFollower = @realEvents[eventIndex]
- newEventData = events[eventIndex]
- newFollower.moveto(mapTile[1], mapTile[2])
- newEventData[2] = mapTile[0]
- newEventData[3] = mapTile[1]
- newEventData[4] = mapTile[2]
- # Tweaks a few values to ensure the follower transition from
- # map A to map B is smoother.
- running = $game_player.pbCanRun?
- =begin
- newFollower.real_x = $game_player.real_x
- if d == 4
- if running
- newFollower.real_x += Game_Map.realResX - (2 ** $game_player.move_speed) / 0.58
- else
- newFollower.real_x += Game_Map.realResX - (2 ** $game_player.move_speed) / 5.0
- end
- elsif d == 6
- if running
- newFollower.real_x -= Game_Map.realResX - (2 ** $game_player.move_speed) / 0.58
- else
- newFollower.real_x -= Game_Map.realResX - (2 ** $game_player.move_speed) / 5.0
- end
- end
- =end
- newFollower.real_y = $game_player.real_y
- if d == 8
- if running
- newFollower.real_y += Game_Map.realResY - (2 ** $game_player.move_speed) / 0.58
- else
- newFollower.real_y += Game_Map.realResY - (2 ** $game_player.move_speed) / 5.0
- end
- elsif d == 2
- if running
- newFollower.real_y -= Game_Map.realResY - (2 ** $game_player.move_speed) / 0.58
- else
- newFollower.real_y -= Game_Map.realResY - (2 ** $game_player.move_speed) / 5.0
- end
- end
- #=end
- if mapTile[0] == leader.map.map_id
- pbTurnTowardEvent(follower, leader)
- end
- end
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement