【RGSS3】名前入力の処理での職業名の変更について

せくもん
記事: 39
登録日時: 2018年6月09日(土) 21:48

【RGSS3】名前入力の処理での職業名の変更について

投稿記事by せくもん » 2019年7月03日(水) 22:34

いつもお世話になっております。
製作中のゲームでアクター名と別に職業名を固有名詞として使用する為に
Scene_Nameの25行目からを下記のように改変し

コード: 全て選択

 
  #--------------------------------------------------------------------------
  # ● 入力[決定]
  #--------------------------------------------------------------------------
  def on_input_ok
   if $game_variables[1] == 10
    @actor.class.name = @edit_window.name
   else
    @actor.name = @edit_window.name
   end
    return_scene
  end


Window_Baseの235行目あたりに

コード: 全て選択

result.gsub!(/\eJ\[(\d+)\]/i) { $data_classes[$1.to_i].name }

と書き加える事でプレイヤーが入力した職業名を制御文字で表示出来るようにしたのですが
現状では職業名の入力の際にデフォルトでアクター名が表示されており
プレイヤーが名前を変更しないまま名前入力を確定させると
『アクター名:エリック 職業名:エリック』みたいな結果になってしまいます。

変数[1]が10の時のみ名前入力の際のデフォルト名に職業名を表示させるには
どのようにしたら良いのでしょうか?

ぽんぽこねるそん
記事: 53
登録日時: 2018年10月26日(金) 12:24

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ぽんぽこねるそん » 2019年7月04日(木) 00:35

せくもんさん、こんばんは。
名前入力のデフォルト名はWindow_NameEditのinitializeで決めているので

コード: 全て選択

class Window_NameEdit < Window_Base
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(actor, max_char)
    x = (Graphics.width - 360) / 2
    y = (Graphics.height - (fitting_height(4) + fitting_height(9) + 8)) / 2
    super(x, y, 360, fitting_height(4))
    @actor = actor
    @max_char = max_char
    @default_name = @name = ($game_variables[1] == 10 ? @actor.class.name : actor.name)[0, @max_char]
    @index = @name.size
    deactivate
    refresh
  end
end

こんな感じにしてやれば変数1が10の時にデフォルトが職業名になります。

あと余計なお世話かもしれませんが2点ほど。
1.職業名を制御文字で表示させる処理ですがそのままだと
存在しない職業が指定された場合にエラーになるので職業が存在しなかった場合は
空文字列に置換したほうがよろしいかと思います。

コード: 全て選択

result.gsub!(/\eJ\[(\d+)\]/i) { $data_classes[$1.to_i] ? $data_classes[$1.to_i].name : ""}


2.職業名はデフォルトだと保存されないのでプレイヤーが入力しても
ロードすると元に戻ってしまいますがいいのでしょうか。
せくもん
記事: 39
登録日時: 2018年6月09日(土) 21:48

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by せくもん » 2019年7月04日(木) 22:53

ぽんぽこねるそん様、ご返答ありがとうございます。

教えて頂いたコードでWindow_NameEditを改変したところ
無事にデフォルト名を職業名にする事が出来ました。
どうもありがとうございます。

ところで、ご指摘頂いた件に関してですが
概要としてはアクター名を『ロボットの名前』、職業名を『操縦するパイロットの名前』として
戦闘中のバトルログ「○○の攻撃!」等ではアクター名
町の中での会話では職業名で呼ばれる物を想定していました。

1.に関しては『存在しない職業』の定義がよく分からなかったので再現する事が出来ませんでしたが
一応、パーティから外した状態でも制御文字で不在のメンバーの職業名を表示出来る事は確認しました。

2.に関しては致命的で、いつもテストプレーをニューゲームで行なっていた為
セーブデータから再開したケースにおいては完全に盲点でした。
ゲーム中でパイロットの名前を変更出来るのは主人公の『アクター1』のみなので
アクター1の職業名だけでもセーブデータの保存内容に追加する事は可能でしょうか?
ショウ
記事: 135
登録日時: 2016年8月10日(水) 19:52

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ショウ » 2019年7月05日(金) 00:08

