#==============================================================================
# ** Prexus - Job Changer (v1.0)
#------------------------------------------------------------------------------
# This is a Job Changing system, made by Prexus. It does several things, up to
# and including changing Jobs:
# * You can change in between any Job in the 'Class' tab of the Database.
# * Experience is totalled for characters and their Jobs, individually.
# * Jobs gain levels, Jobs determine what skills you learn in the Class tab.
# * Job Levels/Exp are remembered when changing jobs.
# * An interface for changing jobs.
# * Interface will show available/unavailable skills when highlighting a job
# and pressing Shift.
#
# It also includes a Window_Base method (draw_seperator,) that is useful for
# drawing a fancy line to separate one area of a window from another, and the
# Window_Confirm class. A subclass of Window_Selectable that creates a small
# Yes/No confirmation window.
#
# To call the Job Changer interface, use $scene = Scene_ClassChange.new
# To increase the level of a specific job for an actor:
# <#Game_Actor>.class_level_up(ID of Class)
# For example:
# $game_party.members[0].class_level_up(2)
# Would increase the leading member's Warrior class level in the demo.
#
# - Changelog (v1.0)
# * Initial Release
#==============================================================================
ENEMY_CLASS_EXP = {
}
ENEMY_CLASS_EXP.default = -1 # Don't Change This Value (-1)
class Game_Actor < Game_Battler
attr_accessor :class_exp
attr_accessor :class_level
#--------------------------------------------------------------------------
alias prex_prof_g_actor_setup setup
#--------------------------------------------------------------------------
def setup(actor_id)
prex_prof_g_actor_setup(actor_id)
@class_exp = {}
@class_exp.default = 0
@class_level = {}
@class_level.default = 1
define_skills
end
#--------------------------------------------------------------------------
def define_skills(id = nil)
id = @class_id if id == nil
@skills = []
for i in $data_classes[id].learnings
learn_skill(i.skill_id) if i.level <= @class_level[id]
end
end
#--------------------------------------------------------------------------
def class_change_exp(exp, id = nil, show = false)
id = @class_id if id == nil
last_level = @class_level[id]
last_skills = skills
@class_exp[id] = [[exp, 9999999].min, 0].max
while @class_exp[id] >= @exp_list[@class_level[id]+1] and @exp_list[@class_level[id]+1] > 0
class_level_up(id)
end
while @class_exp[id] < @exp_list[@class_level[id]]
class_level_down(id)
end
if show and @class_level[id] > last_level
display_class_level_up(skills - last_skills, id)
end
end
#--------------------------------------------------------------------------
def class_exp_s(id = nil)
id = @class_id if id == nil
return @exp_list[@class_level[id]+1] > 0 ? @class_exp[id] : "-------"
end
#--------------------------------------------------------------------------
def next_class_exp_s(id = nil)
id = @class_id if id == nil
return @exp_list[@class_level[id]+1] > 0 ? @exp_list[@class_level[id]+1] : "-------"
end
#--------------------------------------------------------------------------
def next_class_rest_exp_s(id = nil)
id = @class_id if id == nil
return @exp_list[@class_level[id]+1] > 0 ?
(@exp_list[@class_level[id]+1] - @class_exp[id]) : "-------"
end
#--------------------------------------------------------------------------
def class_level_up(id = nil, adjust = false)
id = @class_id if id == nil
@class_level[id] += 1
@class_exp[id] = @exp_list[@class_level[id]]
if adjust
define_skills(id)
else
define_skills
end
end
#--------------------------------------------------------------------------
def class_level_down(id = nil, adjust = false)
id = @class_id if id == nil
@class_level[id] -= 1
@class_exp[id] = @exp_list[@class_level[id]]
if adjust
define_skills(id)
else
define_skills
end
end
#--------------------------------------------------------------------------
def class_gain_exp(exp, id = nil, show = false)
id = @class_id if id == nil
if double_exp_gain
class_change_exp(@class_exp[id] + exp * 2, id, show)
else
class_change_exp(@class_exp[id] + exp, id, show)
end
end
#--------------------------------------------------------------------------
def class_change_level(level, id = nil, show = false)
id = @class_id if id == nil
level = [[level, 99].min, 1].max
class_change_exp(@exp_list[level], id, show)
end
#--------------------------------------------------------------------------
def level_up
@level += 1
end
#--------------------------------------------------------------------------
def class_id=(class_id)
@class_id = class_id
for i in 0..4 # Remove unequippable items
change_equip(i, nil) unless equippable?(equips[i])
end
define_skills
end
#--------------------------------------------------------------------------
def display_class_level_up(new_skills, id)
$game_message.new_page
text = sprintf(Vocab::ClassLevelUp, @name, $data_classes[id].name, Vocab::level, @level)
$game_message.texts.push(text)
for skill in new_skills
text = sprintf(Vocab::ObtainSkill, skill.name)
$game_message.texts.push(text)
end
end
end
module Vocab
ObtainClassExp = "%s Class EXP were received!"
ClassLevelUp = "%s is now %s %s %s!"
end
class Game_Troop < Game_Unit
def class_exp_total
exp = 0
for enemy in dead_members
next if enemy.hidden
if ENEMY_CLASS_EXP[enemy.enemy.id] >= 0
exp += ENEMY_CLASS_EXP[enemy.enemy.id]
else
exp += enemy.exp
end
end
return exp
end
end
class Scene_Battle < Scene_Base
def display_exp_and_gold
exp = $game_troop.exp_total
gold = $game_troop.gold_total
class_exp = $game_troop.class_exp_total
$game_party.gain_gold(gold)
text = sprintf(Vocab::Victory, $game_party.name)
$game_message.texts.push('\|' + text)
if exp > 0
text = sprintf(Vocab::ObtainExp, exp)
$game_message.texts.push('\.' + text)
end
if class_exp > 0
text = sprintf(Vocab::ObtainClassExp, class_exp)
$game_message.texts.push('\.' + text)
end
if gold > 0
text = sprintf(Vocab::ObtainGold, gold, Vocab::gold)
$game_message.texts.push('\.' + text)
end
wait_for_message
end
#--------------------------------------------------------------------------
def display_level_up
exp = $game_troop.exp_total
class_exp = $game_troop.class_exp_total
for actor in $game_party.existing_members
last_level = actor.level
last_skills = actor.skills
actor.gain_exp(exp, true)
actor.class_gain_exp(class_exp, nil, true)
end
wait_for_message
end
end
class Scene_ClassChange < Scene_Base
def start
create_menu_background
create_windows
end
#--------------------------------------------------------------------------
def create_windows
@party_window = Window_CurrentParty.new
@class_window = Window_ClassPick.new(@party_window.member)
@skill_window = Window_ClassSkills.new
@show_window = Window_ShowSkills.new(@party_window.member)
@help_window = Window_Help.new
@help_window.visible = false
@help_window.close
@help_window.x = 48
@help_window.y = 280
@help_window.width = 448
@help_window.create_contents
@show_window.help_window = @help_window
@confirm_window = Window_Confirm.new
end
#--------------------------------------------------------------------------
def update_windows
@party_window.update
@class_window.update(@party_window.member)
@skill_window.update
@show_window.update
@help_window.update
@confirm_window.update
if @party_window.active
@skill_window.set(@party_window.member, nil)
elsif @class_window.active
@skill_window.set(@party_window.member, @class_window.item)
end
end
#--------------------------------------------------------------------------
def terminate
super
@party_window.dispose
@class_window.dispose
@skill_window.dispose
@show_window.dispose
@help_window.dispose
@confirm_window.dispose
end
#--------------------------------------------------------------------------
def update
super
update_windows
update_input
end
#--------------------------------------------------------------------------
def update_input
if @party_window.active
if Input.trigger?(Input::B)
Sound.play_cancel
$scene = Scene_Map.new
elsif Input.trigger?(Input::C)
Sound.play_decision
@class_window.active = true
@class_window.index = 0
@party_window.active = false
end
elsif @class_window.active
if Input.trigger?(Input::B)
Sound.play_cancel
@party_window.active = true
@class_window.active = false
@class_window.index = -1
elsif Input.trigger?(Input::C)
if @class_window.item.id == @class_window.member.class_id
Sound.play_buzzer
return
end
Sound.play_decision
@confirm_window.visible = true
@confirm_window.active = true
@confirm_window.index = 0
@confirm_window.open
@class_window.active = false
elsif Input.trigger?(Input::A)
Sound.play_decision
@show_window.set(@party_window.member, @class_window.item.id)
@show_window.active = true
@show_window.index = 0
@show_window.open
@help_window.visible = true
@help_window.open
@class_window.active = false
end
elsif @show_window.active
if Input.trigger?(Input::B)
Sound.play_cancel
@class_window.active = true
@show_window.active = false
@show_window.index = -1
@show_window.close
@help_window.close
end
elsif @confirm_window.active
if Input.trigger?(Input::B)
Sound.play_cancel
if @confirm_window.index == 1
@confirm_window.active = false
@confirm_window.index = -1
@confirm_window.close
@class_window.active = true
return
else
@confirm_window.index = 1
return
end
elsif Input.trigger?(Input::C)
case @confirm_window.index
when 0
Sound.play_decision
member = @class_window.member
member.class_id = @class_window.item.id
@confirm_window.active = false
@confirm_window.index = -1
@confirm_window.close
@class_window.refresh
@skill_window.refresh
@class_window.active = true
when 1
@confirm_window.active = false
@confirm_window.index = -1
@confirm_window.close
@class_window.active = true
return
end
end
end
end
end
class Window_Base < Window
def draw_seperator(x, y, width, height, color = Color.new(255, 255, 255))
edge = (width / 4)
self.contents.gradient_fill_rect(x, y, edge, height, Color.new(0, 0, 0, 0), color)
self.contents.fill_rect(x + edge, y, width / 2, height, color)
self.contents.gradient_fill_rect(x + width - edge, y, edge, height, color, Color.new(0, 0, 0, 0))
end
end
class Window_CurrentParty < Window_Selectable
def initialize
super(48, 80, 256, 99)
@item_max = $game_party.members.size
@column_max = 3
create_contents
self.index = 0
refresh
end
#--------------------------------------------------------------------------
def member
return $game_party.members[self.index]
end
#--------------------------------------------------------------------------
def refresh
for i in 0...@item_max
rect = item_rect(i)
self.contents.clear_rect(rect)
end
for i in 0...$game_party.members.size
rect = item_rect(i)
bitmap = Cache.character($game_party.members[i].character_name)
sign = $game_party.members[i].character_name[/^[\!\$]./]
if sign != nil and sign.include?('$')
cw = bitmap.width / 3
ch = bitmap.height / 4
else
cw = bitmap.width / 12
ch = bitmap.height / 8
end
n = $game_party.members[i].character_index
src_rect = Rect.new((n%4*3+1)*cw, (n/4*4)*ch, cw, ch)
self.contents.blt(rect.x, rect.y, bitmap, src_rect, 255)
end
end
#--------------------------------------------------------------------------
def item_rect(index)
rect = Rect.new(0, 0, 0, 0)
rect.width = (contents.width + @spacing) / @column_max - @spacing
rect.height = 32
rect.x = index % @column_max * (rect.width + @spacing)
rect.y = index / @column_max * 32
return rect
end
end
class Window_ClassPick < Window_Selectable
def initialize(member = nil)
super(48, 178, 256, 158)
@item_max = $data_classes.size - 1
create_contents
@member = member
self.index = -1
self.active = false
refresh
end
#--------------------------------------------------------------------------
def update(member = nil)
super()
return if member == @member
@member = member
refresh
end
#--------------------------------------------------------------------------
def member
return @member
end
#--------------------------------------------------------------------------
def item
return $data_classes[self.index + 1]
end
#--------------------------------------------------------------------------
def refresh
for i in 0..@item_max
rect = item_rect(i)
self.contents.clear_rect(rect)
end
for i in 1..@item_max
next unless $data_classes[i]
y = (i-1) * WLH
w = self.contents.width
self.contents.font.color.alpha = (@member.class_id == $data_classes[i].id ? 128 : 255)
self.contents.draw_text(0, y, w, WLH, $data_classes[i].name)
next unless @member
level = @member.class_level[$data_classes[i].id]
self.contents.draw_text(0, y, w, WLH, "Lv. " + level.to_s, 2)
end
end
#--------------------------------------------------------------------------
def item_rect(index)
rect = Rect.new(0, 0, 0, 0)
rect.width = (contents.width + @spacing) / @column_max - @spacing
rect.height = WLH
rect.x = index % @column_max * (rect.width + @spacing)
rect.y = index / @column_max * (WLH)
return rect
end
end
class Window_ClassSkills < Window_Base
def initialize(member = nil, class_obj = nil)
super(304, 80, 192, 256)
create_contents
@member = member
@class_obj = class_obj
refresh
end
#--------------------------------------------------------------------------
def member
return @member
end
#--------------------------------------------------------------------------
def item
return @class_obj
end
#--------------------------------------------------------------------------
def set(member, class_obj)
old_member = @member
@member = member
old_class_obj = @class_obj
@class_obj = class_obj
refresh if (old_member != @member) or (old_class_obj != @class_obj)
end
#--------------------------------------------------------------------------
def refresh
self.contents.clear
return unless @member
c = (@class_obj != nil ? @class_obj : $data_classes[@member.class_id])
x, y = 0, 0
w = self.contents.width
self.draw_actor_face(@member, x, y, 48)
self.draw_actor_name(@member, x + 52, y)
self.contents.draw_text(x + 52, y + WLH, w, WLH, $data_classes[@member.class_id].name)
self.draw_actor_level(@member, x, y + WLH*2)
self.draw_icon(142, self.contents.width - 24, y + WLH*2)
self.contents.draw_text(x, y + WLH*2, self.contents.width - 12, WLH, 'Skills', 2)
self.draw_seperator(x, y + WLH * 3 + 11, w, 2)
return unless @class_obj
self.contents.draw_text(x, y + WLH*4, w, WLH, c.name)
self.contents.font.color = system_color
self.contents.draw_text(x, y + WLH*5, w, WLH, "Class #{Vocab::level_a}")
self.contents.font.color = normal_color
self.contents.draw_text(x, y + WLH*5, w, WLH, @member.class_level[c.id], 2)
s1 = @member.class_exp_s(c.id)
s2 = @member.next_class_rest_exp_s(c.id)
s_next = sprintf(Vocab::ExpNext, Vocab::level)
self.contents.font.color = system_color
self.contents.draw_text(x, y + WLH * 7, w, WLH, Vocab::ExpTotal)
self.contents.draw_text(x, y + WLH * 8, w, WLH, s_next)
self.contents.font.color = normal_color
self.contents.draw_text(x, y + WLH * 7, w, WLH, s1, 2)
self.contents.draw_text(x, y + WLH * 8, w, WLH, s2, 2)
end
end
class Window_ShowSkills < Window_Selectable
def initialize(member, class_id = nil)
super(48, 80, 448, 200)
@member = member
@class_id = (class_id != nil ? class_id : @member.class_id)
@item_max = $data_classes[@class_id].learnings.size
@column_max = 3
create_contents
self.index = -1
self.active = false
self.openness = 0
refresh
end
#--------------------------------------------------------------------------
def set(member, class_id)
old_member = @member
@member = member
old_class_id = @class_id
@class_id = class_id
@item_max = $data_classes[@class_id].learnings.size unless @class_id == nil
create_contents
refresh
end
#--------------------------------------------------------------------------
def refresh
return if @class_id == nil
return if $data_classes[@class_id].learnings.empty?
for i in 0...@item_max
rect = item_rect(i)
learning = $data_classes[@class_id].learnings[i]
next unless learning
self.contents.font.color.alpha = (@member.class_level[@class_id] >= learning.level ? 255 : 128)
self.contents.draw_text(rect, $data_skills[learning.skill_id].name)
end
end
#--------------------------------------------------------------------------
def update_help
if $data_classes[@class_id].learnings.empty?
self.help_window.set_text('')
return
end
level = $data_classes[@class_id].learnings[self.index].level
skill = $data_skills[$data_classes[@class_id].learnings[self.index].skill_id]
self.help_window.set_text(skill == nil ? '' : "[Level #{level}] #{skill.description}")
end
end
class Window_Confirm < Window_Selectable
def initialize(index = -1)
super(192, 168, 160, 80)
create_contents
@item_max = 2
@column_max = 2
self.index = index
self.active = false
self.openness = 0
refresh
end
#--------------------------------------------------------------------------
def refresh
for i in 0..@item_max
rect = item_rect(i)
self.contents.clear_rect(rect)
end
self.contents.draw_text(0, 0, self.contents.width, WLH, "Confirm?", 1)
rect = item_rect(0)
self.contents.draw_text(rect, "Yes", 1)
rect = item_rect(1)
self.contents.draw_text(rect, "No", 1)
end
#--------------------------------------------------------------------------
def item_rect(index)
rect = Rect.new(0, 0, 0, 0)
rect.width = (contents.width + @spacing) / @column_max - @spacing
rect.height = WLH
rect.x = index % @column_max * (rect.width + @spacing)
rect.y = (index / @column_max * WLH) + WLH
return rect
end
end