238 lines
7.8 KiB
Ruby
Executable File
238 lines
7.8 KiB
Ruby
Executable File
#
|
|
# gamedataloader.rb
|
|
# Game Data Loader
|
|
#
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Date:: 28 February 2008
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/config/projects'
|
|
require 'pipeline/content/content_core'
|
|
require 'pipeline/content/content_maps'
|
|
require 'pipeline/game/mapidefile'
|
|
require 'pipeline/game/mapiplfile'
|
|
require 'pipeline/os/path'
|
|
require 'pipeline/log/log'
|
|
require 'pipeline/util/rage'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Code
|
|
#-----------------------------------------------------------------------------
|
|
module Pipeline
|
|
module Game
|
|
|
|
#
|
|
# == Description
|
|
# This class is a helper class to load a Rockstar North game's data files
|
|
# into memory for further processing.
|
|
#
|
|
# E.g. it can be used to load all map IDE/IPL files for later processing
|
|
# by data exporters or statistics tools.
|
|
#
|
|
class GameDataLoader
|
|
class Error < StandardError; end
|
|
|
|
attr_reader :project # Associated project
|
|
attr_reader :project_ides # Hash ide_filename => IDEFile
|
|
attr_reader :project_ipls # Hash ipl_filename => IPLFile
|
|
attr_reader :project_imgs # Hash img_filename => IMGFile
|
|
|
|
#---------------------------------------------------------------------
|
|
# Virtual Attributes
|
|
#---------------------------------------------------------------------
|
|
|
|
def total_definitions
|
|
|
|
total = 0
|
|
@project_ides.each do |ide_filename, ideobj|
|
|
|
|
total += ideobj.total_definitions
|
|
end
|
|
total
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Constructor
|
|
#---------------------------------------------------------------------
|
|
|
|
#
|
|
# Constructor, loads all game definition and placement data using the
|
|
# project configuration, based on the game_tag specified.
|
|
#
|
|
def initialize( project )
|
|
|
|
@log = Log.new( 'Game Data Loader' )
|
|
@project = project
|
|
@r = Pipeline::RageUtils.instance()
|
|
|
|
@project_ides = {}
|
|
@project_ipls = {}
|
|
@project_imgs = {}
|
|
@definitions_cache = {}
|
|
|
|
# Ensure project and RAGE are properly initialised...
|
|
@project.load_config()
|
|
@project.load_content()
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Public Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
#
|
|
# Load all project IDE files based on nodes in the project's content
|
|
# tree.
|
|
#
|
|
def load_ides( verbose = false )
|
|
|
|
puts "Loading Project #{@project.uiname} IDE Files..."
|
|
content = @project.content.find_first_group( 'output_inner' )
|
|
@project.in_env do |env|
|
|
content.walk do |c|
|
|
next unless ( c.is_a?( Pipeline::Content::MapImage ) )
|
|
|
|
c.inputs.each do |input|
|
|
next unless ( input.is_a?( Pipeline::Content::Map ) )
|
|
next unless ( input.exportdefinitions )
|
|
|
|
ide_filename = env.subst( OS::Path.combine( c.path, input.name ) + '.ide' )
|
|
next unless ::File::exists?( ide_filename )
|
|
|
|
load_ide_file( ide_filename, verbose )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
#
|
|
# Load all project IPL files based on nodes in the project's content
|
|
# tree.
|
|
#
|
|
def load_ipls( verbose = false )
|
|
|
|
puts "Loading Project #{@project.uiname} IPL Files..."
|
|
content = @project.content.find_first_group( 'output_inner' )
|
|
@project.in_env do |env|
|
|
content.walk do |c|
|
|
next unless ( c.is_a?( Pipeline::Content::MapImage ) )
|
|
|
|
c.inputs.each do |input|
|
|
next unless ( input.is_a?( Pipeline::Content::Map ) )
|
|
next unless ( input.exportinstances )
|
|
|
|
ipl_filename = env.subst( OS::Path.combine( c.path, input.name ) + '.ipl' )
|
|
img_filename = env.subst( OS::Path.combine( c.path, input.name ) + '.img' )
|
|
next unless ::File::exists?( ipl_filename )
|
|
|
|
load_ipl_file( ipl_filename, img_filename, verbose )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return an IDEDef object for the specified instance object. Return nil
|
|
# if not found, or not loaded.
|
|
#
|
|
def find_def_for_inst( instance )
|
|
throw ArgumentError.new( "Specify IPLObjInst object" ) \
|
|
unless ( instance.is_a?( IPLObjInst ) )
|
|
|
|
return @definitions_cache[instance.name] if ( @definitions_cache.has_key?( instance.name ) )
|
|
nil
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Private Attributes
|
|
#---------------------------------------------------------------------
|
|
|
|
private
|
|
|
|
attr_reader :definition_cache
|
|
|
|
#---------------------------------------------------------------------
|
|
# Private Constants
|
|
#---------------------------------------------------------------------
|
|
|
|
private
|
|
|
|
IMAGE_MOUNT = 'image:/'
|
|
|
|
#---------------------------------------------------------------------
|
|
# Private Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
private
|
|
|
|
#
|
|
# Load a single IDE file
|
|
#
|
|
def load_ide_file( map_ide_path, verbose = false )
|
|
|
|
raise ArgumentError.new( "IDE File #{map_ide_path} does not exist." ) \
|
|
unless File.exists?( map_ide_path )
|
|
|
|
puts "Loading IDE: #{map_ide_path}" if verbose
|
|
idefile = MapIDEFile.new( map_ide_path )
|
|
@project_ides[map_ide_path] = idefile
|
|
|
|
# Populate our definition cache for easy lookup later. This
|
|
# could be built on first access to find_def_for_inst()
|
|
# function.
|
|
addToDefCache( idefile )
|
|
end
|
|
|
|
#
|
|
# Load IPL file(s) for a specific map section.
|
|
#
|
|
def load_ipl_file( map_ipl_path, map_img_path, verbose = false )
|
|
raise ArgumentError.new( "IPL file #{map_ipl_path} does not exist." ) \
|
|
unless File.exists?( map_ipl_path )
|
|
raise ArgumentError.new( "IMG file #{map_img_path} does not exist." ) \
|
|
unless File.exists?( map_img_path )
|
|
|
|
puts "Loading IPL: #{map_ipl_path}" if verbose
|
|
@project_ipls[map_ipl_path] = MapIPLFile.new( map_ipl_path )
|
|
|
|
# Load all map image IPLs...
|
|
@r.image.mount( map_img_path, IMAGE_MOUNT )
|
|
found_files = @r.find_files( "#{IMAGE_MOUNT}*.ipl" )
|
|
found_files.each do |file|
|
|
|
|
if ( @project_ipls.has_key?( "#{IMAGE_MOUNT}#{file}" ) )
|
|
@log.warn( "GameDataLoader: IPL File #{file} already loaded." )
|
|
next
|
|
end
|
|
|
|
puts "\tLoading sub-IPL: #{IMAGE_MOUNT}#{file}" if verbose
|
|
@project_ipls[file] = MapIPLFile.new( "#{IMAGE_MOUNT}#{file}" )
|
|
end
|
|
end
|
|
|
|
#
|
|
#
|
|
#
|
|
def addToDefCache( idefile )
|
|
|
|
raise "idefile not MapIDEFile class." unless MapIDEFile == idefile.class
|
|
|
|
idefile.object_definitions.each do |obj|
|
|
|
|
@definitions_cache[obj.name.downcase] = obj
|
|
end
|
|
idefile.time_object_definitions.each do |obj|
|
|
|
|
@definitions_cache[obj.name.downcase] = obj
|
|
end
|
|
end
|
|
end
|
|
|
|
end # Game module
|
|
end # Pipeline module
|
|
|
|
# End of gamedataloader.rb
|