diff --git a/tools/script/Dialogue.py b/tools/script/Dialogue.py new file mode 100644 index 000000000..07104c6f0 --- /dev/null +++ b/tools/script/Dialogue.py @@ -0,0 +1,116 @@ +#!/usr/bin/python +import sys +import string + +def _xml_line(line, firstline): + if len(line) == 0 and firstline: return '' + return ' '+line.strip()+' \n' + +def _xml_join(a, tag, b): + if tag is None: + return a.strip() + ' '+ b.lstrip() + result=a.strip() + if a != '' and a[-1] in string.whitespace: + result += " " + result += ' ' + if b != '' and b[0] in string.whitespace: + result += " " + result += b.lstrip() + return result + +class Speech: + def __init__(self, id=None, audio=None): + self.id = id + self.audio = audio + self.lines = [] + def add_line (self, line): + if len(line) != 0 and line[-1] == '\n': line = line[:-1] + self.lines.append(line) + def clean (self): + while self.lines != []: + if self.lines[-1].strip() != "": break + self.lines.pop() + def join (self, tag, other): + if self.lines == []: + self.lines = [''] + if other is None: + self.lines[-1] = _xml_join(self.lines[-1], tag, '') + return + if other.lines == []: + other.lines = [''] + self.lines[-1] = _xml_join(self.lines[-1], tag, other.lines[0]) + self.lines.extend(other.lines[1:]) + +class Speeches: + def __init__(self, datafile): + current = None + speeches = [] + self.speechdict = {} + for line in datafile: + if line[0] == '#': + lparen = line.index('(') + rparen = line.rindex(')') + if (lparen > rparen): raise ValueError + id = line[(lparen+1):rparen] + if (lparen != 1): + print "Warning: Speech "+id+" in "+filename+" isn't flush left" + audio = line[rparen+1:].strip() + if audio == "": audio = None + current = Speech(id, audio) + speeches.append(current) + else: + current.add_line(line) + for speech in speeches: speech.clean() + self.speecharray = speeches + self.__rehash() + def as_xml(self): + result = '\n' + result += '\n\n' + result += '\n' + + for speech in self.speecharray: + result += ' \n' + if speech.audio is not None: + result += ' \n' + for line, i in zip(speech.lines, xrange(sys.maxint)): + result += _xml_line(line, i==0) + result += ' \n' + + result += '\n' + return result + def __rehash(self): + self.speechdict = {} + for speech, i in zip(self.speecharray, xrange(sys.maxint)): + self.speechdict[speech.id]=i + def deletespeech(self, id): + i = self.speechdict[id] + del self.speecharray[i] + self.__rehash() + def renamespeech(self, oldid, newid): + i = self.speechdict[oldid] + del self.speechdict[oldid] + self.speechdict[newid]=i + self.speecharray[i].id=newid + def joinspeech(self, srcid, tag, nextid): + src = self.speecharray[self.speechdict[srcid]] + if nextid is not None: + next = self.speecharray[self.speechdict[nextid]] + else: + next = None + src.join(tag, next) + def addtospeech(self, id, str): + src = self.speecharray[self.speechdict[id]] + if src.lines == []: + src.lines = [str] + else: + src.lines[-1] = _xml_join(src.lines[-1], None, str) + def pretag(self, id, tag): + src = self.speecharray[self.speechdict[id]] + if src.lines == []: + src.lines = [''] + src.lines[0] = _xml_join('', tag, src.lines[0]) + + +if __name__ == '__main__': + print "This is the core library for the Ur-Quan Masters dialogue translators." + print "You don't need to run it directly." diff --git a/tools/script/config.txt b/tools/script/config.txt new file mode 100644 index 000000000..8264b39b8 --- /dev/null +++ b/tools/script/config.txt @@ -0,0 +1,118 @@ +fuse chmmr: i_am_captain=i_am_captain0 captain i_am_captain1 ship i_am_captain2 +fuse comandr: name_4 = name_40 captain name_41 +fuse comandr: we_are_vindicator=we_are_vindicator0 captain we_are_vindicator1 ship we_are_vindicator2 +fuse comandr: no_but_well_help=no_but_well_help0 ship no_but_well_help1 +fuse melnorm: we_are_from_alliance=we_are_from_alliance0 alliance +addstr melnorm: we_are_from_alliance ! +fuse orz: we_are_vindicator=we_are_vindicator0 captain we_are_vindicator1 ship we_are_vindicator2 +fuse pkunk: conquer_because_1=conquer_because_1 alliance +addstr pkunk: conquer_because_1 ! +fuse pkunk: we_are_vindicator=we_are_vindicator0 captain we_are_vindicator1 ship we_are_vindicator2 +fuse shofixt: i_am_captain=i_am_captain0 captain i_am_captain1 alliance i_am_captain2 ship i_am_captain3 +fuse shofixt: look=look0 shofixti_name look1 +fuse shofixt: report=report0 shofixti_name report1 +fuse shofixt: why_here=why_here0 shofixti_name why_here1 +fuse shofixt: bye=bye0 shofixti_name bye1 +fuse slyhome: we_are_us=we_are_us0 captain we_are_us1 ship we_are_us2 +fuse spahome: we_are_vindicator=we_are_vindicator0 captain we_are_vindicator1 ship we_are_vindicator2 +fuse starbas: tell_me_about_modules=tell_me_about_modules0 ship tell_me_about_modules1 +fuse starbas: tell_me_about_fuel=tell_me_about_fuel0 ship tell_me_about_fuel1 +fuse supox: i_am=i_am0 captain i_am1 +fuse supox: my_ship=my_ship0 ship my_ship1 +fuse supox: from_alliance=from_alliance0 alliance from_alliance1 +fuse syreen: we_are_vindicator=we_are_vindicator0 captain we_are_vindicator1 ship we_are_vindicator2 +fuse talkpet: we_are_vindicator=we_are_vindicator0 ship we_are_vindicator1 +fuse thradd: alliance_name=alliance_name alliance +fuse umgah: we_vindicator=we_vindicator0 captain we_vindicator1 ship we_vindicator2 +fuse utwig: we_are_vindicator=we_are_vindicator0 captain we_are_vindicator1 alliance we_are_vindicator2 +fuse yehat: i_demand_you_ally_homeworld=i_demand_you_ally_homeworld0 captain i_demand_you_ally_homeworld1 alliance i_demand_you_ally_homeworld2 ship i_demand_you_ally_homeworld3 +fuse yehat: i_demand_you_ally_space=i_demand_you_ally_space0 captain i_demand_you_ally_space1 ship i_demand_you_ally_space2 alliance i_demand_you_ally_space3 +fuse zoqfot: we_are_vindicator=we_are_vindicator0 alliance_possessive we_are_vindicator1 ship we_are_vindicator2 + +fuse comandr: OK_THE_NAME_IS_EMPIRE=OK_THE_NAME_IS_EMPIRE0 captain OK_THE_NAME_IS_EMPIRE1 +fuse druuge: FUEL=FUEL0 earned_units FUEL1 +fuse melnorm: SOLD_LIFE_DATA=SOLD_LIFE_DATA1 sell_count SOLD_LIFE_DATA2 earned_units SOLD_LIFE_DATA3 +fuse melnorm: SOLD_RAINBOW_LOCATIONS=SOLD_RAINBOW_LOCATIONS1 sell_count SOLD_RAINBOW_LOCATIONS2 earned_units SOLD_RAINBOW_LOCATIONS3 +fuse melnorm: CREDIT_IS=CREDIT_IS0 credits CREDIT_IS1 +fuse melnorm: NEED_MORE_CREDIT=NEED_MORE_CREDIT0 more_credits NEED_MORE_CREDIT1 +fuse pkunk: NOT_CONQUER_1=NOT_CONQUER_10 alliance NOT_CONQUER_11 alliance NOT_CONQUER_12 +fuse shofixt: GOODBYE=GOODBYE0 captain GOODBYE1 +fuse shofixt: FRIENDLY_HELLO=FRIENDLY_HELLO0 captain FRIENDLY_HELLO1 ship FRIENDLY_HELLO2 +fuse shofixt: NOTHING_NEW=NOTHING_NEW0 captain NOTHING_NEW1 +fuse spahome: JUST_MISUNDERSTANDING=JUST_MISUNDERSTANDING0 captain JUST_MISUNDERSTANDING1 +fuse starbas: NORMAL_HELLO_A=NORMAL_HELLO_A0 captain NORMAL_HELLO_A1 +fuse starbas: NORMAL_HELLO_B=NORMAL_HELLO_B0 captain NORMAL_HELLO_B1 +fuse starbas: NORMAL_HELLO_C=NORMAL_HELLO_C0 captain NORMAL_HELLO_C1 +fuse starbas: NORMAL_HELLO_D=NORMAL_HELLO_D0 captain NORMAL_HELLO_D1 +fuse starbas: NORMAL_HELLO_E=NORMAL_HELLO_E0 captain NORMAL_HELLO_E1 +fuse starbas: NORMAL_HELLO_F=NORMAL_HELLO_F0 captain NORMAL_HELLO_F1 +fuse starbas: NORMAL_HELLO_G=NORMAL_HELLO_G0 captain NORMAL_HELLO_G1 +fuse starbas: NORMAL_HELLO_H=NORMAL_HELLO_H0 captain NORMAL_HELLO_H1 +fuse starbas: NORMAL_GOODBYE_A=NORMAL_GOODBYE_A0 captain NORMAL_GOODBYE_A1 +fuse starbas: NORMAL_GOODBYE_B=NORMAL_GOODBYE_B0 captain NORMAL_GOODBYE_B1 +fuse starbas: NORMAL_GOODBYE_C=NORMAL_GOODBYE_C0 captain NORMAL_GOODBYE_C1 +fuse starbas: NORMAL_GOODBYE_D=NORMAL_GOODBYE_D0 captain NORMAL_GOODBYE_D1 +fuse starbas: NORMAL_GOODBYE_E=NORMAL_GOODBYE_E0 captain NORMAL_GOODBYE_E1 +fuse starbas: NORMAL_GOODBYE_F=NORMAL_GOODBYE_F0 captain NORMAL_GOODBYE_F1 +fuse starbas: NORMAL_GOODBYE_G=NORMAL_GOODBYE_G0 captain NORMAL_GOODBYE_G1 +fuse starbas: NORMAL_GOODBYE_H=NORMAL_GOODBYE_H0 captain NORMAL_GOODBYE_H1 +fuse starbas: LIGHT_LOAD_A=LIGHT_LOAD_A0 captain LIGHT_LOAD_A1 +fuse starbas: LIGHT_LOAD_B=LIGHT_LOAD_B0 captain LIGHT_LOAD_B1 +fuse starbas: LIGHT_LOAD_C=LIGHT_LOAD_C0 captain LIGHT_LOAD_C1 +fuse starbas: LIGHT_LOAD_D=LIGHT_LOAD_D0 captain LIGHT_LOAD_D1 +fuse starbas: LIGHT_LOAD_E=LIGHT_LOAD_E0 captain LIGHT_LOAD_E1 +fuse starbas: LIGHT_LOAD_F=LIGHT_LOAD_F0 captain LIGHT_LOAD_F1 +fuse starbas: LIGHT_LOAD_G=LIGHT_LOAD_G0 captain LIGHT_LOAD_G1 +fuse starbas: MEDIUM_LOAD_A=MEDIUM_LOAD_A0 captain MEDIUM_LOAD_A1 +fuse starbas: MEDIUM_LOAD_B=MEDIUM_LOAD_B0 captain MEDIUM_LOAD_B1 +fuse starbas: MEDIUM_LOAD_C=MEDIUM_LOAD_C0 captain MEDIUM_LOAD_C1 +fuse starbas: MEDIUM_LOAD_D=MEDIUM_LOAD_D0 captain MEDIUM_LOAD_D1 +fuse starbas: MEDIUM_LOAD_E=MEDIUM_LOAD_E0 captain MEDIUM_LOAD_E1 +fuse starbas: MEDIUM_LOAD_F=MEDIUM_LOAD_F0 captain MEDIUM_LOAD_F1 +fuse starbas: MEDIUM_LOAD_G=MEDIUM_LOAD_G0 captain MEDIUM_LOAD_G1 +fuse starbas: HEAVY_LOAD_A=HEAVY_LOAD_A0 captain HEAVY_LOAD_A1 +fuse starbas: HEAVY_LOAD_B=HEAVY_LOAD_B0 captain HEAVY_LOAD_B1 +fuse starbas: HEAVY_LOAD_C=HEAVY_LOAD_C0 captain HEAVY_LOAD_C1 +fuse starbas: HEAVY_LOAD_D=HEAVY_LOAD_D0 captain HEAVY_LOAD_D1 +fuse starbas: HEAVY_LOAD_E=HEAVY_LOAD_E0 captain HEAVY_LOAD_E1 +fuse starbas: HEAVY_LOAD_F=HEAVY_LOAD_F0 captain HEAVY_LOAD_F1 +fuse starbas: HEAVY_LOAD_G=HEAVY_LOAD_G0 captain HEAVY_LOAD_G1 +fuse starbas: STARBASE_IS_READY=STARBASE_IS_READY_A ship STARBASE_IS_READY_B ship STARBASE_IS_READY_C +fuse starbas: ABOUT_CREW=ABOUT_CREW0 ship ABOUT_CREW1 +fuse syreen: WELCOME_VINDICATOR=WELCOME_VINDICATOR0 captain WELCOME_VINDICATOR1 ship WELCOME_VINDICATOR2 +fuse syreen: MORE_COMFORTABLE=MORE_COMFORTABLE0 captain MORE_COMFORTABLE1 +fuse syreen: THIS_HAPPENS=THIS_HAPPENS0 captain THIS_HAPPENS1 +fuse thradd: WELCOME_SPACE=WELCOME_SPACE0 culture_20 WELCOME_SPACE1 +fuse thradd: WELCOME_HOMEWORLD=WELCOME_HOMEWORLD0 culture_20 WELCOME_HOMEWORLD1 +fuse thradd: SLAVE_EMPIRE=SLAVE_EMPIRE captain + +pretag melnorm: LANDERS landers +pretag melnorm: THRUSTERS thrusters +pretag melnorm: JETS jets +pretag melnorm: PODS pods +pretag melnorm: BAYS bays +pretag melnorm: DYNAMOS dynamos +pretag melnorm: FURNACES furnaces +pretag melnorm: GUNS guns +pretag melnorm: BLASTERS blasters +pretag melnorm: CANNONS cannons +pretag melnorm: TRACKERS trackers +pretag melnorm: DEFENSES defenses + +add starbas: NORMAL_HELLO_A NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_B NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_C NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_D NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_E NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_F NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_G NORMAL_HELLO_TAIL +add starbas: NORMAL_HELLO_H NORMAL_HELLO_TAIL +add thradd: OK_SLAVE SLAVE_EMPIRE +add thradd: the_slave_empire SLAVE_EMPIRE + +delete melnorm: name_1 name_2 name_3 name_40 name_41 +delete pkunk: name_1 name_2 name_3 name_40 name_41 +delete shofixt: name_1 name_2 name_3 name_40 name_41 +delete starbas: NORMAL_HELLO_TAIL +delete supox: name_1 name_2 name_3 name_40 name_41 +delete thradd: name_1 name_2 name_3 name_40 name_41 diff --git a/tools/script/dialogue.tar.gz b/tools/script/dialogue.tar.gz new file mode 100644 index 000000000..d72dc4a25 Binary files /dev/null and b/tools/script/dialogue.tar.gz differ diff --git a/tools/script/scriptcheck.py b/tools/script/scriptcheck.py index 57588f3d1..78a9d4d26 100755 --- a/tools/script/scriptcheck.py +++ b/tools/script/scriptcheck.py @@ -1,4 +1,4 @@ -#!/usr/local/bin/python2.2 +#!/usr/bin/python import string import os.path @@ -98,8 +98,8 @@ def read_source_header(filename): races = ['arilou', 'blackur', 'chmmr', 'comandr', 'druuge', 'ilwrath', 'melnorm', 'mycon', 'orz', 'pkunk', 'rebel', 'shofixt', 'slyhome', 'slyland', 'spahome', 'spathi', - 'starbas', 'supox', 'syreen', 'talkpet', 'utwig', - 'vux', 'yehat', 'zoqfot'] + 'starbas', 'supox', 'syreen', 'talkpet', 'thradd', + 'umgah', 'urquan', 'utwig', 'vux', 'yehat', 'zoqfot'] root = os.path.join('..','..','sc2') diff --git a/tools/script/xmlize.py b/tools/script/xmlize.py new file mode 100755 index 000000000..27cf6bf74 --- /dev/null +++ b/tools/script/xmlize.py @@ -0,0 +1,129 @@ +#!/usr/bin/python + +import sys +import os.path +import Dialogue + +races = ['arilou', 'blackur', 'chmmr', 'comandr', 'druuge', + 'ilwrath', 'melnorm', 'mycon', 'orz', 'pkunk', 'rebel', + 'shofixt', 'slyhome', 'slyland', 'spahome', 'spathi', + 'starbas', 'supox', 'syreen', 'talkpet', 'thradd', 'utwig', + 'umgah', 'urquan', 'vux', 'yehat', 'zoqfot'] + +root = os.path.join('..','..','sc2') + +race_speeches = {} + +def load_txt(): + print "Loading .txt files...", + for race in races: + try: + filename = os.path.join(root,'content','comm',race,race+'.txt') + speeches = Dialogue.Speeches(file(filename)) + race_speeches[race] = speeches + print race, + except ValueError: + print "["+race+" didn't parse]", + except IOError: + print "["+race+" didn't load]", + sys.stdout.flush() + print "" + +def do_commands(): + def do_delete(speeches, argstr): + args = argstr.split() + # Check all args before deleting any of them + for arg in args: + temp = speeches.speechdict[arg] + for arg in args: + speeches.deletespeech(arg) + def do_fuse(speeches, argstr): + i = argstr.index('=') + left = argstr[:i].split() + right = argstr[i+1:].split() + if len(left) != 1: raise ValueError + if len(right) == 0: raise ValueError + new_id = left[0] + old_id = right[0] + speeches.renamespeech(old_id, new_id) + # Split out tags from items. + is_tag = 1 + tags = [] + speechIDs = [] + for arg in right[1:]: + if is_tag: + tags.append(arg) + is_tag = 0 + else: + speechIDs.append(arg) + is_tag = 1 + # Now do the actual join + for tag, speech in map(None, tags, speechIDs): + speeches.joinspeech(new_id, tag, speech) + for speech in speechIDs: + speeches.deletespeech(speech) + def do_add(speeches, argstr): + args = argstr.split() + if len(args) == 0: raise ValueError + for arg in args[1:]: + speeches.joinspeech(args[0], None, arg) + def do_addstr(speeches, argstr): + args = argstr.split() + if len(args) == 0: raise ValueError + id = args[0] + str = " ".join(args[1:]) + speeches.addtospeech(id, str) + def do_pretag(speeches, argstr): + args = argstr.split() + if len(args) != 2: raise ValueError + id = args[0] + tag = args[1] + speeches.pretag(id, tag) + directives = {'delete':do_delete, 'fuse':do_fuse, + 'add':do_add, 'addstr':do_addstr, + 'pretag':do_pretag} + print "Processing command file..." + try: + cmdfile = file(sys.argv[1]) + for cmd in cmdfile: + try: + i = cmd.index(':') + left = cmd[:i].split() + right = cmd[i+1:] + if len(left) != 2: raise ValueError + directive = directives[left[0].lower()] + race = race_speeches[left[1]] + directive(race, right) + except ValueError: + if cmd.strip() != "": + print "Malformed command '%s'" % cmd.strip() + except KeyError: + print "Bad ID in '%s'" % cmd.strip() + cmdfile.close() + except IndexError: + print "Well, we would have if it were specified." + except IOError: + print "Well, we would have had the file specified actually existed." + +def write_XML(): + print "Writing XML...", + for race in races: + try: + speeches = race_speeches[race] + outfilename = os.path.join('.', race+'.xml'); + race_xml = speeches.as_xml() + xmlfile = file(outfilename, 'wt') + xmlfile.write(race_xml) + xmlfile.close() + print race, + except KeyError: + print "["+race+" didn't load or process]", + except IOError: + print "["+race+" couldn't write]", + sys.stdout.flush() + print "" + +if __name__ == "__main__": + load_txt() + do_commands() + write_XML()