とりあえず2の職業名の保存状態について。
ぽんぽこねるそんさんの言う様に職業名などは変更する事自体はさほど難しくは無いんですが、
その状態が保存されないのでロード時にデータベースで設定されている状態に戻ってしまいます。
保存させる事も出来なくはないしたしかそういうスクリプトをどこかで見た気はしますが個人的
にはあまりオススメしません。
なので今回はもっと単純の方法でロード時に再設定する方法を紹介します。
スクリプトのDataManagerの中にロードの実行という部分があるので下の様にしてみて下さい。

#--------------------------------------------------------------------------
# ● ロードの実行
#--------------------------------------------------------------------------
def self.load_game(index)
load_game_without_rescue(index) rescue false
$game_switches[1] = true#追加部分
end

こうするとロード時にスイッチ1番がONになる様になります。
なお番号に関しては便宜上の物なので都合の良い番号を使ってください。
そして適当なコモンイベントを自動実行にしてトリガーを指定したスイッチに設定してください。
これで下準備は完了です。
あとは職業名変更の際に適当な変数に変更した名前を代入しておき、このコモンイベントで今度
は逆にその変数を使って再設定する様に設定しましょう。
こうする事でロード時に自動的に指定のコモンイベントが実行され再設定してくれます。
もちろん他の事に使ってもOKなのでロード時になにか動作させたい事があるなら一緒に
設定しましょう。
コモンイベントを弄るだけで良いので誰でも作りやすく案外汎用性が高いかと思います。
注意点としてはコモンイベントの設定の際にこのスイッチをちゃんとOFFにしないと
無限ループに陥ってしまうので忘れないようにしてください。

ついでにスクリプト素材も置いときます。(素材というほど大層な物では無いですが)
需要があるかは分からんが探して追加するのが面倒な人向け、もしくはスクリプトよく分からん
というツクール初心者向けに、これ突っ込むだけで上のと同じ動作になります。

コード: 全て選択

#ロード時スイッチON
#byショウ

module DataManager
  #--------------------------------------------------------------------------
  # ● ロードの実行
  #--------------------------------------------------------------------------
  def self.load_game(index)
    load_game_without_rescue(index) rescue false
    $game_switches[1] = true
  end
end

素材単体での販売以外自由
ぽんぽこねるそん
記事: 53
登録日時: 2018年10月26日(金) 12:24

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ぽんぽこねるそん » 2019年7月05日(金) 06:38

『存在しない職業』はデータベースに存在しない職業のことです。
\j[0]とか\j[10000]みたいに0や職業の最大数より大きい数を指定した時に
そのままだとエラーになりますという意味でした。

職業名の保存ですが出来ればパイロット名に職業を使わずに
Game_Actorに新しい変数を用意してそれを職業の代わりに表示するようにしたほうがいいんですが
どうしても職業を使う必要があるならはショウさんが書かれているようにロード時に上書きするようにするか

コード: 全て選択

class Game_System
  attr_accessor :class_names
  alias org_initialize initialize
  def initialize
    org_initialize
    @class_names = {}
  end
end
class RPG::Class < RPG::BaseItem
  alias org_name name
  def name
    $game_system.class_names ||= {}
    $game_system.class_names[self.id] || org_name
  end
  alias_method "org_set_name", "name="
  def name=(name)
    org_set_name(name)
    $game_system.class_names ||= {}
    $game_system.class_names[self.id] = @name
  end
end

こんな感じで名前を変更した時に別の場所に記録するようにして
記録があった場合はそれを返すようにすれば一応保存することはできます。
ecf5DTTzl6h6lJj02
記事: 139
登録日時: 2018年12月23日(日) 13:55

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ecf5DTTzl6h6lJj02 » 2019年7月05日(金) 18:13

パイロット名を処理するスクリプトを作成してみました。
以下のスクリプトを導入してみてください。

コード: 全て選択

=begin
------------------------------------------------------------------------------
 ■パイロット名を追加、処理するためのスクリプト
   2019/07/05  by ecf5DTTzl6h6lJj02
