#============================================================================== # 経験値消費でスキル習得 ver1.07 #------------------------------------------------------------------------------ #[特徴] # 経験値を消費して、スキルを習得します。 # #[スキル設定方法] # スキルのメモ欄に <必要経験値:数値> と書く。 # <必要経験値1:数値> と書くと、アクターID 1 の必要経験値を個別に設定できます。 # # スキルのメモ欄に <必要スキル:スキルID> と書く。 # そのIDのスキルを習得していないと、習得することができません。 # 複数書くと、その全てを習得している必要があります。 # #[習得可能スキルの追加] # イベントコマンドのスクリプトで、 # add_learn_skill(アクターID, スキルID) # イベント後に習得可能スキルを増やしたい場合などに使用してください。 # # 作成:ぶちょー # ホム:http://nyannyannyan.bake-neko.net/ # 著作:自分で作ったとか言わないで>< # 改造はご自由にどうぞ。 # リードミーとかに私の名前の載せたりするのは任意で。 #============================================================================== #============================================================================== # バージョンアップ情報 # ver1.07 アクティブでないウィンドウにカーソルが表示されてしまうのを修正 # ver1.06 レベルが下がっても習得できるかの判定を可能に # ver1.05 細かな不具合を修正 # ver1.04 習得スキルがなにもないときに決定キーを押すとバグが出るのを修正 # ver1.03 細かな不具合を修正 # ver1.02 細かな不具合を修正 # ver1.01 習得条件を満たしていないスキルを選択した際、必要なスキルを表示する機能を追加 # ver1.00 公開 #============================================================================== #============================================================================== # 設定項目 #============================================================================== module Kazari module LearnSkill # メニュー画面に表示するスキル習得のコマンド名 COMMAND_NAME = "スキル習得" # スキル習得時に鳴らす音 ("名前", 音量, ピッチ) LEARN_SOUND = RPG::SE.new("Item2", 80, 100) # 習得時に確認ウィンドウを表示する場合は true LEARN_CHECK = true # スキルを覚えるとき、レベルが下がっても覚えることができるのなら true # false にすると、必要経験値が大きいスキルを序盤は覚えられなくなったりします。 # 5000 でレベルアップしてしまう場合、必要経験値が 10000 のスキルは覚えられない。 LEARN_FLAG = true # スキルの色 # COLOR1 : 習得可能なスキル # COLOR2 : 習得不可能なスキル # COLOR3 : 習得済みのスキル COLOR1 = Color.new(255, 255, 255) COLOR2 = Color.new(255, 255, 255, 128) COLOR3 = Color.new(132, 170, 255) # デフォルトのシステムカラーと同じ色 # 習得済みのスキルはウィンドウに表示しない場合は true HIDE_LEARN_SKILL = true # 習得済みのスキルも表示する場合、必要経験値の場所に描画する文字 SKILL_LEARN = "習得済み" # 習得条件を満たしていないスキルの、必要経験値の場所に描画する文字 #UNNEED_SKILL = "習得不可" UNNEED_SKILL = "%d exp" # 習得不可でも経験値を表示したい場合 # 習得条件を満たしていないスキルを表示しない場合は true HIDE_UNNEED_SKILL = false # 習得条件を満たしていないスキルを選択した際、 # 必要なスキルを表示するウィンドウを表示場合は true CHECK_NEED_SKILL = true # 必要経験値の描画方法 NEED_EXP = "%d exp" # 習得できるスキルの設定 # アクターID => [スキルID, スキルID], ACTOR_LEARN = { # ID 1 のアクターが習得できるスキル 1 => [8,9,10], # 最後の 『,』 を忘れないように 2 => [11,12,13], } # 職業ID => [スキルID, スキルID], CLASS_LEARN = { # 職業IDが1のアクターが習得できるスキル 1 => [26,27,28], } end end #============================================================================== # ここまで #============================================================================== $kms_imported = {} if $kms_imported == nil $kzr_imported = {} if $kzr_imported == nil $kzr_imported["LearnSkillExp"] = true #============================================================================== # ■ Scene_LearnSkill #============================================================================== class Scene_LearnSkill < Scene_ItemBase include Kazari::LearnSkill #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super create_help_window create_command_window create_status_window create_skill_window create_check_window if LEARN_CHECK create_check_need_window if CHECK_NEED_SKILL end #-------------------------------------------------------------------------- # ● コマンドウィンドウの作成 #-------------------------------------------------------------------------- def create_command_window wy = @help_window.height @command_window = Window_SkillCommand.new(0, wy) @command_window.viewport = @viewport @command_window.help_window = @help_window @command_window.actor = @actor @command_window.set_handler(:skill, method(:command_skill)) @command_window.set_handler(:cancel, method(:return_scene)) @command_window.set_handler(:pagedown, method(:next_actor)) @command_window.set_handler(:pageup, method(:prev_actor)) end #-------------------------------------------------------------------------- # ● ステータスウィンドウの作成 #-------------------------------------------------------------------------- def create_status_window x = @command_window.width y = @help_window.height @status_window = Window_SkillStatusExp.new(x, y) @status_window.viewport = @viewport @status_window.actor = @actor end #-------------------------------------------------------------------------- # ● スキルウィンドウの作成 #-------------------------------------------------------------------------- def create_skill_window wx = 0 wy = @status_window.y + @status_window.height @skill_window = Window_LearnSkill.new(wx, wy) @skill_window.actor = @actor @skill_window.viewport = @viewport @skill_window.help_window = @help_window @skill_window.set_handler(:ok, method(:on_skill_ok)) @skill_window.set_handler(:cancel, method(:on_skill_cancel)) @command_window.skill_window = @skill_window end #-------------------------------------------------------------------------- # ● 習得確認ウィンドウの作成 #-------------------------------------------------------------------------- def create_check_window @learn_check_window = Window_LearnCheck.new @learn_check_window.viewport = @viewport @learn_check_window.set_handler(:ok, method(:learn_skill)) @learn_check_window.set_handler(:cancel, method(:learn_cancel)) end #-------------------------------------------------------------------------- # ● 習得条件ウィンドウの作成 #-------------------------------------------------------------------------- def create_check_need_window @check_need_skill = Window_CheckNeed.new @check_need_skill.viewport = @viewport @check_need_skill.set_handler(:ok, method(:check_need)) @check_need_skill.set_handler(:cancel, method(:check_need)) end #-------------------------------------------------------------------------- # ● コマンド[スキル] #-------------------------------------------------------------------------- def command_skill @skill_window.activate @skill_window.select_last end #-------------------------------------------------------------------------- # ● スキル[決定] #-------------------------------------------------------------------------- def on_skill_ok @skill = @skill_window.item if @actor.skill_can_learn?(@skill) if LEARN_CHECK @learn_check_window.index = 0 @learn_check_window.open.activate else LEARN_SOUND.play @actor.learning_skill(@skill) @skill_window.refresh @status_window.refresh @skill_window.activate end elsif CHECK_NEED_SKILL && @skill && !@actor.need_skill?(@skill) @check_need_skill.set_skill(@skill) @check_need_skill.open.activate else Sound.play_buzzer @skill_window.activate end end #-------------------------------------------------------------------------- # ● スキル[キャンセル] #-------------------------------------------------------------------------- def on_skill_cancel @skill_window.deactivate.unselect @command_window.activate end #-------------------------------------------------------------------------- # ● スキル習得 [決定] #-------------------------------------------------------------------------- def learn_skill case @learn_check_window.index when 0 LEARN_SOUND.play @actor.learning_skill(@skill) @skill_window.refresh @status_window.refresh when 1 Sound.play_ok end @learn_check_window.close.deactivate @skill_window.activate end #-------------------------------------------------------------------------- # ● スキル習得 [キャンセル] #-------------------------------------------------------------------------- def learn_cancel Sound.play_cancel @learn_check_window.close @skill_window.activate end #-------------------------------------------------------------------------- # ● 条件スキルの確認 #-------------------------------------------------------------------------- def check_need Sound.play_ok @check_need_skill.close.deactivate @skill_window.activate end #-------------------------------------------------------------------------- # ● アクターの切り替え #-------------------------------------------------------------------------- def on_actor_change @command_window.actor = @actor @status_window.actor = @actor @skill_window.actor = @actor @command_window.activate end end #============================================================================== # ■ Window_LearnSkill #============================================================================== class Window_LearnSkill < Window_Selectable include Kazari::LearnSkill #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y) super(x, y, window_width, Graphics.height - y) self.index = -1 @stype_id = 0 end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width Graphics.width end #-------------------------------------------------------------------------- # ● 桁数の取得 #-------------------------------------------------------------------------- def col_max return 1 end #-------------------------------------------------------------------------- # ● 項目数の取得 #-------------------------------------------------------------------------- def item_max @data ? @data.size : 1 end #-------------------------------------------------------------------------- # ● アイテムの取得 #-------------------------------------------------------------------------- def item @data && index >= 0 ? @data[index] : nil end #-------------------------------------------------------------------------- # ● スキルタイプ ID の設定 #-------------------------------------------------------------------------- def stype_id=(stype_id) return if @stype_id == stype_id @stype_id = stype_id refresh self.oy = 0 end #-------------------------------------------------------------------------- # ● アクターの設定 #-------------------------------------------------------------------------- def actor=(actor) return if @actor == actor @actor = actor refresh self.oy = 0 end #-------------------------------------------------------------------------- # ● スキルをリストに含めるかどうか #-------------------------------------------------------------------------- def include?(item) item && item.stype_id == @stype_id end #-------------------------------------------------------------------------- # ● スキルリストの作成 #-------------------------------------------------------------------------- def make_item_list @data = @actor ? @actor.learnable_skills.select {|skill| include?(skill) } : [] end #-------------------------------------------------------------------------- # ● 前回の選択位置を復帰 #-------------------------------------------------------------------------- def select_last select(@data.index(@actor.last_skill.object) || 0) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh make_item_list create_contents draw_all_items end #-------------------------------------------------------------------------- # ● 項目の描画 #-------------------------------------------------------------------------- def draw_item(index) rect = item_rect(index) self.contents.clear_rect(rect) skill = @data[index] if skill != nil rect.width -= 4 draw_skill_name(skill, rect.x, rect.y) if @actor.skill_learn?(skill) && !HIDE_LEARN_SKILL text = sprintf(SKILL_LEARN, @actor.need_exp(skill)) elsif !@actor.skill_can_learn?(skill) && !HIDE_UNNEED_SKILL text = sprintf(UNNEED_SKILL, @actor.need_exp(skill)) else text = sprintf(NEED_EXP, @actor.need_exp(skill)) end draw_text(rect, text, 2) end end #-------------------------------------------------------------------------- # ● スキル名の描画 #-------------------------------------------------------------------------- def draw_skill_name(skill, x, y) draw_icon(skill.icon_index, x, y) if @actor.skill_learn?(skill) color = COLOR3 elsif @actor.skill_can_learn?(skill) color = COLOR1 else color = COLOR2 end change_color(color) draw_text(x + 24, y, 172, line_height, skill.name) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help @help_window.set_item(item) end end #============================================================================== # ■ Window_SkillStatusExp #============================================================================== class Window_SkillStatusExp < Window_Base #-------------------------------------------------------------------------- # ● 文字色の取得 #-------------------------------------------------------------------------- def exp_gauge_color1; text_color(28); end; # 経験値ゲージ 1 def exp_gauge_color2; text_color(29); end; # 経験値ゲージ 2 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(x, y) super(x, y, Graphics.width - 160, fitting_height(4)) end #-------------------------------------------------------------------------- # ● アクターの設定 #-------------------------------------------------------------------------- def actor=(actor) return if @actor == actor @actor = actor refresh end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear draw_actor_face(@actor, 0, 0) draw_actor_simple_status(@actor, 108, line_height / 2) end #-------------------------------------------------------------------------- # ● シンプルなステータスの描画 #-------------------------------------------------------------------------- def draw_actor_simple_status(actor, x, y) draw_actor_name(actor, x, y) draw_actor_level(actor, x, y + line_height * 1) draw_actor_icons(actor, x, y + line_height * 2) draw_actor_hp(actor, x + 120, y) draw_actor_mp(actor, x + 120, y + line_height * 1) draw_actor_exp(actor, x + 120, y + line_height * 2) end #-------------------------------------------------------------------------- # ● 経験値情報の描画 #-------------------------------------------------------------------------- def draw_actor_exp(actor, x, y) if Kazari::LearnSkill::LEARN_FLAG exp = actor.exp else exp = actor.exp - actor.current_level_exp exp_rate = exp.to_f / (actor.next_level_exp - actor.current_level_exp) if $kms_imported["GenericGauge"] draw_generic_gauge(KMS_GenericGauge::EXP_IMAGE, x, y, 124, exp_rate, KMS_GenericGauge::EXP_OFFSET, KMS_GenericGauge::EXP_LENGTH, KMS_GenericGauge::EXP_SLOPE ) else draw_gauge(x, y, 124, exp_rate, exp_gauge_color1, exp_gauge_color2) end end change_color(system_color) draw_text(x, y, 36, line_height, "EXP") change_color(normal_color) draw_text(x, y, 124, line_height, exp, 2) end end #============================================================================== # ■ Window_LearnCheck #============================================================================== class Window_LearnCheck < Window_Command #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 0) update_placement self.openness = 0 self.active = false end #-------------------------------------------------------------------------- # ● ウィンドウ幅の取得 #-------------------------------------------------------------------------- def window_width return 160 end #-------------------------------------------------------------------------- # ● ウィンドウ位置の更新 #-------------------------------------------------------------------------- def update_placement self.x = (Graphics.width - width) / 2 self.y = (Graphics.height - height) / 2 end #-------------------------------------------------------------------------- # ● コマンドリストの作成 #-------------------------------------------------------------------------- def make_command_list add_command("習得する", :learn_slill) add_command("習得しない", :learn_cancel) end end #============================================================================== # ■ Window_CheckNeed #============================================================================== class Window_CheckNeed < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 0, 272, 48) update_placement self.openness = 0 self.active = false end #-------------------------------------------------------------------------- # ● ウィンドウ位置の更新 #-------------------------------------------------------------------------- def update_placement self.x = (Graphics.width - width) / 2 self.y = (Graphics.height - height) / 2 end #-------------------------------------------------------------------------- # ● スキルのセット #-------------------------------------------------------------------------- def set_skill(skill) needs = skill.need_skills self.height = fitting_height(needs.size + 1) create_contents update_placement change_color(system_color) draw_text(0, 0, 256, line_height, "必要スキル") change_color(normal_color) needs.each_with_index do |need, i| draw_item_name($data_skills[need], 0, line_height * (i + 1)) end end end #============================================================================== # ■ Game_Actor #============================================================================== class Game_Actor < Game_Battler include Kazari::LearnSkill #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :added_learn_skill #-------------------------------------------------------------------------- # ● セットアップ #-------------------------------------------------------------------------- alias add_learn_skill_setup setup def setup(actor_id) add_learn_skill_setup(actor_id) @added_learn_skill = [] end #-------------------------------------------------------------------------- # ● 習得可能なスキルオブジェクトの配列取得 #-------------------------------------------------------------------------- def learnable_skills list = ACTOR_LEARN[@actor_id] if ACTOR_LEARN[@actor_id] list += CLASS_LEARN[@class_id] if CLASS_LEARN[@class_id] list += @added_learn_skill list -= @skills if HIDE_LEARN_SKILL list += @skills unless HIDE_LEARN_SKILL if HIDE_UNNEED_SKILL list -= list.select { |s_id| !need_skill?($data_skills[s_id]) } end list.uniq.sort.collect {|id| $data_skills[id] } end #-------------------------------------------------------------------------- # ● スキル習得に必要な経験値 #-------------------------------------------------------------------------- def need_exp(skill) return skill.need_exp(@actor_id) end #-------------------------------------------------------------------------- # ● スキルの習得可能判定 #-------------------------------------------------------------------------- def skill_can_learn?(skill) return false if skill == nil return false if skill_learn?(skill) return false unless need_skill?(skill) usable_exp = LEARN_FLAG ? exp : exp - current_level_exp return usable_exp >= need_exp(skill) end #-------------------------------------------------------------------------- # ● 習得に必要なスキルを満たしているか #-------------------------------------------------------------------------- def need_skill?(skill) (skill.need_skills & @skills) == skill.need_skills end #-------------------------------------------------------------------------- # ● スキルの習得の際、レベルが下がるかどうかの判定 #-------------------------------------------------------------------------- def skill_learn_level_down?(skill) return (exp - current_level_exp) < need_exp(skill) end #-------------------------------------------------------------------------- # ● スキルの習得(経験値消費) #-------------------------------------------------------------------------- def learning_skill(skill) learn_skill(skill.id) change_exp(self.exp - need_exp(skill), false) end #-------------------------------------------------------------------------- # ● 習得可能スキルを追加する #-------------------------------------------------------------------------- def add_learn_skill(skill_id) @added_learn_skill.push(skill_id) @added_learn_skill.uniq end end #============================================================================== # ■ Game_Interpreter #============================================================================== class Game_Interpreter #-------------------------------------------------------------------------- # ● 習得可能スキルを追加する #-------------------------------------------------------------------------- def add_learn_skill(actor_id, skill_id) $game_actors[actor_id].add_learn_skill(skill_id) end end #============================================================================== # ■ Scene_Menu #============================================================================== class Scene_Menu < Scene_MenuBase #-------------------------------------------------------------------------- # ● コマンドウィンドウの作成 #-------------------------------------------------------------------------- alias kzr_learn_skill_by_exp_create_command_window create_command_window def create_command_window kzr_learn_skill_by_exp_create_command_window @command_window.set_handler(:kzr_learn_skill, method(:command_personal)) end #-------------------------------------------------------------------------- # ● 個人コマンド[決定] #-------------------------------------------------------------------------- alias kzr_learn_skill_by_exp_on_personal_ok on_personal_ok def on_personal_ok case @command_window.current_symbol when :kzr_learn_skill SceneManager.call(Scene_LearnSkill) else kzr_learn_skill_by_exp_on_personal_ok end end end #============================================================================== # ■ Window_MenuCommand #============================================================================== class Window_MenuCommand < Window_Command include Kazari::LearnSkill #-------------------------------------------------------------------------- # ● 独自コマンドの追加用 #-------------------------------------------------------------------------- alias kzr_learn_skill_by_exp_add_original_commands add_original_commands def add_original_commands kzr_learn_skill_by_exp_add_original_commands add_command(COMMAND_NAME, :kzr_learn_skill, main_commands_enabled) end end class RPG::Skill def need_exp(actor_id) @parsonal_need ||= {} return @parsonal_need[actor_id] if @parsonal_need[actor_id] != nil need = 0 note.each_line { |line| case line when /<必要経験値(\d+):(\d+)>/i if $1.to_i == actor_id @parsonal_need[actor_id] = $2.to_i return @parsonal_need[actor_id] end when /<必要経験値:(\d+)>/i need = $1.to_i end } return need end def need_skills return @needs if @needs != nil @needs = [] note.each_line { |line| case line when /<必要スキル:(\d+)>/i ; @needs << $1.to_i end } return @needs end end