查看: 3297|回复: 9

[已经解决] [已解决]想实现一个NPC队友功能,战斗不受我方控制。

[复制链接]
梦石
0
星屑
15041
在线时间
2230 小时
注册时间
2019-1-24
回帖
964

R考场第七期纪念奖

发表于 2019-10-21 12:08:18 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 miantouchi 于 2019-10-24 06:57 编辑

初步想法是打个比方,
场景1:我方坚持打到第5回合时,这个npc会加入到游戏战斗画面里面,所在的位置是我方队友的位置。
            我方无法进行控制,到了这个npc行动时,会自动释放大型技能。
             厉害的npc会秒杀BOSS.
场景2.弱点的npc,是个医生职业一直普通攻击和初级治疗。
共同点是
这一次战役(也就是这次的剧情完事)打完后,npc离开。
  系统现在只有敌人中途出现,敌人使用某个技能释放几率这些设置,然而没有一个npc有这种情况。

增加这个npc不受控的会有不少乐趣,可翻了论坛基本也没找到这个方面的。

不同战役,失败条件不同,例如需要保护的npc挂了直接失败。

欢迎大家来讨论!!!

只有我方和敌方的战斗太单调了!

梦石
0
星屑
39236
在线时间
11155 小时
注册时间
2009-3-15
回帖
4768
发表于 2019-10-21 13:46:25 | 显示全部楼层
[pre lang="ruby"]#==============================================================================
# ■ XP-RGSS-47 オート行動キャラクタ [Ver.1.0.0]          by Claimh
#------------------------------------------------------------------------------
#  特定のキャラクタのみオート行動させることが出来ます。
#------------------------------------------------------------------------------
# ● オート行動者の変更(イベントコマンド)
#   $game_actors[アクターID].auto_play = true/false
#     true  :オート行動者に設定
#     false ;オート行動者を解除
#------------------------------------------------------------------------------
# ● オート行動者の変更
#   設定カスタマイズで設定しているPT_SW[アクターID]で指定した変数を変更する。
#   対応する行動パターンが設定されていないと「何もしない」
#==============================================================================

module AutoPlayer
  AUTO_MODE = []
  PT_SW = []
  RATING_PLUS = 5
  RETRY_TIME = 10