------------------------------------------------------------------------------
 概要:
  パイロット名を処理するためのスクリプト
  以下の機能を有します。
 
  ・Game_Actor の変数として パイロット名をあらわす pilot という変数を持ち、
    ステータス画面において、職業名の変わりにパイロット名を表示させます。
    パイロット名の初期値はアクターに設定した職業名になります。
 
  ・PN_Switchで指定した番号のスイッチがオンのとき、名前入力の処理を実行すると
    アクター名ではなくパイロット名を入力するモードになります。
   
  ・エスケープ文字として \PN[n] を追加
    メッセージウィンドウ等で、このエスケープ文字を使用して、
    パイロット名を表示できます。
------------------------------------------------------------------------------
=end

if true         #この機能を使うかどうかのフラグ 使わないときはfalse
 
module Add_Pilot
  PN_Switch = 100    #この番号のスイッチがオンの時はパイロット名入力モード
end

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :pilot          #パイロット名

  #--------------------------------------------------------------------------
  # ● セットアップ
  #--------------------------------------------------------------------------
  def setup(actor_id)
    @actor_id = actor_id
    @name = actor.name
    @nickname = actor.nickname
    init_graphics
    @class_id = actor.class_id
    @pilot = $data_classes[@class_id].name
    @level = actor.initial_level
    @exp = {}
    @equips = []
    init_exp
    init_skills
    init_equips(actor.equips)
    clear_param_plus
    recover_all
  end
end
 
class Window_Base
   #--------------------------------------------------------------------------
  # ● アクター n 番のパイロット名を取得
  #--------------------------------------------------------------------------
  def actor_pilot(n)
    actor = n >= 1 ? $game_actors[n] : nil
    actor ? actor.pilot : ""   
  end 
  #--------------------------------------------------------------------------
  # ● パイロットの描画
  #--------------------------------------------------------------------------
  def draw_actor_pilot(actor, x, y, width = 112)
    change_color(hp_color(actor))
    draw_text(x, y, width, line_height, actor.pilot)
  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_pilot(actor, x + 120, y)
#~     draw_actor_class(actor, x + 120, y)
    draw_actor_hp(actor, x + 120, y + line_height * 1)
    draw_actor_mp(actor, x + 120, y + line_height * 2)
  end
  #--------------------------------------------------------------------------
  # ● 制御文字の事前変換
  #    実際の描画を始める前に、原則として文字列に変わるものだけを置き換える。
  #    文字「\」はエスケープ文字(\e)に変換。
  #--------------------------------------------------------------------------
  def convert_escape_characters(text)
    result = text.to_s.clone
    result.gsub!(/\\/)            { "\e" }
    result.gsub!(/\e\e/)          { "\\" }
    result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
    result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }   
    result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) }   
    #\PN[n]でパイロット名を表示できるように変更
    result.gsub!(/\ePN\[(\d+)\]/i){ actor_pilot($1.to_i) }
    result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
    result.gsub!(/\eG/i)          { Vocab::currency_unit }
    result
  end
end

class Window_Status < Window_Selectable
  #--------------------------------------------------------------------------
  # ● ブロック 1 の描画
  #--------------------------------------------------------------------------
  def draw_block1(y)
    draw_actor_name(@actor, 4, y)
#~     draw_actor_class(@actor, 128, y)
    draw_actor_pilot(@actor, 128, y)
    draw_actor_nickname(@actor, 288, y)
  end 
end

class Window_NameEdit < Window_Base
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(actor, max_char)
    x = (Graphics.width - 360) / 2
    y = (Graphics.height - (fitting_height(4) + fitting_height(9) + 8)) / 2
    super(x, y, 360, fitting_height(4))
    @actor = actor
    @max_char = max_char
    @default_name = @name = $game_switches[Add_Pilot::PN_Switch] ?
      actor.pilot[0, @max_char] : actor.name[0, @max_char]
    @index = @name.size
    deactivate
    refresh
  end 
end

class Scene_Name < Scene_MenuBase
  #--------------------------------------------------------------------------
  # ● 入力[決定]
  #--------------------------------------------------------------------------
  def on_input_ok
    if $game_switches[Add_Pilot::PN_Switch]
      @actor.pilot = @edit_window.name
    else     
      @actor.name = @edit_window.name
    end
    return_scene
  end 
end

end           # if true に対応する end です 誤消去注意

▼素材 の一番下においてください。
使い方は、コード内の説明書きを見てください。

