Files
2025-09-29 00:52:08 +02:00

163 lines
6.6 KiB
Ruby
Executable File

# 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.