# ▽△▽ XRXSv19. MeLT_Skill. オートスキルツリー! ▽△▽ # # publish 2010/ 3/16 # update - 5/ 1b # #============================================================================== # カスタマイズポイント #============================================================================== module XRXSV19 # # データベースレベル1あたりのAP量 # APAmount = 10 # # オートルート&ソート を有効にする? # (スキルの属性などに応じて、自動的にルートを設定、並び替えます。) # AutoRoot = false # # レベルアップによる獲得AP # APLevelGain = 10 # # AP獲得時、自動的に一番上のスキルにAPを振り分ける? # APAutoGain = false # # 敵撃破獲得APの基本値 # APEnemy = 1 # # 敵撃破AP、2匹目以降は1ポイントずつ減らす? # APEnemyReducing = true # # 戦闘獲得APを常に 1 にする?(APを戦闘回数として扱う場合に便利です) # APForNumberofBattle = false # # 確認時の文字式 # APConfirm_S1 = "AP %s を消費して %s を習得する!" APConfirm_S2 = "やめる" # # 文字列 # Next_S = "あと" AP_S = "AP" # # APを支払いスキルを習得した時のSE # APLearnSE = RPG::SE.new("Saint9", 80, 130) # # オートツリーのずれ幅(0〜72) # TreeXMax = 72 # # 現在APウィンドウを表示する? # APWindowVisible = true # # ツリーの線の色 # TreeLineColor = Color.new(255,255,0,160) # # 必要AP \ap[] の正規表現 (ここを変えると別の記述方法でもAP指定できます) # 敵AP  \ap[]  〃 # APNoteRegexp = /\\ap\[([0-9]+?)\]/ APEnemyRegexp = /\\ap\[([0-9]+?)\]/ end #============================================================================== # AP文字色 #============================================================================== class Window_Base < Window def ap_color return text_color(4) end end #============================================================================== # 「スキルの習得」の変更 #============================================================================== class Game_Actor < Game_Battler #-------------------------------------------------------------------------- # ● スキルの習得 #-------------------------------------------------------------------------- alias xrxsv19_learn_skill learn_skill def learn_skill(skill_id) unless @skill_learn_ban xrxsv19_learn_skill(skill_id) n, maxap = ap_data(skill_id) self.skill_aps[skill_id] = maxap end end #-------------------------------------------------------------------------- # ● セットアップ #-------------------------------------------------------------------------- alias xrxsv19_setup setup def setup(actor_id) @skill_learn_ban = true xrxsv19_setup(actor_id) @skill_learn_ban = nil self.ap = 0 self.skill_aps.clear for learning in self.class.learnings if learning.level == 1 xrxsv19_learn_skill(learning.skill_id) end end self.ap += (self.level - 1) * XRXSV19::APLevelGain end #-------------------------------------------------------------------------- # ● レベルアップ #-------------------------------------------------------------------------- alias xrxsv19_level_up level_up def level_up @skill_learn_ban = true xrxsv19_level_up @skill_learn_ban = nil self.ap += XRXSV19::APLevelGain end end #============================================================================== # ◆スキルの増減 での追加処理 #============================================================================== class Game_Interpreter alias xrxsv19_command_318 command_318 def command_318 actor = $game_actors[@params[0]] if actor != nil if @params[1] == 0 actor.xrxsv19_learn_skill(@params[2]) else actor.skill_aps[@params[2]] = 0 end end return xrxsv19_command_318 end end #============================================================================== # スキルラーニング - ツリー機能 #============================================================================== module RPG class Class class Learning attr_accessor :root attr_accessor :before_id def root? return true if self.level == 1 return true if self.skill.note[/\\root/] return @root end def before_id if self.skill.note[/\\before\[([0-9]+?)\]/] return $1.to_i end return @before_id.to_i end def ap return (self.level - 1) * XRXSV19::APAmount end def skill return $data_skills[self.skill_id] end end end end #============================================================================== # グローバルAP #============================================================================== class Game_Party < Game_Unit attr_accessor :ap def ap @ap = 0 unless @ap return @ap end end #============================================================================== # EXP,APの取得/獲得AP/スキル別習得度/APデータベースの取得 #============================================================================== class Scene_BattleResult < Scene_Base end class Game_Actor < Game_Battler #-------------------------------------------------------------------------- # EXP,APの取得 #-------------------------------------------------------------------------- attr_accessor :exp_list def ap @ap = 0 unless @ap return @ap end def ap=(n) @ap = n if XRXSV19::APAutoGain @ap -= gain_ap_current(@ap) end end def skill_aps @skill_aps = {} unless @skill_aps return @skill_aps end #-------------------------------------------------------------------------- # APの獲得 #-------------------------------------------------------------------------- def gain_ap(skill_id, n) self.skill_aps[skill_id] = self.skill_aps[skill_id].to_i + n id, need_ap = ap_data(skill_id) if self.skill_aps[skill_id] >= need_ap self.skill_aps[skill_id] = need_ap xrxsv19_learn_skill(skill_id) end end #-------------------------------------------------------------------------- # カレントに対するAP加算 (消費値を返す) #-------------------------------------------------------------------------- def gain_ap_current(gain_ap) return 0 if gain_ap <= 0 n = 0 for learning in self.class.learnings if not skill_learn?($data_skills[learning.skill_id]) and self.skill_before_learn?($data_skills[learning.skill_id]) rest = ap_rest(learning) if rest >= 1 n = [rest, gain_ap].min gain_ap(learning.skill_id, n) break end end end if n >= 1 return n + gain_ap_current(gain_ap - n) end end #-------------------------------------------------------------------------- # 習得までの残りAP #-------------------------------------------------------------------------- def ap_rest(learning) before_id, maxap = ap_data(learning.skill_id) return (maxap - self.skill_aps[learning.skill_id].to_i) end #-------------------------------------------------------------------------- # 階層の深さの取得 #-------------------------------------------------------------------------- def ap_depth(learning) n = -1 loop do n += 1 learning = before_learning(learning) break unless learning end return n end #-------------------------------------------------------------------------- # ひとつ前のラーニングを取得 #-------------------------------------------------------------------------- def before_learning(learning, original_mode = false) unless original_mode return nil if learning.root? end now_learnings = self.class.learnings n = now_learnings.index(learning) unless original_mode if learning.before_id >= 1 for i in 0...n learning2 = self.class.learnings[i] if learning2.skill_id == learning.before_id return learning2 end end end end for i in 1..n learning2 = now_learnings[n-i] if learning2.level < learning.level return learning2 end end return nil end #-------------------------------------------------------------------------- # このスキルの前階層のスキルを習得している? #-------------------------------------------------------------------------- def skill_before_learn?(skill) before_id, maxap = ap_data(skill.id) return (before_id == 0 or self.skill_learn?($data_skills[before_id])) end #-------------------------------------------------------------------------- # APデータの取得 #-------------------------------------------------------------------------- def ap_data(skill_id) return 0, 0 if skill_id == 0 learning = nil for learning2 in self.class.learnings if learning2.skill_id == skill_id learning = learning2 break end end return 0, 0 unless learning learnign2 = before_learning(learning) if learning.root? or !learnign2 before_id = 0 else before_id = learnign2.skill_id end if learning.skill.note[XRXSV19::APNoteRegexp] ap = $1.to_i else learnign2 = before_learning(learning, true) lv = (learnign2 ? learnign2.level : 1) ap = (learning.level - lv) * XRXSV19::APAmount end return before_id, ap end #-------------------------------------------------------------------------- # オートルート&ソート #-------------------------------------------------------------------------- if XRXSV19::AutoRoot alias xrxsv19_class :class def class new_class = xrxsv19_class.dup learnings = [] for learning in new_class.learnings done = false if element_id = learning.skill.element_set[0] for learning2 in learnings.reverse if learning2.skill.element_set.include?(element_id) learning.before_id = learning2.skill_id learnings.insert(learnings.index(learning2)+1, learning) done = true break end end end next if done if learning.skill.minus_state_set.include?(1) for learning2 in learnings.reverse if learning2.skill.minus_state_set.include?(1) learning.before_id = learning2.skill_id learnings.insert(learnings.index(learning2)+1, learning) done = true break end end end next if done if learning.skill.base_damage <= -1 for learning2 in learnings.reverse if learning2.skill.base_damage <= -1 learning.before_id = learning2.skill_id learnings.insert(learnings.index(learning2)+1, learning) done = true break end end end next if done if learning.skill.minus_state_set.size >= 1 for learning2 in learnings.reverse if learning2.skill.minus_state_set.size >= 1 learning.before_id = learning2.skill_id learnings.insert(learnings.index(learning2)+1, learning) done = true break end end end next if done learning.before_id = 0 learning.root = true learnings.push(learning) end new_class.learnings = learnings return new_class end end def learnings_reset! for learning in self.class.learnings learning.root = nil learning.before_id = nil end end end #============================================================================== # 敵AP #============================================================================== class Game_Troop < Game_Unit def ap_total return 1 if XRXSV19::APForNumberofBattle n = 0 for enemy in self.dead_members n += enemy.ap end n -= (self.dead_members.size - 1) if XRXSV19::APEnemyReducing return [n, 0].max end end class Game_Enemy < Game_Battler def ap if self.enemy.note[XRXSV19::APEnemyRegexp] return $1.to_i end return XRXSV19::APEnemy end end #============================================================================== # ナンバー描画への対応 #============================================================================== module XRXSVForDNX def draw_number(x, y, width, height, number, align, skin, opacity = 224) self.draw_text(x, y, width, height, number, align) end def draw_number_l(x, y, width, height, number, align = 0) skin = Cache.system(XRXSVDsIn::NumberL) rescue nil self.draw_number(x, y, width, height, number, align, skin) end def draw_number_s(x, y, width, height, number, align = 0) skin = Cache.system(XRXSVDsIn::NumberS) rescue nil self.draw_number(x, y, width, height, number, align, skin) end end class Bitmap include XRXSVForDNX end #============================================================================== # 現在AP表示 #============================================================================== class Window_AP < Window_Base def initialize(actor) @actor = actor super(416, 72, 128, 56) self.z += 5 refresh end def refresh self.contents.clear self.contents.font.color = ap_color self.contents.draw_text(0,0,32,WLH, "AP") self.contents.font.color = normal_color self.contents.draw_number_l(32,0,64,WLH, @actor.ap + $game_party.ap, 2) end end #============================================================================== # APスキルリストウィンドウ #============================================================================== class Window_APSkillList < Window_Selectable def initialize(actor) @draw_x_offsets = [] @ap_rests = [] @skills = [] @actor = actor @learnable = [] @skill_visible = [] super(0, 60, 352, 300) @column_max = 1 self.index = 0 self.opacity = 0 refresh end #-------------------------------------------------------------------------- # リフレッシュ #-------------------------------------------------------------------------- def refresh @data = @actor.class.learnings.dup for skill in @actor.skills included = false for learning in @actor.class.learnings included |= (skill.id == learning.skill_id) end @data.push(skill) unless included end @item_max = @data.size max_depth = 3 for learning in @actor.class.learnings n = @actor.ap_depth(learning) max_depth = n if max_depth < n end @depth_offset = XRXSV19::TreeXMax / max_depth create_contents for i in 0...@item_max draw_item(i) end end def draw_item(index) obj = @data[index] if obj.is_a?(RPG::Skill) skill = obj learning = nil depth = 0 @ap_rests[index] = 0 @draw_x_offsets[index] = 0 @skill_visible[index] = true learned = true @learnable[index] = false else learning = obj skill = $data_skills[learning.skill_id] depth = @actor.ap_depth(learning) @ap_rests[index] = @actor.ap_rest(learning) @draw_x_offsets[index] = depth * @depth_offset @skill_visible[index] = @actor.skill_before_learn?(skill) learned = @actor.skill_learn?(skill) @learnable[index] = (@skill_visible[index] and not learned and @ap_rests[index] <= (@actor.ap + $game_party.ap)) end rect = item_rect(index) @skills[index] = skill enable = ((learned and @actor.skill_can_use?(skill))) unless @skill_visible[index] skill = skill.dup skill.name = "????" end x1 = rect.x + 8 + @draw_x_offsets[index] # # 階層ライン部分 # if learning and depth >= 1 and @depth_offset >= 12 color = XRXSV19::TreeLineColor w = @depth_offset/2 x2 = x1 - w self.contents.fill_rect(x2, rect.y+13, w-4, 2, color) self.contents.fill_rect(x2, rect.y, 1, 14, color) learning2 = @actor.before_learning(learning) n = @data.index(learning2) if n for i in (n+1)...@data.index(learning) y = WLH * i self.contents.fill_rect(x2, y, 1, WLH, color) end end end # # 名前〜 # self.contents.font.size = 18 draw_item_name(skill, x1, rect.y, enable) x1 = rect.x + 40 if @skill_visible[index] if not learned self.contents.font.color = normal_color self.contents.font.size = 14 self.contents.draw_number_s(x1 + 220, rect.y, 32, WLH, @ap_rests[index], 2) self.contents.font.color = ap_color self.contents.font.size = 16 self.contents.draw_text(x1 + 252, rect.y, 20, WLH, XRXSV19::AP_S, 2) self.contents.draw_text(x1 + 188, rect.y, 32, WLH, XRXSV19::Next_S, 2) else cost = @actor.calc_mp_cost(skill) if cost >= 1 self.contents.font.size = 14 self.contents.font.color = system_color self.contents.draw_text(x1 + 200, rect.y, 32, WLH, Vocab.mp_a,2) self.contents.font.color = normal_color self.contents.draw_number_s(x1 + 232, rect.y, 40, WLH, cost, 2) end end end end #-------------------------------------------------------------------------- # 習得の実行 #-------------------------------------------------------------------------- def learn! n = self.ap_rest m = [n, $game_party.ap].min $game_party.ap -= m n -= m @actor.ap -= n @actor.gain_ap(self.skill.id, self.ap_rest) refresh end #-------------------------------------------------------------------------- # 取得 #-------------------------------------------------------------------------- def ap_rest return @ap_rests[self.index].to_i end def skill return @skills[self.index] end def learnable? return @learnable[self.index] end def usable? return (@actor.skill_learn?(self.skill) and @actor.skill_can_use?(self.skill)) end def update_help @help_window.set(@skill_visible[self.index] ? self.skill : nil) end end #============================================================================== # AP支払い実行確認ウィンドウ #============================================================================== class Window_APConfirm < Window_Selectable def initialize super(0, 0, 384, 80) self.x = (Graphics.width - self.width ) / 2 self.y = (Graphics.height - self.height) / 2 self.index = 0 self.openness = 0 self.active = false @item_max = 2 end def set(ap, skill) self.index = 0 text1 = sprintf(XRXSV19::APConfirm_S1, ap.to_s, skill.name) text2 = sprintf(XRXSV19::APConfirm_S2, ap.to_s, skill.name) self.contents.clear self.contents.draw_text(8,0, self.contents.width-16, WLH, text1) self.contents.draw_text(8,WLH,self.contents.width-16, WLH, text2) end end #============================================================================== # 追加対応/その他 #============================================================================== module XRXSV19_UpdateExtra def update_extra return false end def update_extra_command_decide(work_id) end end #============================================================================== # 拡張ヘルプ対応 #============================================================================== class Window_HelpEX < Window_Help def set(item) self.set_text(item == nil ? "" : item.description) end end #============================================================================== # 背景ウィンドウ #============================================================================== class Window_SkillBack < Window_Selectable def initialize super(0, 56, 544, 304) self.z = 0 end end #============================================================================== # 無効化スキルウィンドウ #============================================================================== class Window_DisabledSkill < Window_Skill def initialize(actor) super(0,0,36,36,actor) self.index = 0 self.visible = false end def refresh end end #============================================================================== # スキル画面 #============================================================================== class Scene_Skill < Scene_Base include XRXSV19_UpdateExtra #-------------------------------------------------------------------------- # ● トランジション実行 #-------------------------------------------------------------------------- def perform_transition Graphics.transition(0) end #-------------------------------------------------------------------------- # 戻り位置 #-------------------------------------------------------------------------- def return_scene_index index = XRXSV10::MENU_SCENES.index(Scene_Skill) rescue 1 return index end #-------------------------------------------------------------------------- # ● 元の画面へ戻る #-------------------------------------------------------------------------- def return_scene $scene = Scene_Menu.new(self.return_scene_index) end #-------------------------------------------------------------------------- # ● 次のアクターの画面に切り替え #-------------------------------------------------------------------------- def next_actor @command_window.slideout! rescue nil @actor_index += 1 @actor_index %= $game_party.members.size @next_scene = $scene.class.new(@actor_index) @next_scene_duration = 4 end #-------------------------------------------------------------------------- # ● 前のアクターの画面に切り替え #-------------------------------------------------------------------------- def prev_actor @command_window.slideout! rescue nil @actor_index += $game_party.members.size - 1 @actor_index %= $game_party.members.size @next_scene = $scene.class.new(@actor_index) @next_scene_duration = 4 end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super create_menu_background @clear_style = ((XRXSV10::BG_NAME rescue "").size >= 1) unless @clear_style @back_window = Window_SkillBack.new end @actor = $game_party.members[@actor_index] @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height) @help_window = Window_HelpEX.new @help_window.y = Graphics.height - @help_window.height @ap_list_window = Window_APSkillList.new(@actor) @ap_list_window.help_window = @help_window @ap_window = Window_AP.new(@actor) if XRXSV19::APWindowVisible @ap_confirm_window = Window_APConfirm.new @status_window = Window_SkillStatus.new(0, 0, @actor) @target_window = Window_MenuStatus.new(0, 0) @target_window.z += 3 hide_target_window @skill_window = Window_DisabledSkill.new(@actor) @help_window.visible = true @command_window.slidein! rescue nil @show_actor = @actor @next_scene = nil @next_scene_duration = 0 end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def terminate super dispose_menu_background @back_window.dispose if @back_window != nil @help_window.dispose @skill_window.dispose @ap_list_window.dispose @ap_window.dispose if @ap_window @ap_confirm_window.dispose @status_window.dispose @target_window.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super update_menu_background @help_window.update @status_window.update @target_window.update if @next_scene != nil @next_scene_duration -= 1 if @next_scene_duration < 0 $scene = @next_scene end return end @ap_confirm_window.update if @ap_confirm_window.active update_ap_confirm elsif @target_window.active update_target_selection else if Input.trigger?(Input::R) or Input.trigger?(Input::L) # else @ap_list_window.update end update_ap_list end end #-------------------------------------------------------------------------- # フレーム更新 - AP支払い確認 #-------------------------------------------------------------------------- def update_ap_confirm if Input.trigger?(Input::C) case @ap_confirm_window.index when 0 XRXSV19::APLearnSE.play @ap_list_window.learn! @ap_window.refresh if @ap_window when 1 Sound.play_decision end @ap_confirm_window.active = false @ap_confirm_window.close elsif Input.trigger?(Input::B) Sound.play_cancel @ap_confirm_window.active = false @ap_confirm_window.close end end #-------------------------------------------------------------------------- # フレーム更新 - APリスト #-------------------------------------------------------------------------- def update_ap_list if Input.trigger?(Input::B) Sound.play_cancel return_scene elsif Input.trigger?(Input::A) Sound.play_cursor go_equip_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) if @ap_list_window.learnable? Sound.play_decision @ap_confirm_window.set(@ap_list_window.ap_rest, @ap_list_window.skill) @ap_confirm_window.active = true @ap_confirm_window.open elsif @ap_list_window.usable? Sound.play_decision @skill = @ap_list_window.skill if @skill != nil @actor.last_skill_id = @skill.id end determine_skill else Sound.play_buzzer end end end #-------------------------------------------------------------------------- # ● ターゲットウィンドウの表示 #-------------------------------------------------------------------------- alias xrxsv19_show_target_window show_target_window def show_target_window(right) #@skill_window.contents_opacity = 80 #@skill_window.cursor2_copy! rescue nil xrxsv19_show_target_window(true) @target_window.x += 16 @target_window.slidein! rescue nil @help_window.visible = true end #-------------------------------------------------------------------------- # ● ターゲットウィンドウの非表示 #-------------------------------------------------------------------------- def hide_target_window #@skill_window.cursor2_dispose! rescue nil #@skill_window.contents_opacity = 255 #@skill_window.active = true @target_window.visible = false @target_window.active = false @help_window.visible = true @viewport.rect.set(0, 0, Graphics.width, Graphics.height) @viewport.ox = 0 end #-------------------------------------------------------------------------- # ● スキルの決定 #-------------------------------------------------------------------------- alias xrxsv19_determine_skill determine_skill def determine_skill if @skill.for_opponent? Sound.play_buzzer return end xrxsv19_determine_skill end #-------------------------------------------------------------------------- # ● スキルの使用 (使用効果を適用) #-------------------------------------------------------------------------- alias xrxsv19_use_skill_nontarget use_skill_nontarget def use_skill_nontarget xrxsv19_use_skill_nontarget @ap_list_window.refresh end end #============================================================================== # --- ターゲットウィンドウ用メニューステータスへの対応 --- #============================================================================== module XRXSV19SkillTargetSlidable def slidable_scenes return super + [Scene_Skill] end end class Window_MenuStatus < Window_Selectable include XRXSV19SkillTargetSlidable end #============================================================================== # --- カーソルコピー機能 (Window_Selectableの下位クラス用) --- #============================================================================== class Window_PartySkill < Window_Selectable include XRXSV_CursorCopy rescue nil end