What's new

Need help setting up RPG Maker XP for editing


Strange

Demon Girl Pro
Joined
Jul 24, 2014
Messages
1,256
Reputation score
486
Just from looking at the picture I think the problem lies with the line 121. You can clearly see it replaces both 'A' and 'a' with \101[#{$1}]

Removing [Aa] from the line should fix it, but without the whole script, I don't know if that's the only line or what the possible bugs will be.
I don't think it's there for no reason.
Nope, that'd be too easy.
/[Aa][Ll]/ only matches with "AL","Al","al" or "aL". (edited for the right slashes...)

121 is innocent, but it did catch my eye as well.
 
Last edited:
OP
candyfloss

candyfloss

Sex Demon
Joined
Oct 13, 2013
Messages
303
Reputation score
446
I managed to "fix" it!

22550

I tried the suggestions given in the last page such as if c == "\025" and the [Aa] between line 121 to line 135, but those didn't work...

However, changing one of the values in line 170 made it work!

22551

I changed the value of if c == "\101" to if c == "999" to make it work!
I'm not sure what other impact I had done by changing this line though, hopefully it doesn't cause any bugs.
Like kR1pt0n1t3 said, it looks like that the script was trying to replace [Aa] with \101, but I already tried editing that line and it didn't work. So, who knows what the whole clunk of code is trying to do.

I'll paste the corrected code below for reference if anyone want to take a look at it.

Search for .slice to reach line 124,
Search for # \AL[n] の場合 to reach line 169 where the change was made at line 170

Code:
#==============================================================================
# ■ Window_Message
#------------------------------------------------------------------------------
#  文章表示に使うメッセージウィンドウです。
#==============================================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    super(80, 304, 480, 160)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.visible = false
    self.z = 9998
    @hide = false
    @fade_in = false
    @fade_out = false
    @contents_showing = false
    @cursor_width = 0
    self.active = false
    self.index = -1
    font_size = 22

# ★==========================================================================☆
    # 名前用小型ウィンドウ作成
    @name_window = Window_Base.new(80, 240, 160, 48)
    @name_window.visible = false
    @name_window.back_opacity = 160
    @name_window.z = 9999
# ☆==========================================================================★
  end
  #--------------------------------------------------------------------------
  # ● 解放
  #--------------------------------------------------------------------------
  def dispose
    terminate_message
    $game_temp.message_window_showing = false
    if @input_number_window != nil
      @input_number_window.dispose
    end
# ★==========================================================================☆
    @name_window.dispose
# ☆==========================================================================★
    super
  end
  #--------------------------------------------------------------------------
  # ● メッセージ終了処理
  #--------------------------------------------------------------------------
  def terminate_message
    self.active = false
    self.pause = false
    self.index = -1
    self.contents.clear
    # 表示中フラグをクリア
    @contents_showing = false
    # メッセージ コールバックを呼ぶ
    if $game_temp.message_proc != nil
      $game_temp.message_proc.call
    end
    # 文章、選択肢、数値入力に関する変数をクリア
    $game_temp.message_text = nil
    $game_temp.message_proc = nil
    $game_temp.choice_start = 99
    $game_temp.choice_max = 0
    $game_temp.choice_cancel_type = 0
    $game_temp.choice_proc = nil
    $game_temp.num_input_start = 99
    $game_temp.num_input_variable_id = 0
    $game_temp.num_input_digits_max = 0
    # ゴールドウィンドウを開放
    if @gold_window != nil
      @gold_window.dispose
      @gold_window = nil
    end
  end
  #--------------------------------------------------------------------------
  # ● リフレッシュ
  #--------------------------------------------------------------------------
  def refresh
# ★==========================================================================☆
    self.contents.clear
    # ウィンドウ初期化
    initialize_window
    # 文字列バッファ作成
    text_buf = []; trans_x = []
    text_buf[0] = Bitmap.new(608, 32)
    trans_x[0] = 0
    # メッセージウィンドウ自動サイズ調整がオフの場合
    unless $game_system.message_auto_adjust
      self.contents = Bitmap.new(width - 32, height - 32)
    end
    text_buf[0].font.color = self.normal_color
    x = y = max_x = 0
# ☆==========================================================================★
    @cursor_width = 0
    # 選択肢なら字下げを行う
    if $game_temp.choice_start == 0
      x = 8
    end
    # 表示待ちのメッセージがある場合
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      # 制御文字処理
      begin
        last_text = text.clone
        text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
      end until text == last_text
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
      end
      # 便宜上、"\\\\" を "\000" に変換
      text.gsub!(/\\\\/) { "\000" }
      # "\\C" を "\001" に、"\\G" を "\002" に変換
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      text.gsub!(/\\[Ff]\[(\d+)\]/) { "\025[#{$1}]" }

# ★==========================================================================☆
      # "\\AL" を "\101" に変換
      text.gsub!(/\\[Aa][Ll]\[([0-9]+)\]/) { "\101[#{$1}]" }
# ☆==========================================================================★
      # c に 1 文字を取得 (文字が取得できなくなるまでループ)
      while ((c = text.slice!(/./m)) != nil)
        # \\ の場合
        if c == "\000"
          # 本来の文字に戻す
          c = "\\"
        end
        # \C[n] の場合
        if c == "\001"
          # 文字色を変更
          text.sub!(/\[([0-9]+)\]/, "")
          color = $1.to_i
          if color >= 0 and color <= 7
# ★==========================================================================☆
            text_buf[y].font.color = self.text_color(color)
# ☆==========================================================================★
          end
          # 次の文字へ
          next
        end
   
        # \F[n] の場合、フォントサイズの変更
        if c == "\025"
          text.sub!(/\[([0-9]+)\]/, "")
          self.contents.font.size = $1.to_i
          next
        end

        # \G の場合
        if c == "\002"
          # ゴールドウィンドウを作成
          if @gold_window == nil
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            if $game_temp.in_battle
              @gold_window.y = 192
            else
              @gold_window.y = self.y >= 128 ? 32 : 384
            end
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          # 次の文字へ
          next
        end
# ★==========================================================================☆
        # \AL[n] の場合
        if c == "\999"
          # アラインタイプを変更
          text.sub!(/\[([0-9]+)\]/, "")
          align = $1.to_i
          # 次の文字へ
          next
        end
# ☆==========================================================================★
        # 改行文字の場合
        if c == "\n"
          # 選択肢ならカーソルの幅を更新
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
# ★==========================================================================☆
          # y に 1 を加算
          y += 1
          # 新しい文字列バッファを作成
          text_buf[y] = Bitmap.new(608, 32)
          text_buf[y].font.color = self.normal_color
          # x の最大値更新判定
          max_x = [x, max_x].max
          # x を初期化
          x = 0
# ☆==========================================================================★
          # 選択肢なら字下げを行う
          if y >= $game_temp.choice_start
            x = 8
          end
          # 次の文字へ
          next
        end
# ★==========================================================================☆
        # 文字を描画
        text_buf[y].font.size = self.contents.font.size
        text_buf[y].draw_text(4 + x, 0, 40, 32, c)
        # x に描画した文字の幅を加算
        x += text_buf[y].text_size(c).width
        # 転送用X座標保存
        trans_x[y] = x
        # 選択肢の場合はインデント分戻す
        trans_x[y] += 12 if $game_temp.choice_max > 0
# ☆==========================================================================★
      end
    end
# ★==========================================================================☆
    # メッセージウィンドウ自動サイズ調整がオンの場合
    if $game_system.message_auto_adjust
      # 数値入力の場合は1行余分に追加
      y += 1 if $game_temp.num_input_variable_id > 0
      # ウィンドウサイズを調整
      self.width = max_x + 48
      self.height = y * 32 + 32
      # 顔グラフィックが存在する場合
      if @face_bitmap != nil
        # ウィンドウの幅を加算
        self.width = 630
        #self.width += @face_bitmap.width + 16
        # ウィンドウの高さが顔グラフィックよりも小さい場合
        if @face_bitmap.height + 32 > self.height
          # 顔グラフィックより大きいサイズに設定
          self.height = @face_bitmap.height + 32
        end
        self.contents = Bitmap.new(width - 32, height - 32)
        face_y = (self.contents.height - @face_bitmap.height) / 2
        # 顔グラフィックが左側表示の場合
        if $msg_face[1] == 0
          @text_x = @face_bitmap.width + 16
          self.contents.blt(8, face_y, @face_bitmap,
            Rect.new(0, 0, @face_bitmap.width, @face_bitmap.height))
        else
          @text_x = 0
          self.contents.blt(self.contents.width - @face_bitmap.width - 8,
            face_y, @face_bitmap,
            Rect.new(0, 0, @face_bitmap.width, @face_bitmap.height))
        end
      else
        @text_x = 0
        self.width = 630
        self.contents = Bitmap.new(width - 32, height - 32)
      end
      # 中央に移動
      centering_window
    # メッセージウィンドウ自動サイズ調整がオフの場合
    else
      # 顔グラフィックが存在する場合
      if @face_bitmap != nil
        # ウィンドウの幅を加算
        self.width += @face_bitmap.width + 16
        # ウィンドウの高さが顔グラフィックよりも小さい場合
        if @face_bitmap.height + 32 > self.height
          # 顔グラフィックより大きいサイズに設定
          self.height = @face_bitmap.height + 32
        end
        self.contents = Bitmap.new(width - 32, height - 32)
        face_y = (self.contents.height - @face_bitmap.height) / 2
        # 顔グラフィックが左側表示の場合
        if $msg_face[1] == 0
          @text_x = @face_bitmap.width + 16
          self.contents.blt(8, face_y, @face_bitmap,
            Rect.new(0, 0, @face_bitmap.width, @face_bitmap.height))
        else
          @text_x = 0
          self.contents.blt(self.contents.width - @face_bitmap.width - 8,
            face_y, @face_bitmap,
            Rect.new(0, 0, @face_bitmap.width, @face_bitmap.height))
        end
      else
        @text_x = 0
      end
    end
    # ウィンドウ内容を描画
    for i in 0...text_buf.size
      next if text_buf[i] == nil
      trans_x[i] = 0 if trans_x[i] == nil
      # 転送用X座標設定
      align = $game_system.message_align if align == nil
      case align
      when 0  # 左側
        tx = @text_x
      when 1  # 中央
        if $msg_face != nil && $msg_face[1] == 1
          tx = (self.contents.width - trans_x[i] - @face_bitmap.width - 16) / 2
        else
          tx = (self.contents.width - trans_x[i] + @text_x) / 2
        end
      when 2  # 右側
        if $msg_face != nil && $msg_face[1] == 0
          tx = self.contents.width - trans_x[i] - 8
        elsif $msg_face != nil && $msg_face[1] == 1
          tx = self.contents.width - trans_x[i] - @face_bitmap.width - 24
        else
          tx = self.contents.width - trans_x[i] + @text_x - 8
        end
      end
      self.contents.blt(tx, i * 32, text_buf[i], Rect.new(0, 0, 608, 32))
    end
# ☆==========================================================================★
    # 選択肢の場合
    if $game_temp.choice_max > 0
      @item_max = $game_temp.choice_max
      self.active = true
      self.index = 0
    end
    # 数値入力の場合
    if $game_temp.num_input_variable_id > 0
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
# ★==========================================================================☆
      @input_number_window.x = self.x + 8 + @text_x
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
      # メッセージウィンドウ自動サイズ調整がオンの場合
      if $game_system.message_auto_adjust
        # ウィンドウの幅を調整
        self.width = [self.width, @input_number_window.width + 16].max
        # ウィンドウを中央へ移動
        centering_window
        # 数値入力ウィンドウ位置を調整
        @input_number_window.x = self.x + 8 + @text_x
      end
# ☆==========================================================================★
    end
# ★==========================================================================☆
    # 名前が設定されている場合、名前表示
    if $msg_name != nil
      bitmap = Bitmap.new(32, 32)
      bitmap.font.size = 18
      cx = bitmap.text_size($msg_name).width
      @name_window.width = cx + 32
      @name_window.contents.dispose if @name_window.contents != nil
      @name_window.contents = Bitmap.new(cx, 16)
      @name_window.contents.font.size = 18
      @name_window.contents.draw_text(0, 0, cx + 8, 16, $msg_name)
      @name_window.visible = true
    # 名前が設定されていない場合、ウィンドウ消去
    else
      @name_window.visible = false
    end
# ☆==========================================================================★
  end
# ★==========================================================================☆
  #--------------------------------------------------------------------------
  # ● ウィンドウ設定初期化
  #--------------------------------------------------------------------------
  def initialize_window
    if $msg_face == nil || $msg_face[0] == nil || $msg_face[1] == nil
      @face_bitmap.dispose if @face_bitmap != nil
      @face_bitmap = nil
      self.width = 480
    else
      @face_bitmap = RPG::Cache.picture($msg_face[0])
      self.width = 496 + @face_bitmap.width
    end
    self.x = (640 - self.width) / 2
    self.y = 304
    self.height = 160
    reset_window
  end
  #--------------------------------------------------------------------------
  # ● ウィンドウを中央に移動
  #--------------------------------------------------------------------------
  def centering_window
    self.x = (640 - self.width) / 2
    @name_window.x = self.x
  end
# ☆==========================================================================★
  #--------------------------------------------------------------------------
  # ● ウィンドウの位置と不透明度の設定
  #--------------------------------------------------------------------------
  def reset_window
# ★==========================================================================☆
    if $game_temp.in_battle
      self.y = 32
    else
      case $game_system.message_position
      when 0  # 上
        self.y = 32
      when 1  # 中
        self.y = 160
      when 2  # 下
        self.y = 304
      end
    end
    if $game_system.message_frame == 0
      self.opacity = 255
    else
      self.opacity = 0
    end
    @name_window.y = self.y - 32
    @name_window.opacity = self.opacity
    self.back_opacity = 160
# ☆==========================================================================★
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    super
    # フェードインの場合
    if @fade_in
      self.contents_opacity += 240
# ★==========================================================================☆
      @name_window.contents_opacity += 240 if $msg_name != nil
# ☆==========================================================================★
      if @input_number_window != nil
        @input_number_window.contents_opacity += 240
      end
      if self.contents_opacity == 255
        @fade_in = false
      end
      return
    end
    # 数値入力中の場合
    if @input_number_window != nil
      @input_number_window.update
      # 決定
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se)
        $game_variables[$game_temp.num_input_variable_id] =
          @input_number_window.number
        $game_map.need_refresh = true
        # 数値入力ウィンドウを解放
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    # メッセージ表示中の場合
    if @contents_showing
      # 選択肢の表示中でなければポーズサインを表示
      if $game_temp.choice_max == 0
        self.pause = true
      end
      # キャンセル
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          terminate_message
        end
      end

      # 決定
      if Input.trigger?(Input::C)
        if @hide == true
          self.visible = true
          @name_window.visible = true
          @hide = false
        end
        if $game_temp.choice_max > 0
          $game_system.se_play($data_system.decision_se)
          $game_temp.choice_proc.call(self.index)
        end
        terminate_message
   
         
            # ウィンドウ消去
      elsif Input.trigger?(Input::Y)
        if $game_temp.choice_max > 0
          return
        end
        if @hide == false
          self.visible = false
          @name_window.visible = false
          @hide = true
        elsif @hide == true
          self.visible = true
          @name_window.visible = true
          @hide = false
        end
        return   
      # ウィンドウ消去
      elsif Input.trigger?(Input::SHIFT)
        if $game_temp.choice_max > 0
          return
        end
        if @hide == false
          self.visible = false
          @name_window.visible = false
          @hide = true
        elsif @hide == true
          self.visible = true
          @name_window.visible = true
          @hide = false
        end
        return
   
   

      # スキップ
      elsif Input.repeat?(Input::CTRL)
        # 選択肢で一時スキップストップ
        if $game_temp.choice_max > 0
          return
        end
        terminate_message   
      # スキップ
      elsif Input.repeat?(Input::A)
        # 選択肢で一時スキップストップ
        if $game_temp.choice_max > 0
          return
        end
        terminate_message   
      end
      return
    end
 

    # フェードアウト中以外で表示待ちのメッセージか選択肢がある場合
    if @fade_out == false and $game_temp.message_text != nil
      @contents_showing = true
      $game_temp.message_window_showing = true
      reset_window
      refresh
      Graphics.frame_reset
      self.visible = true
      self.contents_opacity = 0
      if @input_number_window != nil
        @input_number_window.contents_opacity = 0
      end
      @fade_in = true
      return
    end
    # 表示すべきメッセージがないが、ウィンドウが可視状態の場合
    if self.visible
      @fade_out = true
      self.opacity -= 48
