Extracting the dialogue of a project

Post date: Aug 13, 2009 7:19:54 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