一応、自分の制作環境下では動作していると思うけれど、きちんとテストして無いので、
不具合が出る可能性はあります。
また、競合に関しては、ほぼ(というか全く)考えていないので、注意してください。

(2019/07/05 18:49 頃 追記)
アクターn番のパイロット名取得の処理がおかしくなっていたので、直しました。
せくもん
記事: 39
登録日時: 2018年6月09日(土) 21:48

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by せくもん » 2019年7月05日(金) 22:07

皆様、ご返答ありがとうございます。

様々な解決策をご提示いただいてありがたいのですが、ひとつ疑問が生じました。

VX aceのデフォルトの仕様ではメニュー画面やステータス画面で
アクター名 職業名 (二つ名) の順で配置されており、特にスクリプト等を導入しなくても
職業名を利用すれば『ガンダム アムロ』『ザク シャア』といった並びが簡単に再現できると
考えたのが事の発端でした。

別の変数を用いてパイロット名を表示するには、これら全てのスクリプトに手を加える必要があり
出力結果がデフォルトとほぼ変わらない上に名前変更を要しないアクター2以降のメンバーには
意味の無い処理である様に(自分には)感じられるのですが

確かに『どうしても職業を使う必要がある』わけではありませんが
逆に『頑なに職業を使うのを避ける』理由がわかりません。
セーブデータに保存されない以外で、何か職業を使わないほうがいい事情があるのでしょうか?
ショウ
記事: 135
登録日時: 2016年8月10日(水) 19:52

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ショウ » 2019年7月06日(土) 00:35

ぶっちゃけせくもんさんのやりたいくらいの変更ならあんま気にしないで良い程度の話だよ、
ただ保存を前提とするなら二人の言う方法になるし、
アクター1以外にも処理したいならecf5DTTzl6h6lJj02さんのスクリプトはたしかに便利ではある。
まぁ今回の内容に特化した内容ではあるから俺の言った再設定と違って今回のとまったく関係無い
他の処理をぶっこむのは出来ないね。
今回の内容なら再設定か保存かは好みの方を選べばいいよ。
ecf5DTTzl6h6lJj02
記事: 139
登録日時: 2018年12月23日(日) 13:55

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ecf5DTTzl6h6lJj02 » 2019年7月06日(土) 16:52

前回載せたスクリプトに関しては、トピックの内容をあまりちゃんと読まずに流していたため、
職業名保存できないし、どこかにセーブできる変数を追加するなら、Game_Actorsに変数を追加して使ったほうが楽かな?Game_Actorsに変数追加するなら、ステータス画面でもそれを使ったほうがいいし、ついでだから、変えちゃおうか。
という、割と安易な思考で作られているので、
頑なに職業名を使うことを避けている訳ではなく、たいした意味もありませんので、
前回の回答は無かったものとして扱って頂いて構いませんし、その辺りはあまり気にしないでください。疑問を持たせてしまったようで、申し訳ないです。

話題は変わりますが、アクター1の職業名だけセーブデータに追加できるか試してみたところ、
できそうなので、以下にスクリプトを置いておきます。

コード: 全て選択

module DataManager
  #--------------------------------------------------------------------------
  # ● セーブ内容の作成
  #--------------------------------------------------------------------------
  def self.make_save_contents
    contents = {}
    contents[:system]               = $game_system
    contents[:timer]                = $game_timer
    contents[:message]              = $game_message
    contents[:switches]             = $game_switches
    contents[:variables]            = $game_variables
    contents[:self_switches]        = $game_self_switches
    contents[:actors]               = $game_actors
    contents[:party]                = $game_party
    contents[:troop]                = $game_troop
    contents[:map]                  = $game_map
    contents[:player]               = $game_player
    #アクター1番の職業名を保存できるよう追加
    contents[:actor1_class_name]    = $game_actors[1].class.name
    contents
  end
  #--------------------------------------------------------------------------
  # ● セーブ内容の展開
  #--------------------------------------------------------------------------
  def self.extract_save_contents(contents)
    $game_system                  = contents[:system]
    $game_timer                   = contents[:timer]
    $game_message                 = contents[:message]
    $game_switches                = contents[:switches]
    $game_variables               = contents[:variables]
    $game_self_switches           = contents[:self_switches]
    $game_actors                  = contents[:actors]
    $game_party                   = contents[:party]
    $game_troop                   = contents[:troop]
    $game_map                     = contents[:map]
    $game_player                  = contents[:player]
    #アクター1番の職業名を展開するように追加
    $game_actors[1].class.name   = contents[:actor1_class_name]
  end
