Save-Point
KTelePort XP - Printable Version

+- Save-Point (https://www.save-point.org)
+-- Forum: Material Development (https://www.save-point.org/forum-8.html)
+--- Forum: Scripts Database (https://www.save-point.org/forum-39.html)
+---- Forum: RPGMaker XP (RGSS) Engine (https://www.save-point.org/forum-116.html)
+---- Thread: KTelePort XP (/thread-4339.html)



KTelePort XP - kyonides - 08-28-2012

KTelePort XP

Version: 1.7.7


by Kyonides (Kyonides-Arkanthos)



Introduction

By pressing a customizable button on the current game map, this script will allow the player to be teleported or transferred to another map via a scene that shows you a map, its name and all cities on it but no windows, only sprites. By pressing the keys you may move the sword like cursor. The cursor will turn into a red cross or x whenever you get a location you can't go to because you are already there or it's forbidden for some reason known to the game developer. By pressing a button you may change between maps and cities.

You may also change prices for all goods by activating a switch and defining the corresponding price variance for a land (not a map). This means that a few maps may sell goods at a different price than the others that belong to another land or country. (This is valid IF you are using the default scene and window shop scripts or modified versions of these scripts that do not alter their refresh methods.)

I know the images included are quite basic but you are still able to replace them if you edit the corresponding Constants to let the script find your own images.

Any ideas regarding how to fill the empty space below the map are welcome. (You may use a bigger map.)


Demo

DOWNLOAD from Mediafire

DOWNLOAD from Mega


Old Version of my Script

Code:
###  KTelePort XP ###
#    v 1.7.0 - 2012-08-28
#    v 1.3.2 - 2010-10-01
#    v 1.0.0 - 2009-03-28  (former KyoTeleTrans)
#    Scripter: Kyonides-Arkanthos

# Script call:

#    $scene = Scene_KTelePort.new

# Include all pictures required by this script in your game package!

# You should run the tool script to build your RXDATA file first. In that case,
# please disable this script while building the data file to prevent errors
# from showing up at all. Once the data file is available, disable the tool
# script before enabling this one. Go back and forth until you manage to place
# all of your map cities in their rightful location.

# Thereafter you should be able to automatically save all map IDs and x and y
# coordinates. If you still want to save some specific location not closed to
# some Player Transfer event, you can still do it.

# Now you can even change "world maps" on the menu if deemed necessary.

# You may also change goods prices in any land if the corresponding switch is
# activated (it has true as its current value).

module GameSys
  # Travel Button ID
  TRAVELBUTTON = Input::A
  # Location Fixed Switch ID
  LOCFIXSWID = 4
  # Allow Transfer Switch ID
  ALLOWTRANSFERSWID = 5
    # Allow Price Variances between lands (that may include several maps)
    LANDPRICESWID = 6
  # Set the Price Variance for each land
  SHOPPRICEVARIANCE = {1 => 1.25, 2 => 1.75, 3 => 1.5}
  # MapIDs Only - Fixed Map IDs and XY Coordinates
  LOCFIXED = [1,3]
  # MapIDs Only - Useless Maps that should not be automatically saved
  USELESSLOC = [2,4]
  # Arrow Icon Filename
  SWORDICON = 'sword'
  # Error Icon Filename
  ERRORICON = 'wrong'
  # Error Message - You already saved the XY coord. and fixed them
  LOCFIXNSAVEDERROR = "Location could not be saved.\n\n"
            "It might have been saved previously." +
            "Is the Map ID included in LOCFIXED Array?"
end

module Map
  class Land
    def initialize
      @id = 0
      @name = ''
      @filename = ''
      @city_ids = []
      @allegiance = []
    end
    attr_accessor :id, :name, :filename, :city_ids, :allegiance
  end

  class City
    def initialize
      @id = 0
      @x = 0
      @y = 0
      @land_id = 0
      @filename = ''
    end
    attr_accessor :id, :x, :y, :land_id, :filename
  end
  Infos = load_data('Data/MapInfos.rxdata')
  Lands = load_data('Data/MapLandInfos.rxdata')
  Cities = load_data('Data/MapCityInfos.rxdata')
  module_function
  def name(map_id) Infos[map_id].name.sub(/@.*/, '') end

  def land_filename(land_id) Lands[land_id].filename.gsub(/(@.*| )/,'') end

  def land_name(land_id) Lands[land_id].name.gsub(/(@.*)/,'') end

  def allegiance(land_id) Lands[land_id].allegiance.gsub(/(@.*| )/,'') end

  def land_city_ids(land_id) Lands[land_id].city_ids end

  def land_id(map_id)
    return Cities[map_id].land_id if !Cities[map_id].nil?
    return Infos[map_id].name[/#\d+#/].gsub(/#/,'').to_i
  end

  def city_filename(map_id) Cities[map_id].filename.sub(/@.*/, '') end

  def city_x(map_id) Cities[map_id].x end

  def city_y(map_id) Cities[map_id].y end
end

class Game_System
  attr_reader :locations, :all_locations
  attr_accessor :force_memorize_location
  alias kyon_mapid_coord_gm_sys_init initialize
  def initialize
    kyon_mapid_coord_gm_sys_init
    @locations, @all_locations = {}, []
    @force_memorize_location = false
  end

  def new_location(*args)
    args.flatten!
    return if Map::Cities[args[0]].nil?
    if !@locations.has_key?(args[0]) or !location_fixed?(args[0])
      memorize_location(args[0], args[1], args[2], args[3], args[4])
    elsif @locations.has_key?(args[0]) and location_fixed?(args[0])
      if @force_memorize_location
        force_memorize_location = false
        return memorize_location(args[0], args[1], args[2], args[3], args[4])
      end
        land_id = Map.land_id(args[0])
      [args[0]] + @locations[land_id][args[0]][0,2]
    end
  end

  def all_locations; @all_locations end

  def location_fixed?(map_id)
    land_id = Map.land_id(map_id)
    @locations[land_id][map_id][3]
  end

  def forget_location(map_id)
    land_id = Map.land_id(map_id)
    @all_locations.delete map_id
    @locations[land_id].delete map_id
  end

  def free_location(map_id)
    land_id = Map.land_id(map_id)
    @locations[land_id][map_id][5] = false
  end

  def forbidden_location(map_id)
    land_id = Map.land_id(map_id)
    @locations[land_id][map_id][5] = true
  end

  def location_forbidden?(map_id)
    land_id = Map.land_id(map_id)
    @locations[land_id][map_id][5]
  end
  private
  def memorize_location(map_id, x, y, dir, fixed)
    @all_locations << map_id
      land_id = Map.land_id(map_id)
      @locations[land_id] ||= {}
    @locations[land_id][map_id] = [x, y, dir, !fixed ? false : fixed, false]
    [map_id, x, y]
  end
end

class Game_Map
  alias kyon_mapid_coord_gm_map_setup setup
  def setup(map_id)
    $game_variables[0] = map_id if $game_variables[0] != map_id
    $game_variables[0] = 0 if GameSys::USELESSLOC.include?(map_id)
    kyon_mapid_coord_gm_map_setup(map_id)
  end
end

class Game_Player
  alias kyon_mapid_coord_gm_play_move2 moveto
  def moveto(x, y)
    if $game_variables[0] > 0
      fixed = $game_switches[GameSys::LOCFIXSWID]
      fixed = true if GameSys::LOCFIXED.include?($game_variables[0])
      dir = $game_system.locations.size > 0? $game_temp.player_new_direction : 2
      dir = $game_player.direction if $game_temp.player_new_direction == 0
      $game_system.new_location($game_variables[0], x, y, dir, fixed)
      $game_variables[0] = 0
    end
    kyon_mapid_coord_gm_play_move2(x, y)
  end
end

class Interpreter
  def memorize_location
    map_id, x, y = $game_map.map_id, $game_player.x, $game_player.y
    if $game_system.location_fixed?(map_id)
      print GameSys::LOCFIXNSAVEDERROR
      return false
    end
    $game_system.new_location(map_id, x, y, $game_player.direction, true)
    return true
  end

  def force_memorize_location
    map_id, x, y = $game_map.map_id, $game_player.x, $game_player.y
    $game_system.force_memorize_location = true
    $game_system.new_location(map_id, x, y, $game_player.direction, true)
    return true
  end

  def forget_location(map_id=0)
    $game_system.forget_location(map_id > 0 ? $game_map.map_id : map_id)
  end

  def forbidden_location(map_id=0)
    $game_system.forbidden_location(map_id > 0 ? $game_map.map_id : map_id)
  end

  def free_location(map_id=0)
    $game_system.free_location(map_id > 0 ? $game_map.map_id : map_id)
  end
end

unless defined?(Scene_BaseMod)
class Scene_BaseMod
  def main
    start
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    terminate
  end

  def start; end
  def update; update_all_windows end
  def terminate
    dispose_all_windows
    dispose_all_viewports
    dispose_all_sprites
  end

  def update_all_windows # From VX ACE
    instance_variables.each do |varname|
      ivar = instance_variable_get(varname)
      ivar.update if ivar.is_a?(Window)
    end
  end

  def dispose_all_windows # From VX ACE
    instance_variables.each do |varname|
      ivar = instance_variable_get(varname)
      ivar.dispose if ivar.is_a?(Window)
    end
  end

  def dispose_all_viewports
    instance_variables.each do |varname|
      ivar = instance_variable_get(varname)
      ivar.dispose if ivar.is_a?(Viewport)
    end
  end

  def dispose_all_sprites
    instance_variables.each do |varname|
      ivar = instance_variable_get(varname)
      ivar.dispose if ivar.is_a?(Sprite) or ivar.is_a?(RPG::Sprite)
    end
  end
end
end

class Sprite_KyoArrow < Sprite
  attr_reader :index
  def initialize(viewport, land_id, ids, coordxy)
    @viewport, @coordxy = viewport, coordxy
    @ids, @max = ids, coordxy[land_id].size
    @original_land_id = @land_id = land_id
        @land_index = @ids.keys.sort.index(@land_id)
    @coordxy_ids = @coordxy[land_id].keys.sort
    @index = @ids[@land_id].sort.index($game_map.map_id)
    @index = 0 if @index.nil?
    @original_index = @index
    @icon, @last_icon = GameSys::SWORDICON, ''
    super(@viewport)
    self.z = 2000
  end

  def update
    if Input.trigger?(Input::RIGHT) or Input.trigger?(Input::UP)
      $game_system.se_play($data_system.cursor_se)
      @index = (@index + 1) % @max
      update_cursor
    elsif Input.trigger?(Input::LEFT) or Input.trigger?(Input::DOWN)
      $game_system.se_play($data_system.cursor_se)
      @index = @index > 0 ? @index - 1 : @max - 1
      update_cursor
        elsif Input.trigger?(GameSys::TRAVELBUTTON)
          return if $game_system.all_locations.size == 1
      @land_index = (@land_index + 1) % @ids.keys.size
            @land_id = @ids.keys.sort[@land_index]
            @max = @coordxy[@land_id].size
      @index = @land_id == @original_land_id ? @original_index : 0
            update_cursor
    end
  end

  def update_cursor
    id = @ids[@land_id].sort[@index]
    forbidden = $game_system.location_forbidden?(id)
    icon = @icon
    @icon = GameSys::ERRORICON
    if !forbidden && @ids[@land_id].sort[@index] != $game_map.map_id
          @icon = GameSys::SWORDICON
        end
    update_arrow unless icon == @icon
        update_coordinates
  end
  
  def update_arrow
    self.bitmap.dispose if self.bitmap != nil
    self.bitmap = RPG::Cache.picture(@icon)
  end

  def update_coordinates
    id = @ids[@land_id].sort[@index]
    coords = @icon == GameSys::SWORDICON ? [8, -16] : [-4, -8]
    self.x = @coordxy[@land_id][id][0] + coords[0]
      self.y = @coordxy[@land_id][id][1] + coords[1]
  end
end

class Sprite_KyoCity < Sprite
  def initialize(viewport, picture, id, x, y, ox=0, oy=0)
    @viewport = viewport
    @viewport.z = 2500
    super(@viewport)
    @id = id
    self.bitmap = RPG::Cache.picture(picture)
    self.x, self.y, self.z = x, y, 200
    self.ox, self.oy = ox, oy
    self.zoom_x, self.zoom_y = 0.45, 0.45
    refresh
  end
  
  def dispose; self.bitmap.dispose; super end
  
  def refresh
    forbidden = $game_system.location_forbidden?(@id)
    self.opacity = (!forbidden or @id != $game_map.map_id)? 255 : 140
  end
end

class Sprite_KyoCityName < Sprite
  def initialize(viewport, city, x, y, id)
    super(viewport)
    @city, @id, @disabled = city, id, []
    self.bitmap = Bitmap.new(96, 44)
    self.bitmap.font.name = 'Arial'
    self.bitmap.font.size = 16
    self.x, self.y, self.z = x, y, 400
    update
  end
  
  def dispose; self.bitmap.dispose; super end
  
  def update
    super
    self.bitmap.font.bold = self.visible = true
    forbidden = $game_system.location_forbidden?(@id)
    opacity = (!forbidden or @id != $game_map.map_id)? 255 : 140
    self.bitmap.font.color.set(255, 255, 255, opacity)
    self.bitmap.draw_text(self.bitmap.rect, @city, 1)
  end
end

class Window_ShopBuy
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    @original_prices ||= []
    switch = $game_switches[GameSys::LANDPRICESWID]
    land_id = Map.land_id($game_map.map_id)
    for goods_item in @shop_goods
      item = case goods_item[0]
      when 0; $data_items[goods_item[1]]
      when 1; $data_weapons[goods_item[1]]
      when 2; $data_armors[goods_item[1]]
      end
      if item != nil
        @data.push(item)
        if switch and @original_prices.size == @data.size - 1
          @original_prices << @data.last.price
          price = @data.last.price * GameSys::SHOPPRICEVARIANCE[land_id]
          @data.last.price = price.round
        end
      end
    end
    @item_max = @data.size
    return unless @item_max > 0
    self.contents = Bitmap.new(width - 32, row_max * 32)
    for i in 0...@item_max
      draw_item(i)
    end
  end

  alias kyon_mapid_coord_win_shopbuy_dispose dispose
  def dispose
    @data.each_index {|index| @data[index].price = @original_prices[index]}
    kyon_mapid_coord_win_shopbuy_dispose
  end
end

class Window_ShopSell
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    @original_prices ||= []
    land_id = Map.land_id($game_map.map_id)
    for i in 1...$data_items.size
      next unless $game_party.item_number(i) > 0
      @data.push($data_items[i])
      update_goods_prices(land_id)
    end
    for i in 1...$data_weapons.size
      next unless $game_party.weapon_number(i) > 0
      @data.push($data_weapons[i])
      update_goods_prices(land_id)
    end
    for i in 1...$data_armors.size
      next unless $game_party.armor_number(i) > 0
      @data.push($data_armors[i])
      update_goods_prices(land_id)
    end
    @item_max = @data.size
    return unless @item_max > 0
    self.contents = Bitmap.new(width - 32, row_max * 32)
    for i in 0...@item_max
      draw_item(i)
    end
  end

  def update_goods_prices(land_id)
    return if (!$game_switches[GameSys::LANDPRICESWID] or
      @original_prices.size != @data.size - 1)
    @original_prices << @data.last.price
    price = @data.last.price * GameSys::SHOPPRICEVARIANCE[land_id]
    @data.last.price = price.round
  end

  alias kyon_mapid_coord_win_shopsell_dispose dispose
  def dispose
    @data.each_index {|index| @data[index].price = @original_prices[index]}
    kyon_mapid_coord_win_shopsell_dispose
  end
end

class Scene_KTelePort < Scene_BaseMod
  def start
    @id = $game_map.map_id
    @land_id = Map.land_id(@id)
    @mapname = Map.land_name(@land_id)
    @cities_xy, @city_files, @city_names, @land_city_ids = {}, {}, {}, {}
    $game_system.locations.each {|land_id, ids| @land_city_ids[land_id] = []
      ids.each {|idnvalues| @land_city_ids[land_id] << idnvalues[0] } }
    city_files_names_coordinates_setup
        @ids = @land_city_ids[@land_id]
    @land_index = @land_city_ids.keys.sort.index(@land_id)
    update_current_map_mapname_sprites(true)
    @viewport1 = Viewport.new(0, 0, 640, 480)
    @viewport2 = Viewport.new(0, 0, 192, 40)
    @places_sprites, @names_sprites = [], []
    update_names_places
    @arrow = Sprite_KyoArrow.new(@viewport1,@land_id,@land_city_ids,@cities_xy)
    @arrow.update_cursor
    @forbidden = @ids.map {|id| id if $game_system.location_forbidden?(id)}
  end

  def terminate
    super
    @ids.clear
    @land_city_ids.clear
    @cities_xy.clear
    @city_files.clear
    @city_names.clear
    @places_sprites.clear
    @names_sprites.clear
    @forbidden.clear
  end

  def update
    @arrow.update
    if Input.trigger?(GameSys::TRAVELBUTTON)
      if @land_city_ids.keys.size == 1
        $game_system.se_play($data_system.buzzer_se)
        return
      else
        $game_system.se_play($data_system.decision_se)
        update_lands_info_on_screen
        return
      end
    elsif Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
    elsif Input.trigger?(Input::C)
      @current_id = @ids.sort[@arrow.index]
      if @forbidden.include?(@current_id) or @current_id == @id
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      x_y = $game_system.locations[@land_id][@current_id][0,2]
      dir = $game_system.locations[@land_id][@current_id][2]
      quick_transfer(x_y[0], x_y[1], dir)
      $scene = Scene_Map.new
    end
  end

    def city_files_names_coordinates_setup
      @land_city_ids.sort.each {|land_id, ids| @cities_xy[land_id] = {}
          @city_files[land_id], @city_names[land_id] = {}, {}
          ids.sort.each {|id| @city_names[land_id][id] = Map.name(id)
            @cities_xy[land_id][id] = [Map.city_x(id), Map.city_y(id)]
        @city_files[land_id][id] = Map.city_filename(id) } }
    end

  def update_current_map_mapname_sprites(start=false)
      if start;   @map = Sprite.new
    else
      @land_id = Map.land_id(@ids.sort[@arrow.index])
      @mapname = Map.land_name(@land_id)
      @mapname_sprite.bitmap.dispose
        end
    @map.bitmap = RPG::Cache.picture(Map.land_filename(@land_id))
        @map.z = 0
    @mapname_sprite = Sprite.new(@viewport2)
    @mapname_sprite.bitmap = Bitmap.new(192, 44)
    @mapname_sprite.bitmap.font.bold = true
    @mapname_sprite.bitmap.font.size = 26
    @mapname_sprite.bitmap.font.color.set(140, 220, 220)
    @mapname_sprite.bitmap.draw_text(0, 0, 192, 36, @mapname, 1)
  end

  def update_lands_info_on_screen
    lands = @land_city_ids.keys.size
    land_index = @land_city_ids.keys.sort.index(@land_id)
    @land_index = (land_index + 1) % lands
    @land_id = @land_city_ids.keys.sort[@land_index]
    @ids = @land_city_ids[@land_id]
    @cities_xy[@land_id] ||= {}
    @city_files[@land_id] ||= {}
    @city_names[@land_id] ||= {}
    update_current_map_mapname_sprites
    @places_sprites.each {|sprite| sprite.dispose}
    @names_sprites.each {|sprite| sprite.dispose}
    @places_sprites.clear
    @names_sprites.clear
    update_names_places
  end

  def update_names_places
    @ids.each {|id| x, y = @cities_xy[@land_id][id]
      file, city = @city_files[@land_id][id], @city_names[@land_id][id]
      @places_sprites << Sprite_KyoCity.new(@viewport1, file, id, x, y)
      @names_sprites << Sprite_KyoCityName.new(@viewport1, city, x-32, y+10,id)}
  end

  def quick_transfer(x, y, dir)
    $game_system.se_play(RPG::AudioFile.new('020-Teleport03'))
    $game_map.setup(@current_id)
    $game_player.moveto(x, y)
    case dir
    when 0; $game_player.direction
    when 2; $game_player.turn_down
    when 4; $game_player.turn_left
    when 6; $game_player.turn_right
    when 8; $game_player.turn_up;  end
    $game_player.straighten
    $game_map.autoplay
  end
end

class Scene_Map
  alias kyon_mapid_coord_sc_map_up update
  def update
    kyon_mapid_coord_sc_map_up
    if Input.trigger?(GameSys::TRAVELBUTTON)
      if $game_system.all_locations.size < 2 or
                !$game_switches[GameSys::ALLOWTRANSFERSWID]
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      $scene = Scene_KTelePort.new
    end
  end
end


Instructions

Paste below Scene_Debug and above Main. After that, read the instructions, check the Constants
included in KTelep module, edit them and include all required images. Keep in mind that there is the KTelePort script and a script tool. Only one of them may be enabled at the same time but never both of them. After finishing editing your project and before you pack the demo or full game, you may want to remove the tool script.

The script tool allows you to setup all the coordinates of the city sprites. Below the script tool code you may find a template (in Spanish and English) for both TXT files required by the tool script. It is not hard to edit the TXT files, just check the ones I left in the demo package called MapCity.txt and MapLand.txt.

That is pretty much all you
need to do besides testing your demo.


FAQ

I know that the language used in the demo is not English but Spanish, I just forgot to translate the dialogs...


Compatibility

Designed for RPG Maker XP.


Terms and Conditions

Free for use but not meant for commercial projects, still you can contact me if you need it... Due credit is not optional but a must.


RE: KTelePort XP - kyonides - 11-15-2016

¡The Bump Got Teleported!

Well, I just uploaded a new version of my teleport script, but I got to warn you that the demo is in Spanish only. Probably I'll upload another one in English some day. What makes me post this stuff is that it now includes an animated way to transfer the player from the initial map to the second one. Once you picked a new destination in the teleport menu, it will show you how your character gets prepared for teleportation, then a map transition comes next and later you'll see a second animation taking place on a new map letting you know the character has finally arrived without harm! Is isn't quite good looking? XD


RE: KTelePort XP - kyonides - 11-15-2016

Should The Bump Be Teleported Instantly?

I could somehow say that was the question regarding the quick and slow teleportation processes. Now both of them include animations, but the slow one also shows a transition inbetween plus a second animation. I hope you all like these small improvements as much as I do! I also had to fix a small almost imperceptible bug there.