SBBS – Stamina Based Battle System

RPG Maker XP (RGSS)
Autor
Fomar0153, Jirbytaylor
Sprache
Ruby
Zeilen
689
Eingestellt von
GR-FoxDie
Aufrufe
0
Im Forum
[script=6]

Ein Kampfsystem, bei dem Aktionen Ausdauer (SP) kosten.

Als .rb-Datei
# ** SBBS
#    Stamina Based Battle System
#------------------------------------------------------------------------------
#  Original by Fomar0153
#  Conversion to SP by Fomar0153
#  Additional Edits by Jirbytaylor
#==============================================================================


#==============================================================================
# ** Fomar Module
#------------------------------------------------------------------------------
#  some module thingy
#==============================================================================


module Fomar

  Attack_Cost = 1
  Defend_Cost = 5
  Item_Cost = 1
  Flee_Attempt = 10
  Refresh_Rate = 5

  def self.attack
    return Attack_Cost
  end

  def self.defend
    return Defend_Cost
  end

  def self.item
    return Item_Cost
  end

  def self.critical_value(n)
    return (n == Attack_Cost or n == Defend_Cost or n == Item_Cost)
  end

end


#==============================================================================
# ** Game_BattleAction
#------------------------------------------------------------------------------
#  This class handles actions in battle. It's used within the Game_Battler
#  class.
#==============================================================================


class Game_BattleAction

  alias cbs_clear clear
  def clear
    unless (@kind == 0 and @basic == 1)
      cbs_clear
      return
    end
    @speed = 0
    @skill_id = 0
    @item_id = 0
    @target_index = -1
    @forcing = false
  end

end


#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
#  This class deals with battlers. It's used as a superclass for the Game_Actor
#  and Game_Enemy classes.
#==============================================================================


class Game_Battler

  attr_accessor :vitality

  alias cbs_initialize initialize
  def initialize
    cbs_initialize
    @vitality = 1
  end

  def sp_action_cost
    if (@current_action.kind == 0 and @current_action.basic == 1) or
      ((@current_action.kind == 0 and @current_action.basic == 0) and
      @current_action.target_index == -1)
      return
    end
    if @current_action.kind == 0 and @current_action.basic == 0
      @sp -= Fomar.attack
    end
    if @current_action.kind == 1
      @sp -= Fomar.attack
    end
    if @current_action.kind == 2
      @sp -= Fomar.item
    end

  end

end


#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
#  This class handles enemies. It's used within the Game_Troop class
#  ($game_troop).
#==============================================================================


class Game_Enemy < Game_Battler

  alias cbs_make_action make_action
  def make_action
    return
  end

  def can_do_action?
    if @current_action.kind == 0 and @current_action.basic == 0
      return @sp >= Fomar.attack
    end
    if @current_action.kind == 1
      return @sp >= Fomar.attack
    end
    if @current_action.kind == 0 and @current_action.basic == 1
      return @sp >= Fomar.defend
    end
    if @current_action.kind == 0 and @current_action.basic == 3
      return false
    end
  end

end


#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
#  This class performs battle screen processing.
#==============================================================================