#------------------------------------------------------------------------------
# ★設定カスタマイズ
#------------------------------------------------------------------------------
  # 初期状態からオート行動キャラクタ
  # AUTO_PLAYER = [アクターID,・・・]
  AUTO_PLAYER = [1, 3]

  # オート行動パターン切り替え用変数
  # PT_SW[アクターID] = 変数ID
  PT_SW[1] = 1
  PT_SW[2] = 2
  PT_SW[3] = 3
  PT_SW[4] = 4

  # 瀕死条件と判定するHP(%)
  CRISIS = 25

  #-----------------------------------------------------------
  # ◆オート行動パターン設定
  #     行動パターンの設定です。
  #     レーティングに応じて行動をランダムに行動します。
  #     行動優先条件に適合する際は設定されたレーティング+5
  #-----------------------------------------------------------
    # 定数名 = [
    #     レーティング(1~10),
    #     行動優先条件(0:指定なし, 1:味方ピンチ, 2:敵が瀕死状態),
    #     行動種類(0:通常攻撃, 1:防御, 2:スキル, 3:アイテム),
    #     使用スキルID or 使用アイテムID(通常攻撃、防御の場合はnil),
    #     ターゲット選択条件(0:ランダム, 1:残HPの低い者, 2:残HPの高い者)
    # ]

  #---------アクター1---------#
  # アクター1:パターン0
  AT_PATTERN_1_0 = [
    [5, 0, 0, nil, 0],   # レーティング5:条件なし:通常攻撃:ランダム
    [2, 0, 2,  57, 2],   # レーティング2:条件なし:スキル:クロスカット;残HP高
    [1, 0, 1, nil, 0]    # レーティング1:条件なし:防御
  ]

  # アクター1:パターン1
  AT_PATTERN_1_1 = [
    [2, 0, 0, nil, 0],   # レーティング2:条件なし:通常攻撃:ランダム
    [5, 0, 2, nil, 0]    # レーティング5:条件なし:防御
  ]

  #---------アクター2---------#
  # アクター2:パターン0
  AT_PATTERN_2_0 = [
    [5, 0, 0, nil, 0],   # レーティング5:条件なし:通常攻撃:ランダム
    [1, 0, 0, nil, 1],   # レーティング1:条件なし:防御
    [2, 0, 2,   7, 2]    # レーティング2:条件なし:スキル:ファイア;残HP高
  ]

  # アクター2:パターン1
  AT_PATTERN_2_1 = [
    [2, 0, 0, nil, 0],   # レーティング2:条件なし:通常攻撃:ランダム
    [5, 0, 2, nil, 0]    # レーティング5:条件なし:防御
  ]

  #---------アクター3---------#
  # アクター3:パターン0
  AT_PATTERN_3_0 = [
    [5, 0, 0, nil, 1],   # レーティング5:条件なし:通常攻撃:残HP低
    [2, 0, 1, nil, 0],   # レーティング2:条件なし:防御
    [3, 1, 2,   1, 1]    # レーティング3:味方ピンチ:スキル:ヒール:残HP低
  ]

  # アクター3:パターン1
  AT_PATTERN_3_1 = [
    [2, 0, 1, nil, 0],   # レーティング2:条件なし:防御
    [5, 1, 2,   1, 1]    # レーティング5:味方ピンチ:スキル:ヒール:残HP低
  ]

  #---------アクター4---------#
  # アクター4:パターン0
  AT_PATTERN_4_0 = [
    [5, 0, 0, nil, 1],   # レーティング5:条件なし:通常攻撃:残HP低
    [3, 2, 0, nil, 1],   # レーティング2:敵瀕死:通常攻撃:残HP低
    [1, 0, 1, nil, 0]    # レーティング1:条件なし:防御
  ]

  # アクター4:パターン1
  AT_PATTERN_4_1 = [
    [2, 0, 0, nil, 1],   # レーティング2:条件なし:通常攻撃:残HP低
    [5, 0, 2, nil, 0]    # レーティング5:条件なし:防御
  ]


  #-----------------------------------------------------------
  # ◆オート行動設定
  #     各キャラクタの行動パターンの設定
  #-----------------------------------------------------------
  # AUTO_MODE[アクターID] = {
  #   PT_SW[アクターID]で指定した変数の値 => [オート行動パターン]
  # }
  # アクター1
  AUTO_MODE[1] = {
    0 => AT_PATTERN_1_0,    # アクター1:パターン0
    1 => AT_PATTERN_1_1     # アクター1:パターン1
  }

  # アクター2
  AUTO_MODE[2] = {
    0 => AT_PATTERN_2_0,    # アクター2:パターン0
    1 => AT_PATTERN_2_1     # アクター2:パターン1
  }

  # アクター3
  AUTO_MODE[3] = {
    0 => AT_PATTERN_3_0,    # アクター3:パターン0
    1 => AT_PATTERN_3_1     # アクター3:パターン1
  }

  # アクター4
  AUTO_MODE[4] = {
    0 => AT_PATTERN_4_0,    # アクター4:パターン0
    1 => AT_PATTERN_4_1     # アクター4:パターン1
  }

#------------------------------------------------------------------------------
end


#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor   :auto_play                 # オート行動
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     actor_id : アクター ID
  #--------------------------------------------------------------------------
  alias init_auto_chara initialize
  def initialize(actor_id)
    init_auto_chara(actor_id)
    @auto_play = AutoPlayer::AUTO_PLAYER.include?(actor_id)
  end
  #--------------------------------------------------------------------------
  # ● コマンド入力可能判定
  #--------------------------------------------------------------------------
  def inputable?
    ret = super
    ret = false if @auto_play
    return ret
  end
end