end

とりあえず、自分の環境下では正しくセーブ・ロードできてるようです。
(今までのセーブデータをロードすることはできないので注意してください)
ぽんぽこねるそん
記事: 53
登録日時: 2018年10月26日(金) 12:24

Re: 【RGSS3】名前入力の処理での職業名の変更について

投稿記事by ぽんぽこねるそん » 2019年7月06日(土) 17:14

保存されないものを保存するようにするのが問題でそれをするには
前にも書いたように別の場所に保存するようにするか
$data_classesをセーブデータに含めるようにする必要があるんですが

セーブデータに含めると後からエディタで変更したものがセーブデータに反映されなくなるので
ロードした後にClasses.rvdata2を読み込んで名前以外のデータをこれに置き換える処理が必要になります。

別の場所に保存すると関係のない保存されるグローバル変数に保存するのでバグが起きやすくなります。
例えばショウさんが書かれている方法だとゲーム変数に保存してロード時に変更するので
何処かで他の変数に代入するものを間違えて保存している変数に代入してしまった時に
直ぐには変わらずその処理を行った後でセーブするとロードした時に職業名が代入したものに変わるので
何処で代入したかすぐわかるようなものならまだいいですが0とかわからないようなものだと
一つ一つイベントを調べないといけなくて面倒なことになるわけです。

それでパイロット名をプレイヤーが変更できるようにする時点でどちらにせよ
スクリプトに手を加える必要があってどちらが簡単か考えると
Game_Actorに新しい変数作ったほうが簡単なのでそっちの方がよくない?
となるわけです。

コード: 全て選択

#アクターにパイロットを追加して職業の代わりにパイロットの名前を表示するようにします
#パイロットにはアクターを使用しています
#初期パイロットを設定する時はアクターのメモ欄に<パイロットID:パイロットにするアクターのID>を記述してください
#パイロットが設定されていない場合は職業を表示します

#==============================================================================
# ■ Game_Actor
#------------------------------------------------------------------------------
#  アクターを扱うクラスです。このクラスは Game_Actors クラス($game_actors)
# の内部で使用され、Game_Party クラス($game_party)からも参照されます。
#==============================================================================

class Game_Actor < Game_Battler
  attr_accessor :pilot_id
  #--------------------------------------------------------------------------
  # ● セットアップ
  #--------------------------------------------------------------------------
  alias org_setup setup
  def setup(actor_id)
    org_setup(actor_id)
    @pilot_id = actor.pilot_id
  end
  #--------------------------------------------------------------------------
  # ● パイロットの取得
  #--------------------------------------------------------------------------
  def pilot
    $game_actors[@pilot_id]
  end
  #--------------------------------------------------------------------------
  # ● パイロット名の取得
  #--------------------------------------------------------------------------
  def pilot_name
    self.pilot ? self.pilot.name : self.class.name
  end
end
#==============================================================================
# ■ Window_Base
#------------------------------------------------------------------------------
#  ゲーム中の全てのウィンドウのスーパークラスです。
#==============================================================================

class Window_Base < Window
  #--------------------------------------------------------------------------
  # ● 職業の描画(パイロット名を描画するように再定義)
  #--------------------------------------------------------------------------
  def draw_actor_class(actor, x, y, width = 112)
    change_color(normal_color)
    draw_text(x, y, width, line_height, actor.pilot_name)
  end
end
class RPG::Actor < RPG::BaseItem
  #--------------------------------------------------------------------------
  # ● パイロットIDの取得
  #--------------------------------------------------------------------------
  def pilot_id
    /<パイロットID:(\d+)>/ =~ note ? $1.to_i : 0
  end
end

こんな感じでアクターを使うようにすれば
職業名の保存も名前入力画面の変更や制御文字の追加が必要なくなるので
こちらのほうが簡単だと思うのですが……

“VX / Ace:質問” へ戻る