@@ -155,47 +155,103 @@ def generate_build_data(balance_data_path):
155155 sorted_units = collections .OrderedDict (sorted (units .items (), key = lambda x : int (x [0 ])))
156156 sorted_abilities = collections .OrderedDict (sorted (abilities .items (), key = lambda x : int (x [0 ])))
157157
158- unit_lookup = [[ unit_name , unit_name ] for _ , unit_name in sorted_units .items ()]
158+ unit_lookup = dict (( unit_name , unit_name ) for _ , unit_name in sorted_units .items ())
159159
160160 return sorted_units , sorted_abilities , unit_lookup , ability_lookup
161161
162162
163+ def combine_lookups (old_unit_lookup , old_ability_lookup , new_unit_lookup , new_ability_lookup ):
164+ unit_lookup = collections .OrderedDict (old_unit_lookup )
165+ ability_lookup = collections .OrderedDict (old_ability_lookup )
166+
167+ # First just straightforwardly add any missing units
168+ unit_lookup .update (new_unit_lookup )
169+
170+ # Doing this step allows us to preserve any non-standard unit names in the old build data that may have been
171+ # overwritten in the new build data. This allows us to retain support for downstream clients using the existing
172+ # unit names.
173+ unit_lookup .update (old_unit_lookup )
174+
175+ # When merging old and new ability lookups, prefer to overwrite old cell data with new cell data when merging rows
176+ # in the case of a key clash, but preserve old cell data if cell is empty in new ability lookup table
177+ for ability_name , commands in new_ability_lookup .items ():
178+ if ability_name not in ability_lookup :
179+ ability_lookup [ability_name ] = commands
180+ else :
181+ for i , command in enumerate (commands ):
182+ # Pad potential gaps with empty commands
183+ while len (ability_lookup [ability_name ]) <= i :
184+ ability_lookup [ability_name ].append ("" )
185+
186+ if command != "" :
187+ ability_lookup [ability_name ][i ] = command
188+
189+ return unit_lookup , ability_lookup
190+
191+
163192def main ():
164- parser = argparse .ArgumentParser (description = 'Generate [BUILD_VERSION]_abilities.csv, [BUILD_VERSION]_units.csv,'
165- ' ability_lookup.csv and unit_lookup.csv files from exported balance'
166- ' data.' )
193+ parser = argparse .ArgumentParser (description = 'Generate and install new [BUILD_VERSION]_abilities.csv, '
194+ '[BUILD_VERSION]_units.csv, and update ability_lookup.csv and '
195+ 'unit_lookup.csv files with any new units and ability commands.' )
196+ parser .add_argument ('expansion' , metavar = 'EXPANSION' , type = str , choices = ['WoL' , 'HotS' , 'LotV' ],
197+ help = 'the expansion level of the balance data export, one of \' WoL\' , \' HotS\' , or \' LotV\' ' )
167198 parser .add_argument ('build_version' , metavar = 'BUILD_VERSION' , type = int ,
168199 help = 'the build version of the balance data export' )
169200 parser .add_argument ('balance_data_path' , metavar = 'BALANCE_DATA_PATH' , type = str ,
170201 help = 'the path to the balance data export' )
202+ parser .add_argument ('project_path' , metavar = 'SC2READER_PROJECT_PATH' , type = str ,
203+ help = 'the path to the root of the sc2reader project directory' )
171204
172205 args = parser .parse_args ()
173206
174- units , abilities , unit_lookup , ability_lookup = generate_build_data (args .balance_data_path )
207+ units , abilities , new_unit_lookup , new_ability_lookup = generate_build_data (args .balance_data_path )
175208
176209 if not units or not abilities :
177210 parser .print_help ()
178211 print ("\n " )
179212
180213 raise ValueError ("No balance data found at provided balance data path." )
181214
182- with open ('{}_units.csv' .format (args .build_version ), 'w' , newline = '' ) as csvfile :
183- csv_writer = csv .writer (csvfile , delimiter = ',' , lineterminator = os .linesep )
215+ unit_lookup_path = os .path .join (args .project_path , 'sc2reader' , 'data' , 'unit_lookup.csv' )
216+ with open (unit_lookup_path , 'r' ) as file :
217+ csv_reader = csv .reader (file , delimiter = ',' , lineterminator = os .linesep )
218+ old_unit_lookup = collections .OrderedDict ([(row [0 ], row [1 ]) for row in csv_reader if len (row ) > 1 ])
219+
220+ ability_lookup_path = os .path .join (args .project_path , 'sc2reader' , 'data' , 'ability_lookup.csv' )
221+ with open (ability_lookup_path , 'r' ) as file :
222+ csv_reader = csv .reader (file , delimiter = ',' , lineterminator = os .linesep )
223+ old_ability_lookup = collections .OrderedDict ([(row [0 ], row [1 :]) for row in csv_reader if len (row ) > 0 ])
224+
225+ if not old_unit_lookup or not old_ability_lookup :
226+ parser .print_help ()
227+ print ("\n " )
228+
229+ raise ValueError ("Could not find existing unit or ability lookups. Is the sc2reader project path correct?" )
230+
231+ unit_lookup , ability_lookup = combine_lookups (
232+ old_unit_lookup , old_ability_lookup , new_unit_lookup , new_ability_lookup )
233+
234+ units_file_path = os .path .join (
235+ args .project_path , 'sc2reader' , 'data' , args .expansion , '{}_units.csv' .format (args .build_version ))
236+ with open (units_file_path , 'w' ) as file :
237+ csv_writer = csv .writer (file , delimiter = ',' , lineterminator = os .linesep )
184238 for unit_index , unit_name in units .items ():
185239 csv_writer .writerow ([unit_index , unit_name ])
186240
187- with open ('{}_abilities.csv' .format (args .build_version ), 'w' , newline = '' ) as csvfile :
188- csv_writer = csv .writer (csvfile , delimiter = ',' , lineterminator = os .linesep )
241+ abilities_file_path = os .path .join (
242+ args .project_path , 'sc2reader' , 'data' , args .expansion , '{}_abilities.csv' .format (args .build_version ))
243+ with open (abilities_file_path , 'w' ) as file :
244+ csv_writer = csv .writer (file , delimiter = ',' , lineterminator = os .linesep )
189245 for ability_index , ability_name in abilities .items ():
190246 csv_writer .writerow ([ability_index , ability_name ])
191247
192- with open ('unit_lookup.csv' . format ( args . build_version ) , 'w' , newline = '' ) as csvfile :
193- csv_writer = csv .writer (csvfile , delimiter = ',' , lineterminator = os .linesep )
194- for lookup_entry in unit_lookup :
195- csv_writer .writerow (lookup_entry )
248+ with open (unit_lookup_path , 'w' ) as file :
249+ csv_writer = csv .writer (file , delimiter = ',' , lineterminator = os .linesep )
250+ for entry in unit_lookup . items () :
251+ csv_writer .writerow (list ( entry ) )
196252
197- with open ('ability_lookup.csv' . format ( args . build_version ) , 'w' , newline = '' ) as csvfile :
198- csv_writer = csv .writer (csvfile , delimiter = ',' , lineterminator = os .linesep )
253+ with open (ability_lookup_path , 'w' ) as file :
254+ csv_writer = csv .writer (file , delimiter = ',' , lineterminator = os .linesep )
199255 for ability_name , commands in ability_lookup .items ():
200256 csv_writer .writerow ([ability_name ] + commands )
201257
0 commit comments