#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Scene_Battle
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 2 : アクション開始)
  #--------------------------------------------------------------------------
  alias update_phase4_step2_auto_player update_phase4_step2
  def update_phase4_step2
    # オート行動者か?
    if @active_battler.is_a?(Game_Actor) and @active_battler.auto_play
      make_auto_player_actions
    end
    update_phase4_step2_auto_player
  end
  #--------------------------------------------------------------------------
  # ● オート行動者の行動選択
  #--------------------------------------------------------------------------
  def make_auto_player_actions
    # 行動パターン抽出
    action_motion = at_judge_auto_pattern?
    return if action_motion.nil?  # 抽出失敗
    # 行動が決まるまでリトライ(RETRY_TIMEまで)
    for i in 0...AutoPlayer::RETRY_TIME
      # 行動判定処理
      action = make_auto_play_pattern(action_motion)
      # 行動パターンが設定されていない
      if action.nil?
        # 何もしない
        @active_battler.current_action.kind = 0
        @active_battler.current_action.basic = 3
        return
      end
      # 行動設定処理
      ret = make_auto_play_motion(action)
      return if ret   # 正常終了
    end
    # 行動選択に失敗 = 何もしない
    ## 味方全員生存している状態で、味方(HP0)対象のスキル、アイテムが
    ## 連続して発生しない限りここにはこない。
    ## 安全策のために何もしないを入れておく。
    @active_battler.current_action.kind = 0
    @active_battler.current_action.basic = 3
  end
  #--------------------------------------------------------------------------
  # ● 行動パターン抽出
  #--------------------------------------------------------------------------
  def at_judge_auto_pattern?
    # 行動が設定されていない
    vari = $game_variables[AutoPlayer::PT_SW[@active_battler.id]]
    if AutoPlayer::AUTO_MODE[@active_battler.id].nil? or vari.nil?
      # 何もしない
      @active_battler.current_action.kind = 0
      @active_battler.current_action.basic = 3
      return nil
    end
    action_motion = AutoPlayer::AUTO_MODE[@active_battler.id][vari]
    # 行動パターンが設定されていない
    if action_motion.nil?
      # 何もしない
      @active_battler.current_action.kind = 0
      @active_battler.current_action.basic = 3
      return nil
    end
    return action_motion
  end
  #--------------------------------------------------------------------------
  # ● 優先条件"味方ピンチ"の判定
  #--------------------------------------------------------------------------
  def at_judge_party_crisis?
    for actor in $game_party.actors
      # 瀕死状態?
      if actor.hp <= (actor.maxhp * AutoPlayer::CRISIS / 100)
        return true
      end
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ● 優先条件"味方ピンチ"の判定
  #--------------------------------------------------------------------------
  def at_judge_enemy_crisis?
    for enemy in $game_troop.enemies
      # 瀕死状態?
      if enemy.hp <= (enemy.maxhp * AutoPlayer::CRISIS / 100)
        return true
      end
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ● オート行動者の行動パターン判定
  #--------------------------------------------------------------------------
  def make_auto_play_pattern(action_pattern)
    # 優先条件の有無をチェックする
    pt_crisis = at_judge_party_crisis?
    tr_crisis = at_judge_enemy_crisis?
    # レーティング合計値
    total_rating = 0
    rating_box = []
    for i in 0...action_pattern.size
      rating_plus = 0
      case action_pattern[1]
      when 0    # 条件なし
      when 1    # 味方ピンチ
        rating_plus = AutoPlayer::RATING_PLUS if pt_crisis
      when 2    # 敵が瀕死状態
        rating_plus = AutoPlayer::RATING_PLUS if tr_crisis
      else
        p "行動パターン::優先行動条件 設定ミス"
        exit
      end
      rating_box = action_pattern[0] + rating_plus
      total_rating += rating_box
    end
    # レーティングによる行動選択
    rating_randam = rand(total_rating)
    before_rating = 0
    for i in 0...action_pattern.size
      if rating_randam < (rating_box + before_rating)
        return action_pattern
      end
      before_rating += rating_box
    end
    return nil    # 行動選択失敗
  end
  #--------------------------------------------------------------------------
  # ● 行動選択
  #--------------------------------------------------------------------------
  def make_auto_play_motion(action)
    ret = true
    case action[2]
    when 0  # 通常攻撃
      @active_battler.current_action.kind = 0
      @active_battler.current_action.basic = 0
      ret = make_auto_play_target(action[4], 1)
    when 1  # 防御
      @active_battler.current_action.kind = 0
      @active_battler.current_action.basic = 1
    when 2  # スキル
      @active_battler.current_action.kind = 1
      @active_battler.current_action.skill_id = skill_id = action[3]
      # 使えない場合は再選択
      return nil unless @active_battler.skill_can_use?(skill_id)
      # ターゲット選択
      ret = make_auto_play_target(action[4], $data_skills[skill_id].scope)
    when 3  # アイテム
      @active_battler.current_action.kind = 2
      @active_battler.current_action.item_id = item_id = action[3]
      # 持ってない場合は再選択
      return nil if $game_party.item_number(item_id) == 0
      # ターゲット選択
      ret = make_auto_play_target(action[4], $data_items[item_id].scope)
    else
      p "行動パターン::行動種類 設定ミス"
      exit
    end
    return ret
  end
  #--------------------------------------------------------------------------
  # ● ターゲット選択
  #--------------------------------------------------------------------------
  def make_auto_play_target(mode, scope)
    case scope
    when 0, 2, 4, 6, 7   # 全体攻撃なので設定不要
      @active_battler.current_action.target_index = 0
    else  # その他単体攻撃
      # ターゲット選択
      case mode
      when 0  # ランダム
        case scope
        when 1    # 敵
          @active_battler.current_action.target_index = make_randum_target($game_troop.enemies)
        when 3, 5 # 味方
          @active_battler.current_action.target_index = make_randum_target($game_party.actors)
        end
      when 1  # 残HPの低い者
        case scope
        when 1    # 敵
          @active_battler.current_action.target_index = make_crisis_target($game_troop.enemies)
        when 3
          @active_battler.current_action.target_index = make_crisis_target($game_party.actors)
        when 5    # 味方(HP0)
          target = make_dead_target
          return nil if target.nil?   # 選び直し
          @active_battler.current_action.target_index = target
        end
      when 2  # 残HPの高い者
        case scope
        when 1    # 敵
          @active_battler.current_action.target_index = make_vigour_target($game_troop.enemies)
        when 3    # 味方
          @active_battler.current_action.target_index = make_vigour_target($game_party.actors)
        when 5    # 味方(HP0)
          target = make_dead_target
          return nil if target.nil?   # 選び直し
          @active_battler.current_action.target_index = target
        end
      else
        p "行動パターン::ターゲット 設定ミス"
        exit
      end
    end
    return true
  end
  #--------------------------------------------------------------------------
  # ● ランダムターゲット選択
  #--------------------------------------------------------------------------
  def make_randum_target(targets)
    while 0
      index = rand(targets.size)
      if targets[index].exist?
        return index
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 残HP低ターゲット選択
  #--------------------------------------------------------------------------
  def make_crisis_target(targets)
    target_hp = 1000000
    target_index = make_randum_target(targets)
    for index in 0...targets.size
      if targets[index].hp < target_hp
        target_hp = targets[index].hp
        target_index = index
      end
    end
    return target_index
  end
  #--------------------------------------------------------------------------
  # ● 残HP高ターゲット選択
  #--------------------------------------------------------------------------
  def make_vigour_target(targets)
    target_hp = 0
    target_index = make_randum_target(targets)
    for index in 0...targets.size
      if targets[index].hp > target_hp
        target_hp = targets[index].hp
        target_index = index
      end
    end
    return target_index
  end
  #--------------------------------------------------------------------------
  # ● 残HP0ターゲット選択
  #--------------------------------------------------------------------------
  def make_dead_target
    target_index = []
    for index in 0...$game_party.actors.size
      if $game_party.actors[index].dead?
        target_index.push(index)
      end
    end
    return nil if target_index.empty
    return target_index[rand(target_index.size)]
  end
