=begin
#==============================================================================
** Player Switch
Author: Hime
Date: Aug 3, 2013
------------------------------------------------------------------------------
** Change log
Aug 3, 2013
- added ability to delete a player
Aug 12, 2012
- added Moghunter's character select scene as an option for player switch
Aug 9, 2012
- fixed bug where newly created players don't appear on the map immediately
May 23, 2012
- added support for multiple player event checks
May 22, 2012
- Initial release
------------------------------------------------------------------------------
This script allows you to control multiple players across the game.
Accessing the player-switch menu can be done by pressing the player-switch
key specified before.
To create a player, use the script call
$game_players.create_player(actor_id)
Where the actor_id is used to create the new player
You can also switch players directly using the call
$game_players.switch_player(player_id)
By default, the starting player ID is 1, and new player ID's increase
by 1
Multiple player support is also available during events.
If you need to check whether any players are at a specific position,
you can use the following conditional script call
any_players_here?
Similarly, if a specific player must be at that event position, you
can use
player_here?(player_id)
#==============================================================================
=end
$imported = {} if $imported.nil?
$imported["Tsuki_PlayerSwitch"] = true
#==============================================================================
# ** Configuration
#==============================================================================
module Tsuki
module Player_Switch
# Random things players say
Player_Speeches = [
"Hmm...",
"Huh?",
"What do you want?",
"Hey did you see that?",
"I'm bored",
"How boring",
"Can we go now?"
]
# use a better player switch scene
Use_Better_Scene = true
Idle_Player_Move_Type = 0 # 0 for idle, 1 for roam
# Duplicate actors can be created
Allow_Dupe_Actors = false
Switch_Key = :X # default "A" on your keyboard
end
end
#==============================================================================
# ** Rest of the script
#==============================================================================
module DataManager
class << self
alias :th_player_switch_create_game_objects :create_game_objects
alias :th_player_switch_make_save_contents :make_save_contents
alias :th_player_switch_extract_save_contents :extract_save_contents
end
def self.create_game_objects
th_player_switch_create_game_objects
$game_players = Game_Players.new
$game_parties = Game_Parties.new
end
def self.make_save_contents
contents = th_player_switch_make_save_contents
contents[:players] = $game_players
contents[:parties] = $game_parties
contents
end
def self.extract_save_contents(contents)
th_player_switch_extract_save_contents(contents)
$game_players = contents[:players]
$game_parties = contents[:parties]
end
end
module RPG
class Event
attr_accessor :player
end
end
class Game_System
attr_accessor :switch_disabled
attr_accessor :switch_fade
attr_accessor :player_roam
alias :th_player_switch_init_system :initialize
def initialize
th_player_switch_init_system
@switch_disabled = false
@switch_fade = true
@player_roam = 0
end
end
class Game_Map
include Tsuki::Player_Switch
alias :th_player_switch_init_map :initialize
def initialize
th_player_switch_init_map
@player_events = []
end
alias :th_player_switch_setup_map :setup
def setup(map_id)
th_player_switch_setup_map(map_id)
setup_player_events
end
def setup_player_events
index = @events.empty? ? 1 : @events.keys.max + 1
clear_player_events
events = create_player_events(index)
events.each_with_index do |event, i|
@events[index+i] = Game_PlayerEvent.new(@map_id, event)
@player_events << index+i
end
SceneManager.scene.refresh_spriteset if SceneManager.scene_is?(Scene_Map)
end
def create_player_events(index)
events = []
players = $game_players.other_players(@map_id)
players.each_with_index do |player, i|
leader = player.party.leader
event = RPG::Event.new(player.x, player.y)
event.id = index+i
event.player = player
add_balloon_animation(event.pages[0].list)
event.pages[0].move_type = $game_system.player_roam
event.pages[0].trigger = 0
event.pages[0].priority_type = 1
event.pages[0].graphic.character_name = leader.character_name
event.pages[0].graphic.character_index = leader.character_index
event.pages[0].graphic.direction = player.direction
events << event
end
return events
end
def add_balloon_animation(list)
list << RPG::EventCommand.new(101, 0, ["", 0, 0, 2])
list << RPG::EventCommand.new(401, 0, [Player_Speeches[rand(Player_Speeches.size - 1)]])
list << RPG::EventCommand.new
end
def clear_player_events
return if @player_events.nil?
@player_events.each do |id|
ev = @events[id]
next unless ev.is_a?(Game_PlayerEvent)
ev.player.update_position(ev.x, ev.y, ev.direction)
@events.delete(id)
end
@player_events = []
end
end
class Game_CharacterBase
def pos
[@x, @y]
end
end
class Game_PlayerEvent < Game_Event
attr_accessor :player
def initialize(map_id, event)
super
@player = event.player
end
end
class Game_Player
attr_accessor :party
attr_accessor :map_id
attr_accessor :player_id
alias :th_player_switch_init_player :initialize
def initialize
th_player_switch_init_player
@party = $game_party
@player_id = 0
end
def update_position(x, y, direction)
@x = x
@y = y
@direction = direction
moveto(x, y)
end
def save_map_info
@map_id = $game_map.map_id
end
def in_vehicle?
in_boat? || in_ship? || in_airship?
end
#--------------------------------------------------------------------------
# * Don't center on players that aren't the current player
#--------------------------------------------------------------------------
alias :th_player_switch_center :center
def center(x, y)
if @player_id == $game_player.player_id
th_player_switch_center(x, y)
end
end
end
class Game_Players
include Tsuki::Player_Switch
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@data = [nil]
@actors = []
@id = 1
setup
end
def setup
$game_player.party = $game_party
$game_player.player_id = 1
@data << $game_player
end
#--------------------------------------------------------------------------
# * Get Actor
#--------------------------------------------------------------------------
def [](actor_id)
@data[actor_id]
end
def size
@data.size
end
def all_players
@data[1..-1]
end
def update_position(player_id, x, y, direction)
@data[player_id].update_position(x, y, direction)
@data[player_id].moveto(x, y)
end
def other_players(map_id = $game_map.map_id)
@data.select {|player| player if player && player.player_id != @id && player.map_id == map_id}
end
def add_player(player)
@data << player
end
def switch
if @id == 1
switch_player(2)
else
switch_player(1)
end
end
def switch_player(id)
return if @id == id || !@data[id] || $game_player.transfer?
SceneManager.scene.fadeout(60) if SceneManager.scene_is?(Scene_Map) && $game_system.switch_fade
@id = id
$game_player.save_map_info
$game_player = @data[id]
$game_party = $game_player.party
$game_map.setup($game_player.map_id) if $game_map.map_id != $game_player.map_id
$game_player.center($game_player.x, $game_player.y)
$game_player.make_encounter_count
$game_player.refresh
$game_map.setup_player_events
SceneManager.scene.refresh_spriteset if SceneManager.scene_is?(Scene_Map)
SceneManager.scene.fadein(60) if SceneManager.scene_is?(Scene_Map) && $game_system.switch_fade
end
# create a new player with the specified actor as the leader
def create_player(actor_id, start_map_id=$data_system.start_map_id, start_x=$data_system.start_x, start_y=$data_system.start_y)
return if @actors.include?(actor_id) && !Allow_Dupe_Actors
@actors << actor_id
player = Game_Player.new
player.player_id = @data.size
player.moveto(start_x, start_y)
player.map_id = start_map_id
party = $game_parties.create_party(actor_id)
player.party = party
add_player(player)
$game_map.setup_player_events
end
def delete_player(player_id)
player = @data[player_id]
return unless player
@actors -= player.party.members.collect {|mem| mem.instance_variable_get(:@actor_id)}
@data.delete(player)
$game_map.setup_player_events
SceneManager.scene.refresh_spriteset if SceneManager.scene_is?(Scene_Map)
end
end
class Game_Parties
def initialize
@data = [nil]
setup
end
def setup
@data << $game_party
end
#--------------------------------------------------------------------------
# * Get Actor
#--------------------------------------------------------------------------
def [](party_id)
@data[party_id]
end
def add_party(party)
@data << party
end
def create_party(actor_id)
party = Game_Party.new
party.add_actor(actor_id)
add_party(party)
return party
end
end
class Game_Interpreter
def any_players_here?
$game_players.all_players.any? {|player| player.pos == $game_map.events[@event_id].pos}
end
def player_here?(player_id=1)
return unless $game_players[player_id]
$game_players[player_id].pos == $game_map.events[@event_id].pos
end
def delete_player(player_id)
$game_players.delete_player(player_id)
end
end
class Scene_Map < Scene_Base
include Tsuki::Player_Switch
alias :th_player_switch_update_scene :update_scene
def update_scene
th_player_switch_update_scene
update_switch_player unless scene_changing?
end
def update_switch_player
@player_switch ||= Input.trigger?(Switch_Key)
call_player_switch if @player_switch && !$game_player.moving? && !$game_system.switch_disabled || $game_player.transfer?
end
def call_player_switch
@player_switch = false
return if $game_map.interpreter.running?
if $game_players.size - 1 <= 2
$game_players.switch
else
Sound.play_ok
call_switch_scene
end
end
def call_switch_scene
if Tsuki::Player_Switch::Use_Better_Scene
SceneManager.call(Scene_Character_Select)
else
SceneManager.call(Scene_Switch)
end
end
#re-draw sprites
def refresh_spriteset
@spriteset.refresh_characters
end
end
class Scene_Switch < Scene_MenuBase
def start
super
create_switch_window
@switch_window.activate
end
def create_switch_window
@switch_window = Window_Switch.new(84, 100)
@switch_window.set_handler(:ok, method(:on_switch_ok))
@switch_window.set_handler(:cancel, method(:return_scene))
end
def on_switch_ok
player = @switch_window.item
$game_players.switch_player(player.player_id)
return_scene
end
end
class Window_Switch < Window_Selectable
def initialize(x, y)
super(x, y, window_width, window_height)
refresh
select(0)
end
def window_width
400
end
def window_height
240
end
def col_max
2
end
def item
@data && index >= 0 ? @data[index] : nil
end
def item_max
@data ? @data.size : 1
end
def make_item_list
@data = $game_players.all_players
end
def item_height
96
end
def draw_item(index)
player = @data[index]
if player
leader = player.party.leader
rect = item_rect(index)
rect.width -= 4
draw_actor_face(leader, rect.x + 32, rect.y)
end
end
def refresh
make_item_list
create_contents
draw_all_items
end
end