Jump to content
Sign in to follow this  
Euphoria

Using Notetags

Recommended Posts

So I know that I've seen many scripts put the Regex in a module first like so:

module Euphoria
  module Regex
  
    REGEX  = /<KillItem = (\w+)>/i  #Example from one of my scripts.

    REGEX2 = /<KillItem = (\w+)>/i  #Example 2 (pretend it's different...)

    REGEX3 = /<KillItem = (\w+)>/i  #And so on...

  end
end


Then I see them call the notetags like this:

module DataManager
  self << class; end                  #Why put end here?

  alias alias_database     load_database
  def self.load_database
    alias_database
    load_notetags
  end

  def self.load_notetags
    groups = [$data_skills, $data_items, $data_states]
      for group in groups               #
        for obj in group                #Can someone explain these three lines a bit?
          next if obj.nil?              #
        obj.load_notetags               #Same method as above? Why?
      end
    end
  end
end


I don't exactly understand all of that part, and I absolutely have no idea what follows this...

Can someone explain what to do next, and what it all means? (My questions are listed as comments in the code box above)

Is there alternate ways of loading notetags? The tutorials I followed never went into loading notetags outside of the module (using something like "item.note.scan(Regex Here)" )

 

P.S. Sorry if there are any mistakes, this was mostly off the top of my head.

Edited by Euphoria

Share this post


Link to post
Share on other sites

Breaking it down line by line:

groups = [$data_skills, $data_items, $data_states]
for group in groups               
  for obj in group                
    next if obj.nil?              
    obj.load_notetags             
  end
end

1. Store the skills, items and states from the database in an Array

 

2. Iterate through that array, calling the current collection a "group" (first all skills, then all items then all states)

 

3. Iterate through each object in the current group. So when iterating through $data_items, obj is the current item. When iterating through skills, obj is the current skill, etc.

 

4. Most things in the database are 1-indexed, while Ruby collections are always 0-indexed. This means that the first item in each database collection (i.e. $data_items[0]) is usually nil. This line skips processing those to avoid errors.

 

5. Call the load_notetag function of the current object (current item, skill or state). I imagine the engine that's in has defined a load_notetag function for RPG::BaseItem, RPG::Skill and RPG::State. It's not calling the same function (DataManager::load_notetags), it's calling a function that has the same name in a different object (i.e. RPG::BaseItem.load_notetags).

 

All that said, this code isn't actually doing any parsing, it's whatever gets called by the

obj.load_notetags

method that's parsing things.

 

You can parse notetags in anyway you want. How you parse it is part due to preference and part due to how you decide to format the information inside your notetags.

 

For items, for example, item.note returns a string containing whatever is in the note. So you use Ruby's regex functions to find the regex inside that string and store it somewhere. Here's a simple example I use for parsing enemy data in my combat engine:

RX_ENEMY_TYPE   = /<monster_type:\s*(.+)>/i
 
def note_get_monster_type   
  m_data = RX_ENEMY_TYPE.match(@enemy.note)
  if m_data.nil? || m_data[1].nil?
    @monster_type = "(NOT SET)"
  else
    @monster_type =  m_data[1]
  end
end

It's set to match a notetag that looks like this:

<monster_type: Hobgoblin Regular>

inside my enemy notes.

The Regexp.match method returns nil when nothing is found, or a MatchData structure when it is. MatchData[0] returns the entire matched string ("<monster_type: Hobgoblin Regular>"). MatchData[1] returns the equivalent of $1, which is the string matched by the bit in parenthesis inside the regex ("Hobgoblin Regular", in this case).

A more complicated example:

RX_ENEMY_STATS  = /<stat_data>[\r\n]*/i

def note_get_base_stats
  
  @enemy.note.split(RX_ENEMY_STATS).each do |block|
    next if block.empty?             # Skip the start of the note block (the <stat_data> line)
    
    block.split('*').each do |line|  # Split each part of the block starting with '*' into a line
      symbol = line.match(/:[\S]+/)  # Find the first symbol in the line (i.e. ":str")
      next unless symbol             # Skip this line if there aren't any symbols on it
      symbol = symbol[0]             # Grab the symbol from MatchData[0]
      line.sub!(/:[\S]+[\s]+/, "")   # Remove the matched symbol from the line
      line.chop!                     # Chop the newline character out from the end of the line
      cmd = "@stats.set(#{symbol}, #{line})" # Call a function that sets the stats using
      eval(cmd)                              # the loaded symbols. i.e:
                                             # @stats.set(:str, :base, 13)
                                             # Repeat for each stat
    end
  end

end

Which runs on a tag with (for example):

<stat_data>
* :str   :base, 13
* :dex :base, 10
* :con  :base, 16
* :int   :base, 10
* :wis  :base, 15
* :cha :base, 12
* :ac :base, 1
* :hp :base, 29
* :mhp :base, 29
* :fort :base, 3
* :reflex :base, 1
* :will :base, 3
* :bab :base, 2
<stat_data>

Hope that clarifies things a bit.

Edited by Kaelan
  • Like 2

Share this post


Link to post
Share on other sites

I'll have to go through it again just to help me memorize it but it was really well explained. Thanks a ton :)

Share this post


Link to post
Share on other sites

Oh, right, I almost forgot. If you want to practice formatting regular expressions or forget what all the symbols mean, you can use this website: http://www.rubular.com/. It lets you quickly test whether a regex matches a string and has a quick reference of all the accepted characters in one page.

 

I use it a lot when messing with regex stuff, it's faster than trying to test it in RPG maker and having to run your game every time just to check if your regex is correct. You can also use http://codepad.org/ to run small bits of Ruby code and check quickly whether it's doing the right thing or not.

Share this post


Link to post
Share on other sites

Thanks I've been using rubular, but codepad should be very useful!

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
Top ArrowTop Arrow Highlighted