# ★==========================================================================☆
      @name_window.opacity -= 48
# ☆==========================================================================★
      if self.opacity == 0
        self.visible = false
# ★==========================================================================☆
        @name_window.visible = false
# ☆==========================================================================★
        @fade_out = false
        $game_temp.message_window_showing = false
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● カーソルの矩形更新
  #--------------------------------------------------------------------------
  def update_cursor_rect
    if @index >= 0
      n = $game_temp.choice_start + @index
# ★==========================================================================☆
      self.cursor_rect.set(8 + @text_x, n * 32, @cursor_width, 32)
# ☆==========================================================================★
    else
      self.cursor_rect.empty
    end
  end
end
 
Last edited:

Strange

Demon Girl Pro
Joined
Jul 24, 2014
Messages
1,256
Reputation score
486
So, who knows what the whole clunk of code is trying to do.
Well, this one's pretty easy:
Ruby:
p "\101rgh!"
#  => "Argh!"  :(

text = "it's \\AL[5]'s fault"
text.gsub!(/\\[Aa][Ll]\[([0-9]+)\]/) { "\101[#{$1}]" }
p $1
#  => "5"
p text
#  => "it's A[5]'s fault"

p "\201"
#  => "\x81" :)
text = "it's \\AL[5]'s fault"
text.gsub!(/\\[Aa][Ll]\[([0-9]+)\]/) { "\201[#{$1}]" }
p text
#  => "it's \x81[5]'s fault"
text is a string. "\101" is somehow recognized as the "A" character (ASCII? UTF-8? I dunno, I wish I did).
Line 120 converts "it's \\AL[5]'s fault" to "it's \101[5]'s fault"
Line 170 if c=="\101" # matches an "A" now, backslash irrelevant
Line 172 subs out the next "[integer]" instance in text (messing up the next real command in text, if any)
Line 173 changes the default text alignement, processed in line 287's "case"

