Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

[Resolved] I can't quite grasp this code...

In addition to the fact that it's 4 in the morning, I'm still a beginner scripter, and as such I can't quite seem to get a grasp on what a certain portion of this script is doing. It's RPG Advocate's manual EXP table override.

Code:
class Game_Actor < Game_Battler # New Methods 
# -----------------------------
def get_exp_list_from_file(filename)
    begin
      if @exp_file_error
        return
      end
      f = File.open(filename)
      list = f.readlines
      list = correct_malformed_input(list)
      if @exp_file_error
        return
      end
      for i in 0..list.size - 1
        list[i] = list[i].to_i
      end
      list = correct_erroneous_data(list)
      for i in list.size..100
        list[i] = 0
      end
      list.unshift(0)
      @exp_list = list
      rescue StandardError
        s1 = "Unrecoverable error while reading " + @name + "'s EXP list.\n"
        s2 = "Experience curve declared in the database will be used instead."
        print(s1 + s2)
        @exp_file_error = true
        retry
      ensure
        if f != nil
          f.close
        end
      end
  end
# -----------------------------
def correct_malformed_input(list)
    lines_to_delete = []
    if list.size == 0
      s1 = "Warning: " + @name + "'s experience requirement file is empty.  "
      s2 = "Experience curve declared in the database will be used instead."
      print(s1 + s2)
      @exp_file_error = true
      return
    end
    for i in 0..list.size - 1
      delflag = false
      for j in 0..list[i].size - 1
        if list[i][j] != 10 && list[i][j] != 32 && 
          !(list[i][j] >= 48 && list[i][j] <= 57)
          delflag = true
        end
      end
      if list[i].size == 1 && list[i][0] == 10
        delflag = true
      end
      if delflag
        lines_to_delete.push(list[i])
      end
    end
    if lines_to_delete != []
      for i in 0..lines_to_delete.size - 1
        list.delete(lines_to_delete[i])
      end
    end
    for i in 0..list.size - 1
      while list[i].include?(32)
        list[i].slice!(0)
      end
    end
  return list
end
# -----------------------------
def correct_erroneous_data(list)
  warnings = ""
  wrong_exp = false
  if list[0] != 0
    list[0] = 0
    s1 = "Warning: " + @name + "'s experience requirement for level 1 "
    s2 = "must be zero.  Automatically correcting error.\n"
    warnings += s1 + s2
  end
  if list.size < $data_actors[@actor_id].final_level
    if list.size >= 2
      value = list[list.size - 1] - list[list.size - 2]
      for i in list.size..$data_actors[@actor_id].final_level - 1
        list[i] = list[i-1] + value
      end
    else
      list = []
      for i in 0..$data_actors[@actor_id].final_level - 1
        list[i] = i
      end
    end
      s1 = "Warning: Fewer levels than " + @name + "'s maximum level have "
      s2 = "been declared.  Creating temporary substitute values.\n"
      warnings += s1 + s2
  end
  if list.size > $data_actors[@actor_id].final_level
      new_list = []
      for i in 0..$data_actors[@actor_id].final_level - 1
        new_list[i] = list[i]
      end
      list = new_list
      s1 = "Warning: More levels than " + @name + "'s maximum level have "
      s2 = "been declared.  Ignoring excess declarations.\n"
      warnings += s1 + s2
    end
    for i in 1..list.size - 1
      if list[i] <= list[i-1]
        if i == list.size - 1 && list.size != 2
          diff = list[i-1] - list[i-2]
          list[i] = list[i-1] + diff
        elsif i == list.size - 1 && list.size == 2
          list[i] = 10
        else
          if list[i+1] > list[i-1]
            diff = list[i+1] - list[i-1]
            list[i] = list[i-1] + diff / 2
          else
            list[i] = list[i-1] + 10
          end
       end
       wrong_exp = true
    end
  end
  if wrong_exp
    s1 = "Warning: One or more experience requirements for " + @name + " "
    s2 = "is less than or equal to the previous level's requirement.  "
    s3 = "Creating temporary substitute values."
    warnings += s1 + s2 + s3
  end
  if warnings != ""
    print(warnings)
  end
  return list