class Scene_Battle
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------
  alias cbs_main main
  def main
    @fleeing = false
    @flee_attempt = 0
    @refresh_rate = 0
    @enemy_decision = 0
    for actor in $game_party.actors
      actor.current_action.cbs_clear
    end
    cbs_main
  end

  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  alias cbs_update update
  def update
    if @refresh_rate == Fomar::Refresh_Rate
      @refresh_rate = 0
    else
      @refresh_rate += 1
    end
    cbs_update
  end

  #--------------------------------------------------------------------------
  # * Frame Update (party command phase: escape)
  #--------------------------------------------------------------------------
  def update_phase2_escape
    @fleeing = true
    @flee_attempt = 0
    start_phase3
  end

  #--------------------------------------------------------------------------
  # * Start Party Command Phase
  #--------------------------------------------------------------------------
  def start_phase2
    @fleeing = false
    start_phase3
  end

  #--------------------------------------------------------------------------
  # * Frame Update (party command phase)
  #--------------------------------------------------------------------------
  def update_phase2
    start_phase3
  end

  #--------------------------------------------------------------------------
  # * Start Party Command Phase
  #--------------------------------------------------------------------------
  def end_phase2
    @party_command_window.active = false
    @party_command_window.visible = false
  end

  def start_phase3
    end_phase2
    @phase = 3
    @actor_index = 0
    @active_battler = $game_party.actors[0]
    $game_party.clear_actions
    unless @fleeing == true
      phase3_setup_command_window
    end
  end

  def phase3_setup_command_window
    phase3_make_command_window
    @party_command_window.active = false
    @party_command_window.visible = false
    @actor_command_window.active = true
    @actor_command_window.visible = true
    @actor_command_window.x = @actor_index * 160
  end

  def phase3_make_command_window
    unless @actor_command_window == nil
      @actor_command_window.dispose
    end
    s1 = "Moves"
    s2 = "Items"
    s3 = "Defend"
    s4 = "End Turn"
    s5 = "Flee"
    @actor_command_window = Window_Command.new(160, [s1, s2, s3, s4, s5])
    @actor_command_window.y = 160 - 32
    @actor_command_window.back_opacity = 160
    unless @active_battler.inputable?
      @actor_command_window.disable_item(0)
      @actor_command_window.disable_item(1)
      @actor_command_window.disable_item(2)
      @actor_command_window.disable_item(3)
      return
    end
    unless @active_battler.sp >= Fomar.attack
      @actor_command_window.disable_item(0)
    end
    unless @active_battler.sp >= Fomar.defend
      @actor_command_window.disable_item(2)
    end
    unless @active_battler.sp >= Fomar.item
      @actor_command_window.disable_item(3)
    end
  end

  alias cbs_update_phase3 update_phase3
  def update_phase3
    if judge
      return
    end
    cbs_update_phase3
    if @actor_command_window.active == true or @fleeing == true
      @enemy_decision += 1
      if @enemy_decision == 50
        @enemy_decision -= 50
        resolve = false
        for enemy in $game_troop.enemies
          enemy.cbs_make_action
          if enemy.can_do_action?
            resolve = true
          else
            enemy.current_action.clear
          end
        end
        if resolve == true
          @check_index = @actor_index
          start_phase4
          return
        end
      end
    end
    if @fleeing == true
      if Input.trigger?(Input::B)
        start_phase2
      end
      @flee_attempt += 1
      if @flee_attempt == Fomar::Flee_Attempt
        enemies_agi = 0
        enemies_number = 0
        for enemy in $game_troop.enemies
          if enemy.exist?
            enemies_agi += enemy.agi
            enemies_number += 1
          end
        end
        if enemies_number > 0
          enemies_agi /= enemies_number
        end
        actors_agi = 0
        actors_number = 0
        for actor in $game_party.actors
          if actor.exist?
            actors_agi += actor.agi
            actors_number += 1
          end
        end
        if actors_number > 0
          actors_agi /= actors_number
        end
        success = rand(100) < 50 * actors_agi / enemies_agi
        if success
          $game_system.se_play($data_system.escape_se)
          $game_system.bgm_play($game_temp.map_bgm)
          battle_end(1)
        else
          @flee_attempt -= Fomar::Flee_Attempt
        end
      end
    end
    if @active_battler != nil
      if Fomar.critical_value(@active_battler.sp)
        i = @actor_command_window.index
        k = @actor_command_window.visible
        l = @actor_command_window.active
        phase3_make_command_window
        @actor_command_window.x = @actor_index * 160
        @actor_command_window.index = i
        @actor_command_window.visible = k
        @actor_command_window.active = l
      end
    end
    if @actor_command_window.active == true or @fleeing == true
      phase3_pass_time
    end
  end

  #--------------------------------------------------------------------------
  # * Frame Update (increase vitality count)
  #--------------------------------------------------------------------------
  def phase3_pass_time
    for battler in $game_party.actors + $game_troop.enemies
      #battler.sp += battler.vitality
      #if battler.sp > battler.maxsp
      #  battler.sp = battler.maxsp
      #end
    end
  end

  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 1 : action preparation)
  #--------------------------------------------------------------------------
  alias cbs_update_phase4_step1 update_phase4_step1
  def update_phase4_step1
    if @action_battlers.size == 0
      @phase = 3
      for battler in $game_party.actors + $game_troop.enemies
        battler.sp_action_cost
      end
      i = @actor_command_window.index
      phase3_make_command_window
      @actor_command_window.index = 1
      @actor_command_window.visible = true
      @actor_command_window.active = true
      @actor_index = @check_index
      @actor_command_window.x = 160 * @actor_index
      @active_battler = $game_party.actors[@actor_index]
      $game_party.clear_actions
      for enemy in $game_troop.enemies
        enemy.current_action.clear
      end
      return
    end
    cbs_update_phase4_step1
  end

  #--------------------------------------------------------------------------
  # * Go to Command Input for Next Actor
  #--------------------------------------------------------------------------
  def phase3_next_actor
    @check_index = @actor_index
    start_phase4
    return
  end

  #--------------------------------------------------------------------------
  # * Go to Command Input of Previous Actor
  #--------------------------------------------------------------------------
  def phase3_prior_actor
    start_phase2
    return
  end

  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : basic command)
  #--------------------------------------------------------------------------
  def update_phase3_basic_command
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      phase3_prior_actor
      return
    end
    if Input.trigger?(Input::C)
      case @actor_command_window.index
      when 0 #skill
        if @active_battler.sp < Fomar.attack
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        $game_system.se_play($data_system.decision_se)
        @active_battler.current_action.kind = 1
        start_skill_select
      when 1 #item
        if @active_battler.sp < Fomar.item
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        $game_system.se_play($data_system.decision_se)
        @active_battler.current_action.kind = 2
        start_item_select
      when 2 #guard
        if @active_battler.sp < Fomar.defend
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        $game_system.se_play($data_system.decision_se)
        @active_battler.current_action.kind = 0
        @active_battler.current_action.basic = 1
        @active_battler.sp -= Fomar.defend
        phase3_next_actor
      when 3 #end
        $game_system.se_play($data_system.decision_se)
        @actor_index += 1
        if @actor_index == $game_party.actors.size
          @actor_index = 0
        end
        @active_battler = $game_party.actors[@actor_index]
        phase3_make_command_window
        @actor_command_window.x = @actor_index * 160
      when 4 #flee
        if $game_temp.battle_can_escape == false
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        $game_system.se_play($data_system.decision_se)
        update_phase2_escape
      end
      return
    end
  end

  #--------------------------------------------------------------------------
  # * Make Skill Action Results
  #--------------------------------------------------------------------------
  def make_skill_action_result
    # Get skill
    @skill = $data_skills[@active_battler.current_action.skill_id]
    # If not a forcing action
    unless @active_battler.current_action.forcing
      # If unable to use due to SP running out
      unless @active_battler.skill_can_use?(@skill.id)
        # Clear battler being forced into action
        $game_temp.forcing_battler = nil
        # Shift to step 1
        @phase4_step = 1
        return
      end
    end
    # Use up SP
    @active_battler.sp -= @skill.sp_cost
    # Refresh status window
    @status_window.refresh
    # Show skill name on help window
    @help_window.set_text(@skill.name, 1)
    # Set animation ID
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    # Set command event ID
    @common_event_id = @skill.common_event_id
    # Set target battlers
    set_target_battlers(@skill.scope)
    # Apply skill effect
    for target in @target_battlers
      target.skill_effect(@active_battler, @skill)
    end
  end
  #--------------------------------------------------------------------------
  # * Make Basic Action Results
  #--------------------------------------------------------------------------
  def make_basic_action_result
    # If attack
    if @active_battler.current_action.basic == 0
      # Set anaimation ID
      @animation1_id = @active_battler.animation1_id
      @animation2_id = @active_battler.animation2_id
      # If action battler is enemy
      if @active_battler.is_a?(Game_Enemy)
        if @active_battler.restriction == 3
          target = $game_troop.random_target_enemy
        elsif @active_battler.restriction == 2
          target = $game_party.random_target_actor
        else
          index = @active_battler.current_action.target_index
          target = $game_party.smooth_target_actor(index)
        end
      end
      # If action battler is actor
      if @active_battler.is_a?(Game_Actor)
        if @active_battler.restriction == 3
          target = $game_party.random_target_actor
        elsif @active_battler.restriction == 2
          target = $game_troop.random_target_enemy
        else
          index = @active_battler.current_action.target_index
          target = $game_troop.smooth_target_enemy(index)
        end
      end
      # Set array of targeted battlers
      @target_battlers = [target]
      # Apply normal attack results
      for target in @target_battlers
        target.attack_effect(@active_battler)
      end
      return
    end
    # If guard
    if @active_battler.current_action.basic == 1
      # Display "Guard" in help window
      @active_battler.sp += 10 # Only time the active battler recovers SP
      @help_window.set_text($data_system.words.guard, 1)
      @status_window.refresh
      return
    end
    # If escape
    if @active_battler.is_a?(Game_Enemy) and
       @active_battler.current_action.basic == 2
      # Display "Escape" in help window
      @help_window.set_text("Escape", 1)
      # Escape
      @active_battler.escape
      return
    end
    # If doing nothing
    if @active_battler.current_action.basic == 3
      # Clear battler being forced into action
      $game_temp.forcing_battler = nil
      # Shift to step 1
      @phase4_step = 1
      return
    end
  end


  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 1 : action preparation)
  #--------------------------------------------------------------------------
  def update_phase4_step1
    # Hide help window
    @help_window.contents.clear
    @help_window.visible = false
    # Determine win/loss
    if judge
      # If won, or if lost : end method
      return
    end
    # If an action forcing battler doesn't exist
    if $game_temp.forcing_battler == nil
      # Set up battle event
      setup_battle_event
      # If battle event is running
      if $game_system.battle_interpreter.running?
        return
      end
    end
    # If an action forcing battler exists
    if $game_temp.forcing_battler != nil
      # Add to head, or move
      @action_battlers.delete($game_temp.forcing_battler)
      @action_battlers.unshift($game_temp.forcing_battler)
    end
    # If no actionless battlers exist (all have performed an action)
    if @action_battlers.size == 0
      # Start party command phase
      start_phase2
      return
    end
    # Initialize animation ID and common event ID
    @animation1_id = 0
    @animation2_id = 0
    @common_event_id = 0
    # Shift from head of actionless battlers
    @active_battler = @action_battlers.shift
    # If already removed from battle
    if @active_battler.index == nil
      return
    end
    # Slip damage
    if @active_battler.hp > 0 and @active_battler.slip_damage?
      @active_battler.slip_damage_effect
      @active_battler.damage_pop = true
    end
    # Natural removal of states
    @active_battler.remove_states_auto
    # Refresh status window
    @status_window.refresh
    # Shift to step 2
    @phase4_step = 2
  end

  ###
    $game_troop = Game_Troop.new # These were added because there would
    $game_party = Game_Party.new # be an error without it. (Which Trick was confused about.)
    ($game_troop.enemies + $game_party.actors).each do |battler|
      if battler == @active_battler or not battler.exist?
        battler.sp += 1
        @status_window.refresh
      end
  ###
  end

  #--------------------------------------------------------------------------
  # * Start Skill Selection
  #--------------------------------------------------------------------------
  def start_skill_select
    # Make skill window
    @skill_window = Window_Skill.new(@active_battler)
    @skill_window.y = 320
    @skill_window.z = 900
    @skill_window.height = 160
    # Associate help window
    @skill_window.help_window = @help_window
    # Disable actor command window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end
  #--------------------------------------------------------------------------
  # * Start Item Selection
  #--------------------------------------------------------------------------
  def start_item_select
    # Make item window
    @item_window = Window_Item.new
    @item_window.y = 320
    @item_window.z = 900
    @item_window.height = 160
    # Associate help window
    @item_window.help_window = @help_window
    # Disable actor command window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end



end


=begin
#==============================================================================


Okay this script covers a little more of what I want to do. There are
however three things I can't figure out.
- Enemy skill name may not display in the help window after a hero attacks.
- Remember selected hero. After the enemy attacks hero 1 is selected.
Thanks for this head start. If there is anything you think I did wrong tell me.


  ~ Jirby


    ($game_troop.enemies + $game_party.actors).each do |battler|
      if battler == @active_battler or not battler.exist?
        battler.sp += 1
        @status_window.refresh
      end

Trickster wrote this for me to make it so inactive battlers (heroes and enemies)
recover 1 SP a turn. But not the active hero/enemy.
This was with the turn based system, yet I never found it to work.
Placed at the end of def update_phase4_step1


The text goes screwy in the battle status window. Was that why you shrunk it?
Couldn't seem to fix it?
#==============================================================================
=end