Main‎ > ‎

Extracting the dialogue of a project

posted Aug 13, 2009, 12:19 PM by Zeriab NA   [ updated Aug 21, 2009, 12:02 PM ]
Here is a small script I cooked up earlier today.

It extracts all the text messages and choices of all the events in the game. One file for the map events, another for the common events and a third text file for the battle events.

It can be useful for reviewing purposes and also for simple-minded word spell-checking.
Note that since there is loss of information to the format presented you should consider it infeasible to be able to inject your modifications back into the project by automatic means.
I know there is a French project which can do this, but the text files are not as nice to read.

To use the script create a new section right above Main and run the program.
Delete the section afterwards.
You now have 3 new dialogue_xxx.txt files in the project folder.

*hugs*


 def update_sprite
  if @sprite.nil?
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(640, 120)
  end
  current = $current
  unless current == $last
    $last = current
    @sprite.bitmap.clear
    unless current.nil?
      @sprite.bitmap.draw_text(8,4,600,32,$last.map)
      @sprite.bitmap.draw_text(8,40,600,32,$last.event)
    end
  end
end

##
# A separate thread that will run and make sure the Graphics.update is updated
# every now and then.
#
Thread.new {
  loop do
    # Lets the thread sleep for a while to minimize CPU usage
    sleep 0.1
    # Update the sprite
    update_sprite
    # Update the graphics
    Graphics.update
  end
}

Current = Struct.new(:map, :event)
$current = nil

Map = Struct.new(:name, :map_id, :events)
Event = Struct.new(:name, :event_id, :pages)
Page = Struct.new(:number, :list)
ListElement = Struct.new(:message, :type)

######
######

class Map
  def write_to_stream(io)
    io.print "\r\n########################################"
    io.print "\r\n# Map #{map_id} ~ #{name}  (#{events.size} events)\r\n"
    io.print "########################################\r\n"
    for event in events
      event.write_to_stream(io)
   
end
  end
end

class Event
 
def write_to_stream(io)
    io.print "\r\n-= Event #{event_id} - #{name} =-\r\n"
   
for page in pages
      page.write_to_stream(io)
    end
  end
end

class Page
 
def write_to_stream(io)
    io.print "Page #{number}:\r\n"
   
for element in list
      element.write_to_stream(io)
      io.print "\r\n"
    end
  end
end

class ListElement
 
def write_to_stream(io)
    io.print message
  end
end

######
def process_list(list)
  # Go through the event commands in the list
  rlist = [] # resulting list
  command_index = 0
  while command_index < list.size
    command = list[command_index]
    if command.code == 101
      message = command.parameters[0].rstrip
      loop do
        break unless command_index + 1 < list.size
       
if list[command_index+1].code == 401
          command_index += 1
          message += " " + list[command_index].parameters[0].rstrip
        elsif list[command_index+1].code == 102
          command_index += 1
          for text in list[command_index].parameters[0]
            message += "\r\n" + text.rstrip
         
end
        else
          break
       
end
      end
      rlist << ListElement.new(message, 'text')
    elsif command.code == 102
      message = ""
     
for text in list[command_index].parameters[0]
        message += "\r\n" + text.rstrip
     
end
      rlist << ListElement.new(message, 'choice')
   
end
    command_index += 1
 
end
  return rlist
end
######

class CommonEvent < Struct.new(:name, :event_id, :list)
 
def write_to_stream(io)
    io.print "\r\n-= Common Event #{event_id} - #{name} =-\r\n"
   
for element in list
      element.write_to_stream(io)
      io.print "\r\n"
   
end
  end
end

common_events = load_data('Data/CommonEvents.rxdata')
ces = []
for ce in common_events.compact
  # Look at which event is currently processing
  cur = Current.new("Processing common events...",
                    "Common event #{ce.id} - #{ce.name}")
  $current = cur
  # Process the list
  list = process_list(ce.list)
  unless list.empty?
    # Create struct
    current_ce = CommonEvent.new(ce.name, ce.id, list)
    ces << current_ce
 
end
end

######
######

class Troop < Event
 
def write_to_stream(io)
    io.print "\r\n-= Troop #{event_id} - #{name} =-\r\n"
   
for page in pages
      page.write_to_stream(io)
   
end
  end
end

troops = load_data('Data\Troops.rxdata')

battle_events = []
for event in troops.compact
  # Look at which event is currently processing
  cur = Current.new("Processing battle events...",
                    "Troop " + event.id.to_s + " - " + event.name)
  $current = cur
  # Create the event struct
  current_event = Troop.new(event.name, event.id, [])
  # Create pages
  event.pages.each_with_index do |page, page_index|
    list = process_list(page.list)
    unless list.empty?
      current_page = Page.new(page_index+1, list)
      current_event.pages << current_page
   
end
  end
  # Let's disregard useless events
  battle_events << current_event unless current_event.pages.empty?
end

######
######

infos = load_data('Data\MapInfos.rxdata')

maps = []
for map_id, map_info in infos.sort
  # Create map struct
  current_map = Map.new(map_info.name, map_id, [])
  maps << current_map
  map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
  # Create event structs
 
for event_id, event in map.events.sort
    # Look at which event is currently processing
    cur = Current.new("Map " + map_id.to_s + " - " + map_info.name,
                      "Event " + event_id.to_s + " - " + event.name)
    $current = cur
    # Create the event struct
    current_event = Event.new(event.name, event_id, [])
    # Create pages
    event.pages.each_with_index do |page, page_index|
      list = process_list(page.list)
      unless list.empty?
        current_page = Page.new(page_index+1, list)
        # Let's disregard useless pages
        current_event.pages << current_page
     
end
    end
    # Let's disregard useless events
    current_map.events << current_event unless current_event.pages.empty?
 
end
end

# Update status info
cur = Current.new("All maps have been processed",
                  "Writing to a text file")
$current = cur

File.open('Dialogue_Map.txt', 'wb') {|f|
  f.print "THIS FILE CONTAINS THE DIALOGUE EXTRACTED FROM THE MAPS\r\n\r\n"
  for map in maps
    map.write_to_stream(f)
  end
}

File.open('Dialogue_Common.txt', 'wb') {|f|
  f.print "THIS FILE CONTAINS THE DIALOGUE EXTRACTED FROM THE COMMON EVENTS\r\n\r\n"
  for ce in ces
    ce.write_to_stream(f)
  end
}

File.open('Dialogue_Battle.txt', 'wb') {|f|
  f.print "THIS FILE CONTAINS THE DIALOGUE EXTRACTED FROM THE BATTLE EVENTS\r\n\r\n"
  for be
in battle_events
    be.write_to_stream(f)
  end
}
exit


I have done the syntax high lightning in hand, so don't trust it too much.
I will not do it again since it's horrible.

Edit: A big thanks to Trebor777 for the idea of using blocks instead of f = and f.close
Comments