end
[/pre]

点评

百度是个好东西汉化了,好东西啊,正在研究。  发表于 2019-10-21 21:17

评分

参与人数 2星屑 +50 赞 +1 收起 理由
RyanBern + 50 认可答案
miantouchi + 1 是好东西,日文脑袋大。。。

查看全部评分

回复 1 0

使用道具 举报

梦石
0
星屑
15041
在线时间
2230 小时
注册时间
2019-1-24
回帖
964

R考场第七期纪念奖

 楼主| 发表于 2019-10-21 22:37:37 | 显示全部楼层
本帖最后由 miantouchi 于 2019-10-21 22:43 编辑
soulsaga 发表于 2019-10-21 13:46
#==============================================================================
# ■ XP-RGSS-47 オー ...


帮我看下
第1.
  PT_SW[1] = 1 这个是指第1个角色用默认1模式
  PT_SW[2] = 2 这个是指第2个角色用默认2模式(默认脚本没有设置角色2的模式2)
  PT_SW[3] = 3 这个是指第3个角色用默认3模式(默认脚本没有设置角色3的模式3)
  PT_SW[4] = 4 这个是指第4个角色用默认4模式(默认脚本没有设置角色4的模式4)
是这个意思吗
第2.分级1-10是优先级的意思吗?
AT_PATTERN_1_0 = [
    [5, 0, 0, nil, 0],   # 分级5:无条件:普通攻击:随机
    [2, 0, 2,  57, 2],   # 分级2:无条件:技能:十字斩;剩余HP较高者
    [1, 0, 1, nil, 0]    # 分级1:无条件:防御
  ]
这个是不是意思是普通攻击占一半几率,十字斩,占20%,防御10%几率
另外我要添加多个技能咋办?
AT_PATTERN_1_0 = [
    [5, 0, 0, nil, 0],   # 分级5:无条件:普通攻击:随机
    [2, 0, 2,  57, 2],   # 分级2:无条件:技能:十字斩;剩余HP较高者
    [1, 0, 1, nil, 0],   # 分级1:无条件:防御
    [2, 0, 2,  58, 2]   # 分级2:无条件:技能:十字斩;剩余HP较高者
  ]
我在后边加上58号特技好像没反应
1.png
2.png
回复

使用道具 举报

梦石
0
星屑
39236
在线时间
11155 小时
注册时间
2009-3-15
回帖
4768
发表于 2019-10-21 22:41:15 | 显示全部楼层

没错是权重..也就是优先度..

点评

终于搞明白怎么用了。  发表于 2019-10-22 12:00
好吧  发表于 2019-10-22 07:04
我没用过...你自行趼究..  发表于 2019-10-21 23:00
我又补充了下,麻烦帮我看看  发表于 2019-10-21 22:44
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部