#============================================================================== # ○ポイント制スキル習得 Ver1.03 # for RGSS2 # 西瓜 / Space not far # http://muspell.raindrop.jp/ # レベルアップなどで得たポイントを割り振ることでスキルを習得できるシステムです。 # デフォルトのレベルアップによるスキル習得とも併用可能です。 #============================================================================== # ■更新履歴 # Ver1.03 # ・キャラ初期化時ポイントが初期化されない不具合を修正。 # ・KGC Softwareの「ヘルプウィンドウ機能拡張」に対応。 # (ソースを一部コピーして改変しただけ) # Ver1.02 # ・習得条件を満たさないスキルの名前を隠す機能を追加。 # ・その他バグ修正。 # Ver1.01 # ・スキル習得条件として必須スキルの設定を追加。 #============================================================================== # module SNF 内のLEARNLISTでポイントで習得可能なスキルを設定してください。 # メモ欄に<必要SP:n>と書き込むことで # 個別に消費するポイントを設定することが出来ます。 # 例:<必要SP:5> => 習得に5ポイントが必要 # また、スキルのメモ欄に # <必須スキル[必要なスキルその1のID,必要なスキルその2のID]...>という形式で # 記述することによって、それらをそのスキルの習得条件として # 設定することが出来ます。 # 例:<必須スキル[1,2]> => 三回攻撃の習得には連続攻撃と二回攻撃の両方が必要 # イベントコマンドのスクリプトでSNF::LEARNLIST[アクターID].push(スキルID)と # 記述することでそのアクターの習得候補リストにスキルIDのスキルを追加できます。 # 例:SNF::LEARNLIST[1].push(15) => ラルフのリストに毒の息を追加 # イベントコマンドのスクリプトでsnf_grow_sp(増加値, アクターID)と # 記述することでそのIDのアクターのポイントを増加値分プラスすることができます。 # アクターIDを0にしたり省略したりした場合、パーティ全員にプラスされます。 # また、増加値にマイナスの値を設定することも可能です。 # ■仕様 # LEARN_MENUCOMMANDをtrueにした場合でも # 他のシーンからメニューに戻ってきた場合カーソルがズレることがあります。 # 不親切ですがご自分で各シーンのreturn_sceneの引数を変更してください。 module SNF LEARN_WORD = "スキル習得" # メニューコマンドに表示される項目名 LEARN_SP_WORD = "SP" # 習得時に必要なポイントの名称 LEARNLIST = [] LEARNLIST[1] = [11, 12] LEARNLIST[2] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # LEARNLIST[職業orアクターID] = [習得可能スキルIDの配列] # 習得可能スキルの配列にあるものがスキル習得画面に並びます。 # すでに習得しているものはリストから除外されます。 LEARNSKILL_CLASS_OR_ACTOR = 1 # 0 => 職業ID別の習得 1 => アクターID別の習得 # LEARNLISTで職業とアクターIDどちらを参照するかを設定します。 CAPTION_NEEDSKILL = true # 習得条件を満たしていない場合、ヘルプに条件スキルを表示するか?(true/false) CAPTION_SKILL = "必要なスキルを覚えていません" # スキルが足りない場合 CAPTION_SP = "SPが足りません" # SPが足りない場合 LEARN_CONSEAL = true # 習得条件を満たさないときスキル名を隠すか?(true/false) LEARN_CONSEALNAME = "×××××" # スキル名のかわりに表示する文字 DEFAULT_SP = 3 # 各アクターの初期SP DEFAULT_SPCOST = 1 # 消費SP無設定の場合の消費SP GLOW_SP = 1 # レベルアップ時に上昇するSP LEARN_SOUND = RPG::SE.new("Up", 80, 100) # スキル習得時に再生されるSE。RPG::SE.new(ファイル名, 音量, ピッチ) LEARN_RETURN = Scene_Menu.new(2) # スキル習得終了時に戻るシーン LEARN_MENUCOMMAND = true # メニューコマンドを再定義してスキル習得の項目を付け足すか?(true/false) LEARN_COST_DISAPPEAR = false # 習得コストを非表示にするか?(true/false) LEARN_KGC_HelpExtension = false # ヘルプウィンドウ機能拡張を併用しているか? def self.sp_cost(skill) return 0 if skill == nil memo = skill.note.scan(/<必要SP:(\d+)>/) memo = memo.flatten if memo != nil and not memo.empty? return memo[0].to_i else return DEFAULT_SPCOST end end end class Game_Actor #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :sp alias snf_learnskill_initialize initialize def initialize(actor_id) snf_learnskill_initialize(actor_id) @sp = SNF::DEFAULT_SP end #-------------------------------------------------------------------------- # ● セットアップ # actor_id : アクター ID #-------------------------------------------------------------------------- alias snf_learnskill_setup setup def setup(actor_id) snf_learnskill_setup(actor_id) @sp = SNF::DEFAULT_SP end end class Scene_LearnSkill < Scene_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 # actor_index : アクターインデックス #-------------------------------------------------------------------------- def initialize(actor_index = 0, equip_index = 0) @actor_index = actor_index end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super create_menu_background @actor = $game_party.members[@actor_index] @viewport = Viewport.new(0, 0, 544, 416) @help_window = Window_Help.new @help_window.viewport = @viewport @status_window = Window_LearnSkillStatus.new(0, 56, @actor) @status_window.viewport = @viewport @skill_window = Window_LearnSkill.new(0, 112, 544, 304, @actor) @skill_window.viewport = @viewport @skill_window.help_window = @help_window end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def terminate super dispose_menu_background @status_window.dispose @help_window.dispose @skill_window.dispose end #-------------------------------------------------------------------------- # ● 元の画面へ戻る #-------------------------------------------------------------------------- def return_scene $scene = SNF::LEARN_RETURN end #-------------------------------------------------------------------------- # ● 次のアクターの画面に切り替え #-------------------------------------------------------------------------- def next_actor @actor_index += 1 @actor_index %= $game_party.members.size $scene = Scene_LearnSkill.new(@actor_index) end #-------------------------------------------------------------------------- # ● 前のアクターの画面に切り替え #-------------------------------------------------------------------------- def prev_actor @actor_index += $game_party.members.size - 1 @actor_index %= $game_party.members.size $scene = Scene_LearnSkill.new(@actor_index) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super update_menu_background @status_window.update @help_window.update @skill_window.update if @skill_window.active update_skill_selection end end #-------------------------------------------------------------------------- # ● スキル選択の更新 #-------------------------------------------------------------------------- def update_skill_selection if Input.trigger?(Input::B) Sound.play_cancel return_scene elsif Input.trigger?(Input::R) Sound.play_cursor next_actor elsif Input.trigger?(Input::L) Sound.play_cursor prev_actor elsif Input.trigger?(Input::C) @skill = @skill_window.skill if @skill != nil @actor.last_skill_id = @skill.id if @actor.learn_sp_skill?(@skill) @actor.learn_skill(@skill.id) @actor.sp -= SNF.sp_cost(@skill) @skill_window.refresh @status_window.refresh SNF::LEARN_SOUND.play else Sound.play_buzzer end else Sound.play_buzzer end end end end class Window_LearnSkill < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 # x : ウィンドウの X 座標 # y : ウィンドウの Y 座標 # width : ウィンドウの幅 # height : ウィンドウの高さ # actor : アクター #-------------------------------------------------------------------------- def initialize(x, y, width, height, actor) super(x, y, width, height) @actor = actor @column_max = 2 self.index = 0 refresh end #-------------------------------------------------------------------------- # ● スキルの取得 #-------------------------------------------------------------------------- def skill return @data[self.index] end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh @data = [] for skill in @actor.learnskills @data.push(skill) if skill.id == @actor.last_skill_id self.index = @data.size - 1 end end @item_max = @data.size create_contents for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) rect = item_rect(index) self.contents.clear_rect(rect) skill = @data[index] if skill != nil rect.width -= 4 enabled = @actor.learn_sp_skill?(skill) cost = (SNF::LEARN_COST_DISAPPEAR) ? "" : SNF.sp_cost(skill) draw_item_name(skill, rect.x, rect.y, enabled) self.contents.draw_text(rect, cost, 2) end end #-------------------------------------------------------------------------- # ● アイテム名の描画 # item : アイテム (スキル、武器、防具でも可) # x : 描画先 X 座標 # y : 描画先 Y 座標 # enabled : 有効フラグ。false のとき半透明で描画 #-------------------------------------------------------------------------- def draw_item_name(item, x, y, enabled = true) if item != nil draw_icon(item.icon_index, x, y, enabled) self.contents.font.color = normal_color self.contents.font.color.alpha = enabled ? 255 : 128 if enabled name = item.name else if @actor.learn_tree_skill?(item) name = item.name else name = SNF::LEARN_CONSEAL ? SNF::LEARN_CONSEALNAME : item.name end end self.contents.draw_text(x + 24, y, 172, WLH, name) end end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help unless SNF::CAPTION_NEEDSKILL @help_window.set_text(skill == nil ? "" : skill.description) else if @actor.learn_sp_skill?(skill) @help_window.set_text(skill == nil ? "" : skill.description) else if @actor.sp < SNF.sp_cost(skill) @help_window.set_text(skill == nil ? "" : SNF::CAPTION_SP) else @help_window.set_text(skill == nil ? "" : SNF::CAPTION_SKILL) end end end end end class Game_Battler def learn_sp_skill?(skill) if self.sp >= SNF.sp_cost(skill) # コストは足りてるか? return false if skill == nil return learn_tree_skill?(skill) else return false # コストが足りない end end def learn_tree_skill?(skill) memo = skill.note.scan(/<必須スキル\[(\S+)\]>/) memo = memo.flatten if memo != nil and not memo.empty? tree = memo[0].split(/\s*,\s*/) tree_ok = true for tree_id in tree return false unless self.skill_learn?($data_skills[tree_id.to_i]) end if tree_ok return true else return false # スキルが足りない end else return true end end end class Game_Interpreter #-------------------------------------------------------------------------- # ● SP の増減 #-------------------------------------------------------------------------- def snf_grow_sp(value, actor_id = 0) iterate_actor_id(actor_id) do |actor| actor.sp += value end return true end end class Window_LearnSkillStatus < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 # x : ウィンドウの X 座標 # y : ウィンドウの Y 座標 # actor : アクター #-------------------------------------------------------------------------- def initialize(x, y, actor) super(x, y, 544, WLH + 32) @actor = actor refresh end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear draw_actor_name(@actor, 4, 0) self.contents.font.color = system_color self.contents.draw_text(140, 0, 32, WLH, SNF::LEARN_SP_WORD) self.contents.font.color = normal_color self.contents.draw_text(172, 0, 48, WLH, @actor.sp, 2) end end class Game_Actor < Game_Battler alias snf_learnskill_level_up level_up def level_up self.sp += SNF::GLOW_SP snf_learnskill_level_up # メソッド呼び戻し end #-------------------------------------------------------------------------- # ● スキルオブジェクトの配列取得 #-------------------------------------------------------------------------- def learnskills result = [] if SNF::LEARNSKILL_CLASS_OR_ACTOR == 0 # 職業ID skills = (SNF::LEARNLIST[self.class_id] != nil) ? SNF::LEARNLIST[self.class_id] : [] elsif SNF::LEARNSKILL_CLASS_OR_ACTOR == 1 # アクターID skills = (SNF::LEARNLIST[self.id] != nil) ? SNF::LEARNLIST[self.id] : [] end for i in skills next if skill_learn?($data_skills[i]) result.push($data_skills[i]) end return result end end if SNF::LEARN_MENUCOMMAND # 再定義 class Scene_Menu < Scene_Base #-------------------------------------------------------------------------- # ● コマンドウィンドウの作成 #-------------------------------------------------------------------------- def create_command_window s1 = Vocab::item s2 = Vocab::skill s3 = Vocab::equip s4 = Vocab::status s5 = Vocab::save s6 = Vocab::game_end s7 = SNF::LEARN_WORD @command_window = Window_Command.new(160, [s1, s2, s7, s3, s4, s5, s6]) @command_window.index = @menu_index if $game_party.members.size == 0 # パーティ人数が 0 人の場合 @command_window.draw_item(0, false) # アイテムを無効化 @command_window.draw_item(1, false) # スキルを無効化 @command_window.draw_item(2, false) # スキル習得を無効化 @command_window.draw_item(3, false) # 装備を無効化 @command_window.draw_item(4, false) # ステータスを無効化 end if $game_system.save_disabled # セーブ禁止の場合 @command_window.draw_item(5, false) # セーブを無効化 end end #-------------------------------------------------------------------------- # ● コマンド選択の更新 #-------------------------------------------------------------------------- def update_command_selection if Input.trigger?(Input::B) Sound.play_cancel $scene = Scene_Map.new elsif Input.trigger?(Input::C) if $game_party.members.size == 0 and @command_window.index < 5 Sound.play_buzzer return elsif $game_system.save_disabled and @command_window.index == 5 Sound.play_buzzer return end Sound.play_decision case @command_window.index when 0 # アイテム $scene = Scene_Item.new when 1,2,3,4 # スキル、スキル習得、装備、ステータス start_actor_selection when 5 # セーブ $scene = Scene_File.new(true, false, false) when 6 # ゲーム終了 $scene = Scene_End.new end end end #-------------------------------------------------------------------------- # ● アクター選択の更新 #-------------------------------------------------------------------------- def update_actor_selection if Input.trigger?(Input::B) Sound.play_cancel end_actor_selection elsif Input.trigger?(Input::C) $game_party.last_actor_index = @status_window.index Sound.play_decision case @command_window.index when 1 # スキル $scene = Scene_Skill.new(@status_window.index) when 2 # スキル習得 $scene = Scene_LearnSkill.new(@status_window.index) when 3 # 装備 $scene = Scene_Equip.new(@status_window.index) when 4 # ステータス $scene = Scene_Status.new(@status_window.index) end end end end end if SNF::LEARN_KGC_HelpExtension class Scene_LearnSkill < Scene_Base #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- alias start_KGC_HelpExtension start def start start_KGC_HelpExtension adjust_window_size end #-------------------------------------------------------------------------- # ● ウィンドウサイズ調整 #-------------------------------------------------------------------------- def adjust_window_size @help_window.row_max = KGC::HelpExtension::ROW_MAX @status_window.y = @help_window.height dy = @help_window.height + @status_window.height @skill_window.y = dy @skill_window.height = Graphics.height - dy @skill_window.refresh end end end