Worst case scenario: some "A"s will pop up in Japanese, where \AL[x] is used. Other/further commands might break.

TL,DR: Change all instances of "\101" to "\201" (lines 121 & 170) and you're good.
 
Last edited:

habisain

Tentacle God
Joined
Jul 15, 2012
Messages
1,447
Reputation score
465
text is a string. "\101" is somehow recognized as the "A" character (ASCII? UTF-8? I dunno, I wish I did).
For reference, this format of Ruby uses Octal for encoding a character. So "\101" = 65th character in character set, which for anything that has ASCII as a subset (which includes UTF-8, Shift-JIS, cp932, and I think anything else that encodes Japanese), is A. I have no idea why on Ruby chose Octal for this. Like many things in Ruby, it just seems obscure for obscurities sake.
 

Strange

Demon Girl Pro
Joined
Jul 24, 2014
Messages
1,256
Reputation score
486
For reference, this format of Ruby uses Octal for encoding a character. So "\101" = 65th character in character set, which for anything that has ASCII as a subset (which includes UTF-8, Shift-JIS, cp932, and I think anything else that encodes Japanese), is A. I have no idea why on Ruby chose Octal for this. Like many things in Ruby, it just seems obscure for obscurities sake.
Thanks a bunch, mystery solved! 101[oct] = 1*8^2 + 0*8 + 1 = 65[dec]

