12-05-2016, 10:11 AM
(12-05-2016, 04:21 AM)kyonides Wrote: Well, so far I have tested my script, skills don't get deleted unless you didn't learn the replacement skills and the corresponding variable is set to true, if it's nil or false, then it should keep them. Nope, all new skills learned one way or another remained there as expected. So unless you could tell me you included another skill related script there, your issue puzzles me.
Yes, there is! MAX = Any number would tell you how many skills an actor may learn before the next one triggers the open menu feature.
I didint include another script, I jusrt opened your recent demo and included the latest version.
When I replaced a skill with a skill from the "new skill" it vanishes off.
Heres the script:
Code:
# KSkillMax XP
# Scripter : Kyonides-Arkanthos
# v 1.2.12 - 2016-12-02
# Plug & Play Script
# This script allows the game dev to limit the maximum number of skills that a
# hero can use during gameplay. Whenever they have reached this maximum, a new
# menu will show up to tell the player that there is a need to replace some
# skills if they really want to learn new ones.
# The CLEAR_SKILLS_NOT_LEARNED Constant allows the game dev to define whether
# or not the skills heroes will not learn will be discarded before going back
# to the map scene.
# OPTIONAL
# The following script calls may allow the game dev to change the maximum
# number of skills a heroe may remember.
# SCRIPT CALLS
# # INCREASE or DECREASE Maximum Number of Skills #
# $game_party.actors[INDEX].skill_limit += NUMBER
# $game_party.actors[INDEX].skill_limit -= NUMBER
# The Following Script Call is optional, you would only use it if you
# want to let the player check and modify their unlearned skills even if
# they didn't learn a new skill by leveling up or by purchasing a skill at
# a skill shop (that would be possible if you add my KSkill Shop XP script
# and place it below KSkillMax XP).
# $scene = Scene_SkillMax.new
module KSkill
# Maximum Number of Skills to be learned by a hero
MAX = 3
# Will the Maximum Number of Skills be increased by Leveling Up?
LVLUPINCREASE = true
# Increase of Skills After reaching specific Levels : Level => Increase
LVLUPMAX = { 10 => 1, 20 => 1, 40 => 2 }
# Replacement Icon Name
OLD_SKILL_ICON = '047-Skill04'
NEW_SKILL_ICON = '048-Skill05'
# Buttons to display Old and New Skill Data Windows
INFOBUTTONID = Input::A
# Delete Skills Heroes did not learn: YES - true, NO - false or nil
CLEAR_SKILLS_NOT_LEARNED = false
# Help Menu Titles
NOEXTRASKILLS = 'There is no need for any hero to learn new skills'
REACHEDMAX = 'There are heroes that cannot learn more skills'
REPLACESKILLS = 'Which skills do you want to replace with new ones?'
AREYOUSURE = 'Are you really positive about applying these changes?'
REPLACEMENTSLEFT = "Replacement Skills Left: %s"
HEROES = 'Heroes'
LEARNEDSKILLS = 'Learned Skills'
NEWSKILLS = 'New Skills'
EXITOPTIONS = ['Apply Changes', 'Review Changes', 'No Changes']
LABELS = {} # DO NOT EDIT THIS LINE
LABELS[nil] = 'None'
LABELS[:target] = 'Target'
LABELS[0] = LABELS[nil]
LABELS[1] = '1 Enemy'
LABELS[2] = 'Enemies'
LABELS[3] = '1 Ally'
LABELS[4] = 'Allies'
LABELS[5] = 'Dead Ally'
LABELS[6] = 'Dead Allies'
LABELS[7] = 'User'
LABELS[:cost] = 'Cost' # Costo de Habilidad o Técnica
LABELS[:power] = 'Power' # Poder o Fuerza de la Técnica
LABELS[:str] = 'STR' # Fuerza de la Técnica
LABELS[:int] = 'INT' # Inteligencia de la Técnica
LABELS[:agi] = 'AGI' # Agilidad de la Técnica
LABELS[:dex] = 'DEX' # Destreza de la Técnica
LABELS[:pdef] = 'PDEF' # Defensa Física de la Técnica
LABELS[:mdef] = 'MDEF' # Defensa Mágica de la Técnica
LABELS[:eva] = 'EVA' # Evasión de la Técnica
OCCASIONS = {} # DO NOT EDIT THIS LINE
OCCASIONS[:occasion] = 'Occasion'
OCCASIONS[0] = 'Always'
OCCASIONS[1] = 'In Battle'
OCCASIONS[2] = 'From Menu'
OCCASIONS[3] = 'Never'
# STOP! NO MORE EDITS REQUIRED
@help_actors = []
@replacements = 0
LVLUPMAX.default = 0
class << self
attr_accessor :help_actors, :replacements, :open_menu
end
end
class Game_Actor
attr_accessor :pending_skills
attr_reader :skills_not_learned
alias kyon_skill_limit_gm_actor_init initialize
def initialize(actor_id)
@limit_breaker = 0
@skills_not_learned = []
kyon_skill_limit_gm_actor_init(actor_id)
end
def learn_skill(sid)
return unless sid > 0 and !skill_learn?(sid)
if @skills.size == KSkill::MAX + @limit_breaker
KSkill.help_actors << @actor_id if !KSkill.help_actors.include?(@actor_id)
@skills_not_learned << sid
@skills_not_learned = @skills_not_learned.uniq.sort
return
end
@skills << sid
@skills.sort!
end
def exp=(exp)
@exp = [[exp, 9999999].min, 0].max
check_level_up
check_level_down
@hp = [@hp, self.maxhp].min
@sp = [@sp, self.maxsp].min
end
def check_level_up
old_size = @skills_not_learned.size
while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
@level += 1
self.skill_limit += KSkill::LVLUPMAX[@level] if KSkill::LVLUPINCREASE
$data_classes[@class_id].learnings.each {|j|
learn_skill(j.skill_id) if j.level == @level }
@pending_skills = old_size < @skills_not_learned.size
end
end
def check_level_down
while @exp < @exp_list[@level]
@level -= 1
self.skill_limit -= KSkill::LVLUPMAX[@level] if KSkill::LVLUPINCREASE
end
end
def skill_max() KSkill::MAX + @limit_breaker end
def skill_limit() @limit_breaker end
def skill_limit=(int) @limit_breaker = [int, 0].max end
end
class Window_KSkillHelp < Window_Base
def initialize(width=640)
super(0, 0, width, 64)
self.contents = Bitmap.new(width - 32, height - 32)
end
def set_text(text, align=0)
contents.clear
contents.draw_text(0, 0, self.width - 32, 32, text, align)
end
end
class Window_ActorSelection < Window_Selectable
def initialize
empty = KSkill.help_actors.size == 0
h = 32 + KSkill.help_actors.size * 80
h += 80 if empty
super(0, 128, 120, h)
self.contents = Bitmap.new(width - 32, height - 32)
@item_max = KSkill.help_actors.size
self.index = empty ? -2 : 0
refresh unless empty
end
def refresh
self.contents.clear
self.contents.font.bold, self.contents.font.size = true, 18
ny, sy = -80, -64
KSkill.help_actors.each {|id| actor = $data_actors[id]
self.contents.draw_text(0, ny += 80, 88, 28, actor.name, 1)
draw_actor_graphic(actor, 44, ny + 74) }
end
def update_cursor_rect
return if @item_max == 1
self.cursor_rect.set(0, @index * 80, 88, 80)
end
end
class Window_ActorSkills < Window_Selectable
attr_reader :replaced, :replace_index
def initialize
super(120, 128, 260, 288)
@replaced = {}
one_choice = KSkill.help_actors.size == 1
self.index = one_choice ? 0 : -1
end
def replace_skills?() @replaced[@actor_id].size > 0 end
def replace_max() @replaced[@actor_id].size end
def skill_id() @data[@index].id end
def refresh
self.contents.dispose if self.contents
@data = []
@actor.skills.size.times {|i| skill = $data_skills[@actor.skills[i]]
@data << skill if skill != nil }
@item_max = @data.size
return unless @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
self.contents.font.size = 20
self.contents.font.bold = true
@item_max.times {|i| draw_item(i) }
end
def actor=(new_actor)
@actor, @actor_id, @index = new_actor, new_actor.id, 0
@replaced[@actor_id] ||= []
refresh
end
def update_replacement_check
if !@replaced[@actor_id].include?(@index)
if KSkill.replacements == 0
$game_system.se_play($data_system.buzzer_se)
return @replace_index = nil
elsif @replaced[@actor_id].size < @actor.skills_not_learned.size
$game_system.se_play($data_system.decision_se)
@replaced[@actor_id] << @index
KSkill.replacements -= 1
@replace_index = @index
else
$game_system.se_play($data_system.buzzer_se)
return @replace_index = nil
end
else
$game_system.se_play($data_system.decision_se)
@replaced[@actor_id].delete(@index)
KSkill.replacements += 1
@replace_index = nil
end
refresh
end
def draw_item(index)
skill, y = @data[index], index * 32
rect = Rect.new(4, y, self.width - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
if @replaced[@actor_id].include?(index)
bitmap = RPG::Cache.icon(KSkill::OLD_SKILL_ICON)
self.contents.blt(0, y + 4, bitmap, Rect.new(0, 0, 24, 24))
end
bitmap = RPG::Cache.icon(skill.icon_name)
self.contents.blt(28, y + 4, bitmap, Rect.new(0, 0, 24, 24))
self.contents.draw_text(60, y, 204, 32, skill.name, 0)
end
def dispose
@replaced.clear
@replaced = nil
super
end
end
class Window_NewSkills < Window_Selectable
attr_reader :selected
attr_writer :replace_max
def initialize(index, skills)
super(380, 128, 260, 288)
self.index = index
@skills = skills
self.active = nil
@replace_max = 0
@selected = {}
@s = []
@data = []
ds = $data_skills
@skills.each{|d| @s[@s.size] = d.map{|i| [id,ds[i].icon_name,ds[i].name]}}
@actor_index = 0 if @skills.size == 1
refresh unless index < 0
end
def skills_size() @item_max end
def skill_ids() @data.map {|values| values[0] } end
def skills(actor_index, new_index, new_skills)
@actor_index = actor_index
self.index = new_index
@skills = new_skills
refresh
end
def update_single_skill
@selected[@actor_index][0] = 0
refresh
end
def update_selection
$game_system.se_play($data_system.decision_se)
reached_max = @replace_max == @selected[@actor_index].compact.size
selected = @selected[@actor_index].include?(@index)
@selected[@actor_index][@index] = ((reached_max or selected)? nil : @index)
refresh
end
def refresh
self.contents.dispose if self.contents
@data = @s[@actor_index]
@item_max = @data.size
return unless @item_max > 0
@selected[@actor_index] ||= Array.new(@item_max, nil)
self.contents = Bitmap.new(width - 32, @item_max * 32)
self.contents.font.size = 20
self.contents.font.bold = true
@item_max.times {|i| draw_item(i) }
end
def draw_item(index)
skill, y = @data[index], index * 32
rect = Rect.new(4, y, self.width - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
if @selected[@actor_index].include?(index)
bitmap = RPG::Cache.icon(KSkill::NEW_SKILL_ICON)
self.contents.blt(0, y + 4, bitmap, Rect.new(0, 0, 24, 24))
end
bitmap = RPG::Cache.icon(skill[1])
self.contents.blt(28, y + 4, bitmap, Rect.new(0, 0, 24, 24))
self.contents.draw_text(60, y, 204, 32, skill[2], 0)
end
def dispose
@data.clear
@s.clear
super
end
end
class Window_KSkillData < Window_Selectable
def initialize(new_x, new_y)
super(new_x, new_y, 272, 256)
self.contents = Bitmap.new(width - 32, height - 32)
self.z += 100
@skill = nil
refresh if @skill
end
def skill_id=(new_skill_id)
@skill = $data_skills[new_skill_id]
refresh
end
def refresh
self.contents.clear
draw_skill_labels
draw_skill_data
end
def draw_skill_labels
labels = KSkill::LABELS
contents.font.color = system_color
contents.draw_text(0, 28, 240, 28, labels[:target])
contents.draw_text(0, 56, 240, 28, KSkill::OCCASIONS[:occasion])
contents.draw_text(0, 84, 240, 28, labels[:cost])
contents.draw_text(124, 84, 240, 28, labels[:power])
contents.draw_text(0, 112, 240, 28, labels[:str])
contents.draw_text(124, 112, 240, 28, labels[:int])
contents.draw_text(0, 140, 240, 28, labels[:agi])
contents.draw_text(124, 140, 240, 28, labels[:dex])
contents.draw_text(0, 168, 240, 28, labels[:pdef])
contents.draw_text(124, 168, 240, 28, labels[:mdef])
contents.draw_text(0, 196, 240, 28, labels[:eva])
end
def draw_skill_data
contents.font.color = normal_color
bitmap = RPG::Cache.icon(@skill.icon_name)
contents.blt(0, 4, bitmap, Rect.new(0, 0, 24, 24))
contents.draw_text(32, 0, 204, 32, @skill.name, 0)
contents.draw_text(0, 28, 240, 28, KSkill::LABELS[@skill.scope], 2)
contents.draw_text(0, 56, 240, 28, KSkill::OCCASIONS[@skill.occasion], 2)
contents.draw_text(0, 84, 108, 28, @skill.sp_cost.to_s, 2)
contents.draw_text(0, 84, 240, 28, @skill.power.abs.to_s, 2)
contents.draw_text(0, 112, 108, 28, @skill.str_f.to_s, 2)
contents.draw_text(0, 112, 240, 28, @skill.int_f.to_s, 2)
contents.draw_text(0, 140, 108, 28, @skill.agi_f.to_s, 2)
contents.draw_text(0, 140, 240, 28, @skill.dex_f.to_s, 2)
contents.draw_text(0, 168, 108, 28, @skill.pdef_f.to_s, 2)
contents.draw_text(0, 168, 240, 28, @skill.mdef_f.to_s, 2)
contents.draw_text(0, 196, 108, 28, @skill.eva_f.to_s, 2)
end
end
class Interpreter
def command_315
value = operate_value(@parameters[1], @parameters[2], @parameters[3])
iterate_actor(@parameters[0]){|actor| actor.exp += value }
pending = $game_party.actors.select{|actor| actor.pending_skills }.size
KSkill.open_menu = (!KSkill.help_actors.empty? and pending > 0)
$game_party.actors.each {|actor| actor.pending_skills = nil }
return true
end
end
class Scene_Map
alias kyon_kskillmax_scn_map_up update
def update
kyon_kskillmax_scn_map_up
return unless KSkill.open_menu and !$game_temp.message_window_showing
$scene = Scene_KSkillMax.new
end
end
class Scene_Load
alias kyon_kskillmax_scn_load_rsd read_save_data
def read_save_data(file)
kyon_kskillmax_scn_load_rsd(file)
actors = $game_party.actors
actors.each {|a| KSkill.help_actors << a.id if !a.skills_not_learned.empty?}
end
end
class Scene_Battle
def battle_end(result)
$game_temp.in_battle = false
$game_party.clear_actions
$game_party.actors.each {|actor| actor.remove_states_battle }
$game_troop.enemies.clear
if $game_temp.battle_proc != nil
$game_temp.battle_proc.call(result)
$game_temp.battle_proc = nil
end
$scene = KSkill.help_actors.empty? ? Scene_Map.new : Scene_KSkillMax.new
end
end
class Scene_KSkillMax
def initialize
KSkill.open_menu = nil
@skills = []
@actors = []
actors = $game_party.actors
KSkill.replacements = 0
actors.each {|a| skills = a.skills_not_learned
next if skills.empty?
number = [a.skill_max, skills.size].min
next if number == 0
KSkill.replacements += number
@skills << skills
@actors << a }
end
def main
make_help_windows
make_status_windows
make_skill_windows
@command_window = Window_Command.new(200, KSkill::EXITOPTIONS)
@command_window.x = (640 - @command_window.width) / 2
@command_window.y = (480 - @command_window.height) / 2
@command_window.visible = nil
@command_window.active = nil
Graphics.transition
loop do
Graphics.update
Input.update
update
break if $scene != self
end
Graphics.freeze
@command_window.dispose
@new_status_window.dispose
@old_status_window.dispose
@replace_window.dispose
@skill_window.dispose
@selection_window.dispose
@help_windows.each {|window| window.dispose }
end
def make_status_windows
@old_status_window = Window_KSkillData.new(368, 128)
@old_status_window.visible = false
@new_status_window = Window_KSkillData.new(108, 128)
@new_status_window.visible = false
end
def make_help_windows
@help_windows = [Window_KSkillHelp.new, Window_KSkillHelp.new(120)]
@help_windows += [Window_KSkillHelp.new(260), Window_KSkillHelp.new(260)]
@help_windows[4] = Window_KSkillHelp.new(520)
@help_windows[2].x = 120
@help_windows[3].x = 380
@help_windows[4].x = 120
@help_windows[1].y = @help_windows[2].y = @help_windows[3].y = 64
@help_windows[4].y = 416
@empty = KSkill.replacements == 0
text = @empty ? KSkill::NOEXTRASKILLS : KSkill::REACHEDMAX
@help_windows[0].set_text(text, 1)
@help_windows[1].set_text(KSkill::HEROES, 1)
@help_windows[2].set_text(KSkill::LEARNEDSKILLS, 1)
@help_windows[3].set_text(KSkill::NEWSKILLS, 1)
text = sprintf(KSkill::REPLACEMENTSLEFT, KSkill.replacements)
@help_windows[4].set_text(text, 1)
end
def make_skill_windows
@selection_window = Window_ActorSelection.new
@skill_window = Window_ActorSkills.new
if KSkill.help_actors.size == 1
@selection_window.active = nil
@skill_window.active = true
@skill_window.actor = $game_actors[KSkill.help_actors[0]]
@skill_window.index = 0
@replace_window = Window_NewSkills.new(0, @skills)
@help_windows[0].set_text(KSkill::REPLACESKILLS, 1)
else
@skill_window.active = nil
@replace_window = Window_NewSkills.new(-1, @skills)
end
end
def update
@help_windows[0].update
@selection_window.update
@skill_window.update
@replace_window.update
@old_status_window.update
@new_status_window.update
@command_window.update
if @selection_window.active
update_actor_selection
return
elsif @skill_window.active
update_skill_selection
return
elsif @replace_window.active
update_replace_selection
return
elsif @old_status_window.visible
update_old_skills_data
return
elsif @new_status_window.visible
update_new_skills_data
return
elsif @command_window.active
update_exit_selection
return
end
end
def update_skills_info
@help_windows[0].set_text(KSkill::REPLACESKILLS, 1)
@skill_window.actor = actor = @actors[@selection_window.index]
@replace_window.skills(@selection_window.index, 0, @skills)
@selection_window.active = nil
@skill_window.active = true
@skill_window.index = 0
end
def update_actor_selection
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
if @empty
$scene = Scene_Map.new
return
end
@help_windows[0].set_text(KSkill::AREYOUSURE, 1)
@selection_window.active = nil
@command_window.active = true
@command_window.visible = true
elsif Input.trigger?(Input::C)
if @actors[@selection_window.index].nil?
$scene = Scene_Map.new
return
elsif @actors[@selection_window.index].skills_not_learned.empty?
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.decision_se)
update_skills_info
end
end
def update_skill_selection
if Input.trigger?(Input::B)
size1 = @skill_window.replaced.values.flatten.size
size2 = @replace_window.selected.values.flatten.compact.size
if size1 != size2
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.cancel_se)
@help_windows[0].set_text(KSkill::REACHEDMAX, 1)
@skill_window.active = nil
if KSkill.help_actors.size == 1
@help_windows[0].set_text(KSkill::AREYOUSURE, 1)
@command_window.active = true
@command_window.visible = true
else
@selection_window.active = true
end
@skill_window.index = -1
@replace_window.index = -1
if @skill_window.contents
@skill_window.contents.clear
@replace_window.contents.clear
end
return
elsif Input.trigger?(Input::C)
@skill_window.update_replacement_check
text = sprintf(KSkill::REPLACEMENTSLEFT, KSkill.replacements)
@help_windows[4].set_text(text, 1)
return
elsif Input.trigger?(KSkill::INFOBUTTONID)
$game_system.se_play($data_system.decision_se)
actor_id = KSkill.help_actors[@selection_window.index]
@actor_skills = $game_actors[actor_id].skills
@skills_size = @actor_skills.size
@skill_index = @skill_window.index
@old_status_window.skill_id = @skill_window.skill_id
@skill_window.active = false
@old_status_window.visible = true
return
elsif Input.trigger?(Input::L) or Input.trigger?(Input::R)
update_active_window
elsif Input.trigger?(Input::LEFT) or Input.trigger?(Input::RIGHT)
update_active_window
end
end
def update_replace_selection
if Input.trigger?(Input::B) or Input.trigger?(Input::LEFT)
$game_system.se_play($data_system.cancel_se)
@replace_window.active = nil
@skill_window.active = true
return
elsif Input.trigger?(KSkill::INFOBUTTONID)
$game_system.se_play($data_system.decision_se)
@actor_skills = @actors[@selection_window.index].skills_not_learned
@skills_size = @actor_skills.size
@skill_index = 0
@new_status_window.skill_id = @actor_skills[0]
@replace_window.active = false
@new_status_window.visible = true
elsif Input.trigger?(Input::C)
@replace_window.update_selection
end
end
def update_old_skills_data
if Input.trigger?(Input::B) or Input.trigger?(KSkill::INFOBUTTONID)
$game_system.se_play($data_system.cancel_se)
$game_system
@actor_skills = []
@old_status_window.visible = false
@skill_window.active = true
elsif Input.trigger?(Input::UP)
if @skills_size == 1
$game_system.se_play($data_system.cancel_se)
return
end
@skill_index = (@skill_index + @skills_size - 1) % @skills_size
@old_status_window.skill_id = @actor_skills[@skill_index]
elsif Input.trigger?(Input::DOWN)
if @skills_size == 1
$game_system.se_play($data_system.cancel_se)
return
end
@skill_index = (@skill_index + 1) % @skills_size
@old_status_window.skill_id = @actor_skills[@skill_index]
end
end
def update_new_skills_data
if Input.trigger?(Input::B) or Input.trigger?(KSkill::INFOBUTTONID)
$game_system.se_play($data_system.cancel_se)
@actor_skills = []
@new_status_window.visible = false
@replace_window.active = true
elsif Input.trigger?(Input::UP)
if @skills_size == 1
$game_system.se_play($data_system.cancel_se)
return
end
@skill_index = (@skill_index + @skills_size - 1) % @skills_size
@new_status_window.skill_id = @actor_skills[@skill_index]
elsif Input.trigger?(Input::DOWN)
if @skills_size == 1
$game_system.se_play($data_system.cancel_se)
return
end
@skill_index = (@skill_index + 1) % @skills_size
@new_status_window.skill_id = @actor_skills[@skill_index]
end
end
def update_active_window
$game_system.se_play($data_system.decision_se)
@skill_window.active = nil
@replace_window.replace_max = @skill_window.replace_max
@replace_window.active = true
end
def update_exit_selection
if Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
case @command_window.index
when 0
actor_index = -1
@actors.each {|actor| id, actor_index = actor.id, actor_index + 1
next if @skill_window.replaced[id].nil?
index = -1
s = @replace_window.selected[actor_index].compact
@skill_window.replaced[id].each {|ix| index += 1
not_learned = @actors[actor_index].skills_not_learned
@actors[actor_index].skills[ix] = not_learned[s[index]]
not_learned[s[index]] = nil }
@actors[actor_index].skills_not_learned.compact! }
clear_skills_info
when 1
@selection_window.active = true
@command_window.active = @command_window.visible = nil
when 2 then clear_skills_info end
$scene = Scene_Map.new unless @command_window.index == 1
end
end
def clear_skills_info
KSkill.help_actors.delete_if {|i| $game_actors[i].skills_not_learned.empty?}
return unless KSkill::CLEAR_SKILLS_NOT_LEARNED
KSkill.help_actors.each {|id| $game_actors[id].skills_not_learned.clear }
KSkill.help_actors.clear
end
end