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
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.
|