I couldn't find that documented anywhere and couldn't make heads or tails out of it...
 

JustLurksHere

Jungle Girl
Joined
Oct 28, 2016
Messages
558
Reputation score
45
Quite late to chime in on this, but to complete the explanation: ruby didn't choose anything here.
Ruby simply sticks close to C where it can and for reasons that are nearly prehistorical wrt. computer sciences, octal encoding was used cause the extra bits were kept for transmission checking. As such '\xxx' sequences in text strings were meant to be interpreted as octal codes. Only later on that (i.e. that way of transmission checking) had been done away with and hexadecimal became the norm.
Now, why did RPG Maker's authors used octal here instead of hexadecimal is a different question, one only they could answer.
 
Last edited:

habisain

Tentacle God
Joined
Jul 15, 2012
Messages
1,447
Reputation score
465
Quite late to chime in on this, but to complete the explanation: ruby didn't choose anything here.
Ruby simply sticks close to C where it can and for reasons that are nearly prehistorical wrt. computer sciences, octal encoding was used cause the extra bits were kept for transmission checking. As such '\xxx' sequences in text strings were meant to be interpreted as octal codes. Only later on that (i.e. that way of transmission checking) had been done away with and hexadecimal became the norm.
Now, why did RPG Maker's authors used octal here instead of hexadecimal is a different question, one only they could answer.
I'm well aware of that. However, Ruby chose to keep implement Octal escape codes when there really isn't any good reason to do so. I can name many languages which have heavy influence from C which do not support octal escapes, including a number which I would argue are much more C-like than Ruby (e.g. C#), and a good number with a similar target domain (e.g Rust). It really is just an obscure feature, and whether or not Ruby implemented it by copying it from another language or not is irrelevant. It's kind of the raison d'etre of Ruby though - it's a language that gives people almost as many ways to do a thing as is possible, and that means there are a lot of obscure ways of accomplishing something. I'm not a fan of this design, but some people do like it.

As to why Octal was used in this game (It's not used in RPGMaker itself, as far as I know): I can only speculate, but it's probably so that the author could scan the source code for instances of the character A in strings and flag those as errors, whereas the octal escape would never be accidentally used because it's way harder to typo \101 than A. That being said, I have no idea why they didn't use a character which isn't on keyboards (e.g. NUL or SOH) for this purpose, because that would have been even better. It's always fun trying to second guess why someone made weird coding decisions, isn't it?
 

JustLurksHere

Jungle Girl
Joined
Oct 28, 2016
Messages
558
Reputation score
45
including a number which I would argue are much more C-like than Ruby (e.g. C#),
If anything, C# is closer to either python or javascript, not (despite the name) C.
What's more, contrary to the (in the recent years) much too popular mayflies approach, language design is an evolutionary process - it needs to be based on some of already well-established concepts to get a decent users group outside of fanboys and topic enthusiasts. The more out of the blue new language is, the greater the chance it will only be a seasonal fad.

Pity, some of the older date people seem to forget that in their mid-life crisis.

Even though, octal codes are ancient enough history, that there aren't still many active programmers around from the time where they were a necessity.
For example, while I still (vaguely) recall days before Win95 (well, just MS DOS 6.0), even back then it was already a legacy feature.

Also, yes, bikeshedding is one of more popular sports in amateur programming community.
 
Top