end

The method correct_malformed_input is the one that's... Interesting to me.

Code:
def correct_malformed_input(list)
    lines_to_delete = []
    if list.size == 0
      s1 = "Warning: " + @name + "'s experience requirement file is empty.  "
      s2 = "Experience curve declared in the database will be used instead."
      print(s1 + s2)
      @exp_file_error = true
      return
    end
    for i in 0..list.size - 1
      delflag = false
      for j in 0..list[i].size - 1
        if list[i][j] != 10 && list[i][j] != 32 && 
          !(list[i][j] >= 48 && list[i][j] <= 57)
          delflag = true
        end
      end
      if list[i].size == 1 && list[i][0] == 10
        delflag = true
      end
      if delflag
        lines_to_delete.push(list[i])
      end
    end
    if lines_to_delete != []
      for i in 0..lines_to_delete.size - 1
        list.delete(lines_to_delete[i])
      end
    end
    for i in 0..list.size - 1
      while list[i].include?(32)
        list[i].slice!(0)
      end
    end
  return list
end

After a couple of tests, I found out that what it does is change the "list" array to contain the value that's to the right of the level. Erm, if you haven't seen this before, it's a little better explained viewing the sample text document.

I generally understand what the rest of the code is doing (to an extent), I'm just completely lost on how exactly this method is doing its job.

So, anyone wanna help out a newbie understand RGSS a bit better? ^_^;

EDIT: AH!! I just remembered there's a sticky just for asking about existing RGSS scripts. >_<; Sorry, quite a bit tired... I'm not sure, should this post be deleted/merged with that topic, or is it fine as it is...? I guess that's what the mods are here for...
 

e

Sponsor

Code:
def correct_malformed_input(list)
    lines_to_delete = []	# An array which will be filled with the lines to delete
    # Basically, if the list is empty, which it shouldn't, we don't have anything to do.
    # Of course, that means that we don't have any experience list to replace the old one;
    # hence, set the error flag to true to remember there IS an error.
    # Then return so that we don't proceed any further.
    if list.size == 0
      s1 = "Warning: " + @name + "'s experience requirement file is empty.  "
      s2 = "Experience curve declared in the database will be used instead."
      print(s1 + s2)
      @exp_file_error = true
      return
    end
    
    # For each index within the list array
    # list.size returns the number of items in the array, starting with a 1 index.
    # Since arrays handle indices starting at 0, we need to substract 1 from the size.
    # i.e. : there are five lines items in the list.
    # list.size will return 5 (which is correct)
    # However, since we start at index 0, it will go from 0 to 4 (0 being first, 1 being the second, etc.)
    for i in 0..list.size - 1
      delflag = false	# We assume we shouldn't have to delete this line. We will if the delflag is eventually set to true, however.
      
      # We loop through the array at list[i].
      # The logic is the same as before.
      # We could, if we wanted, use a much better notation :
      # list[i].each { |item| &block }
      for j in 0..list[i].size - 1
      	# I couldn't REALLY tell you why, but basically we check for the given condition :
      	# The item at index j in the array list[i] (the array we are currently looping through)
      	# will be set to be deleted if it is not equal to 10 and 32 and if it isn't between 48 and 57 (included)
      	# It doesn't make much sense to me, considering that if it is equal to 10, it couldn't be equal to 32 or be included between 48 and 57...
      	# I believe those should be OR conditions, but that's just me!
        if list[i][j] != 10 && list[i][j] != 32 && 
          !(list[i][j] >= 48 && list[i][j] <= 57)
          delflag = true
        end
      end
      # IF there is but one item which is equal to 10, set for deletion. Why? Dunno.
      if list[i].size == 1 && list[i][0] == 10
        delflag = true
      end
      # If the flag has been set to 0, add the array to the lines to be deleted.
      if delflag
        lines_to_delete.push(list[i])
      end
    end
    # This is pretty much self-explanatory....
    if lines_to_delete != []
      for i in 0..lines_to_delete.size - 1
        list.delete(lines_to_delete[i])
      end
    end
    # Now, we re-iterate through our main list, to see if the value 32 is included somewhere.
    # So, as long as the number 32 is included within our list, we must remove the first value of our subarray
    # (the value at index 0). Go figure why.
    for i in 0..list.size - 1
      while list[i].include?(32)
        list[i].slice!(0)
      end
    end
  return list
