# PURPOSE: This script provides a quick way to generate the enums of selected material names to allow # script access through MATERIAL_ENUMS.SCH. # NOTES: The name string returned by the material manager in code consists of the name as given in # materials.dat postfixed with an integer giving the index of that material in the list, e.g. # "metal_solid_medium_41". # Author: Richard Archibald # Started: 7/3/11 #---------------------------------------------------------------------------- # Includes #---------------------------------------------------------------------------- require 'pipeline/gui/exception_dialog' require 'pipeline/gui/messagebox' require 'pipeline/gui/application' require 'pipeline/util/rage' include Pipeline #------------------------------------------------------------------------------ # Constants #------------------------------------------------------------------------------ FRIENDLY_NAMES= # Equivalent names for the materials - these will be the names of the enums. { 'GOLF_FAIRWAY' => 'grass', 'GOLF_ROUGH' => 'grass_long', 'GOLF_ROUGH2' => 'grass_broken', 'GOLF_BUNKER' => 'sand_loose', 'GOLF_GREEN' => 'grass_short', 'GOLF_FLAG_POLE' => 'plastic_hollow', 'GOLF_WATER_HAZARD' => 'water', 'GOLF_HARD_VEG1' => 'woodchips', 'GOLF_HARD_VEG2' => 'wood_solid_medium', 'GOLF_HARD_VEG3' => 'bushes', 'GOLF_HARD_VEG4' => 'tree_bark', 'GOLF_SOFT_VEG'=> 'leaves', 'GOLF_PATH1' => 'concrete', 'GOLF_PATH2' => 'tarmac', 'GOLF_MISC' => 'plastic', 'GOLF_CART_PATH' => 'gravel_small', 'GOLF_FENCE_1' => 'metal_solid_small', 'GOLF_FENCE_2' => 'metal_chainlink_small', 'GOLF_ROCKS' => 'rock', 'GOLF_DIRT_TRACK' => 'dirt_track', 'TENNIS_TURF' => 'paving_slab', 'TENNIS_TURF_2' => 'rubber', 'TENNIS_TURF_3' => 'sandstone_solid', 'TENNIS_TURF_4' => 'carpet_solid', 'TENNIS_TURF_5' => 'clay_hard', 'TENNIS_NET' => 'cloth', 'TENNIS_FENCE' => 'metal_chainlink_small', 'TENNIS_FENCE_2' => 'prop_fnclink_03a', 'TENNIS_FENCE_3' => 'prop_fnclink_03b', 'TENNIS_FENCE_4' => 'prop_fnclink_03c', 'TENNIS_FENCE_5' => 'prop_fnclink_03d', 'TENNIS_FENCE_6' => 'metal_chainlink_large', 'TENNIS_INNER_WALLS' => 'tarpaulin', 'TENNIS_BLEACHERS_SEATS' => 'plastic_high_density', 'TENNIS_BLEACHERS_SEATS_2' => 'metal_hollow_medium', 'TENNIS_BLEACHERS_FLOOR' => 'metal_solid_medium', 'GENERAL_SNOW_LOOSE' => 'snow_loose', 'GENERAL_SNOW_COMPACT' => 'snow_compact', 'GENERAL_SNOW_DEEP' => 'snow_deep', 'GENERAL_SNOW_TARMAC' => 'snow_tarmac', 'TRAIN_TRACKS_RAILS' => 'metal_solid_small', 'TRAIN_TRACKS_GRAVEL' => 'gravel_train_track', 'TRAIN_TRACKS_GRAVEL_2' => 'gravel_large', } #------------------------------------------------------------------------------ # Subroutines #------------------------------------------------------------------------------ def ConvertU32ToS32(u32) # We assume that the number passed in is a 32-bit int. Let's do some checks. if u32 >= 2**32 Pipeline::GUI::MessageBox::warning("#{g_AppName}", "Number too big to be u32: #{u32}") Kernel::exit end s32 = u32 s32 = -((u32 ^ ((1<<32) -1) ) + 1) if u32 >= 2**31 return s32 end #------------------------------------------------------------------------------ # Main #------------------------------------------------------------------------------ if(__FILE__ == $0) then begin g_AppName = File::basename(__FILE__,'.rb') # Some local variable declarations. proj_root=OS::Path.normalise(ENV['RS_PROJROOT']) materials_dat = proj_root + "/build/dev/common/data/materials/materials.dat" strings_to_hash = [] # Read "materials.dat" into a hash table with the indices as the key values. material_dict = Hash.new() File.open(materials_dat, 'r') do |file| mat_idx = 0 file.each_line do |line| mat_name = line.split[0] # Ignore comment lines and any line which starts with a number (i.e. the magic version number). unless mat_name.nil? or mat_name.match('^#') or mat_name.match('^[0-9]') material_dict[mat_name.downcase] = mat_idx mat_idx += 1 end # Nil test. end # Iteration over each line in "materials.dat". end # Closes "materials.dat". # Display the strings for debugging. puts "--------------------------------------------" FRIENDLY_NAMES.each_key do |friendly_name| printf("%s \t--> %s%s\n", friendly_name, FRIENDLY_NAMES[friendly_name], "_#{material_dict[FRIENDLY_NAMES[friendly_name]]}") end puts "--------------------------------------------" # Initialise the RAGE tools for rage::atStringHash below. g = Globals::instance( ) p = Pipeline::Config::instance().projects[g.toolsproject] r = RageUtils::new( p ) # Now write the enum file (checking it out of Perforce first). material_enums_sch = proj_root + "/src/dev/game/script_headers/material_enums.sch" system("p4 edit //depot/gta5/src/dev/game/script_headers/material_enums.sch") File.open(material_enums_sch, 'w') do |file| file.print("////////////////////////////////////////////////////////////////////////////////\n") file.print("// WARNING: THIS FILE IS AUTOGENERATED. ANY CHANGES MADE WILL GET OVERWRITTEN //\n") file.print("////////////////////////////////////////////////////////////////////////////////\n\n") file.print("ENUM MATERIAL_NAMES\n") file.print("INVALID_MATERIAL=0,") i=0 FRIENDLY_NAMES.each_key do |friendly_name| # Hash the string. material_name = FRIENDLY_NAMES[friendly_name] print material_name hash = r.rage.atStringHash(material_name + "_#{material_dict[material_name]}") if i < FRIENDLY_NAMES.size() - 1 temp_string = sprintf("#{friendly_name}=%d,", ConvertU32ToS32(hash)) else temp_string = sprintf("#{friendly_name}=%d ", ConvertU32ToS32(hash)) end file.printf("\n%-69s// %s", temp_string, material_name) i += 1 end file.printf("\nENDENUM\n") end # Closes "material_enums.sch". puts "Script completed successfully! :)" Pipeline::GUI::MessageBox::information("#{g_AppName}", "Script completed successfully! :)") rescue SystemExit => ex # Allows script to exit quietly after fatal exceptions. rescue Exception => ex puts "Unhandled exception: #{ex.message}" puts ex.backtrace.join( "\n" ) Pipeline::GUI::ExceptionDialog::show_dialog( ex, "Unhandled exception: #{ex.message}" ) end # Main try-catch block. end # Main.