end

Co-co-commented! Feel free to ask more. I didn't really know the inner workings of the script, so some of the conditions baffled me (why is 32 such an evil number?).
 
I added some comments to Etheon's....

Code:
def correct_malformed_input(list)
    lines_to_delete = []	# An array which will be filled with the lines to delete
    # Basically, if the list is empty, which it shouldn't, we don't have anything to do.
    # Of course, that means that we don't have any experience list to replace the old one;
    # hence, set the error flag to true to remember there IS an error.
    # Then return so that we don't proceed any further.
    if list.size == 0
      s1 = "Warning: " + @name + "'s experience requirement file is empty.  "
      s2 = "Experience curve declared in the database will be used instead."
      print(s1 + s2)
      @exp_file_error = true
      return
    end
    
    # For each index within the list array
    # list.size returns the number of items in the array, starting with a 1 index.
    # Since arrays handle indices starting at 0, we need to substract 1 from the size.
    # i.e. : there are five lines items in the list.
    # list.size will return 5 (which is correct)
    # However, since we start at index 0, it will go from 0 to 4 (0 being first, 1 being the second, etc.)
    for i in 0..list.size - 1
      delflag = false	# We assume we shouldn't have to delete this line. 
                        #We will if the delflag is eventually set to true, however.
      
      # We loop through the array at list[i].
      # The logic is the same as before.
      # We could, if we wanted, use a much better notation :
      # list[i].each { |item| &block }
      for j in 0..list[i].size - 1
      	# I couldn't REALLY tell you why, but basically we check for the given condition :
      	# The item at index j in the array list[i] (the array we are currently looping through)
      	# will be set to be deleted if it is not equal to 10 and 32 and if it isn't between 48 and 57 (included)
      	# It doesn't make much sense to me, considering that if it is equal to 10, 
        # it couldn't be equal to 32 or be included between 48 and 57...
      	# I believe those should be OR conditions, but that's just me!

        # Brew
        # This says, "if any character is NOT a newline(10), space(32), or number(48-57)  (ascii values)
        # then delete the line.  It essentially removes all of the comments.

        if list[i][j] != 10 && list[i][j] != 32 && 
          !(list[i][j] >= 48 && list[i][j] <= 57)
          delflag = true
        end
      end
      # IF there is but one item which is equal to 10, set for deletion. Why? Dunno.

      # Brew
      # Delete empty lines.  1 character in line = newline

      if list[i].size == 1 && list[i][0] == 10
        delflag = true
      end
      # If the flag has been set to 0, add the array to the lines to be deleted.

      # Brew - correction:  if flag has been set to "true"

      if delflag
        lines_to_delete.push(list[i])
      end
    end
    # This is pretty much self-explanatory....
    if lines_to_delete != []
      for i in 0..lines_to_delete.size - 1
        list.delete(lines_to_delete[i])
      end
    end
    # Now, we re-iterate through our main list, to see if the value 32 is included somewhere.
    # So, as long as the number 32 is included within our list, we must remove the first value of our subarray
    # (the value at index 0). Go figure why.

    # Brew
    # This chops the first column from each pair of values, if there is a space(32) in the line.
    # At this point, our first line should be ("1 0"). This removes the "1" (and the space)

    for i in 0..list.size - 1
      while list[i].include?(32)
        list[i].slice!(0)
      end
    end
  return list
end

Be Well
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top