198 lines
5.9 KiB
Ruby
Executable File
198 lines
5.9 KiB
Ruby
Executable File
#
|
|
#
|
|
# Author:: Mark Harrison-Ball <Mark.Harrison-Ball@rockstargames.com>
|
|
# Date:: 15 September 2013 (AP3)
|
|
# Purpose:
|
|
# ~ Generic object to store Shot Info
|
|
|
|
|
|
#
|
|
|
|
path = File.expand_path $0
|
|
path = File.dirname(path)
|
|
require 'pathname'
|
|
|
|
|
|
|
|
require "#{path}/../../Global/cutscene/modelInfo"
|
|
require "#{path}/../../Global/cutscene/eventInfo"
|
|
|
|
PROP_TYPE = 'cutfPropModelObject'
|
|
PED_TYPE = 'cutfPedModelObject'
|
|
VEHICLE_TYPE = 'cutfVehicleModelObject'
|
|
WEAPON_TYPE = 'cutfWeaponModelObject'
|
|
HIDDENPROP_TYPE = 'cutfHiddenModelObject'
|
|
BLOCKINGBOUNDS_TYPE = 'cutfBlockingBoundsObject'
|
|
AUDIO_TYPE = 'cutfAudioObject'
|
|
PARTICLE_TYPE = 'cutfParticleEffectObject'
|
|
OVERLAY_TYPE = 'cutfOverlayObject'
|
|
ANIMATEDPARTICLE = 'cutfAnimatedParticleEffectObject'
|
|
SUBTITLE_TYPE = 'cutfSubtitleObject'
|
|
LIGHT_TYPE = 'cutfLightObject'
|
|
ANIMATEDLIGHT_TYPE = 'cutfAnimatedLightObject'
|
|
|
|
EVENTOBJECTID_TYPE = 'cutfObjectIdEvent'
|
|
|
|
|
|
class ShotInfo
|
|
attr_reader :shotName
|
|
attr_reader :relativePath
|
|
attr_reader :shotPath
|
|
attr_reader :duration
|
|
attr_reader :frames
|
|
attr_reader :flags
|
|
attr_reader :iRangeStart
|
|
attr_reader :iRangeEnd
|
|
attr_reader :errorMsg
|
|
attr_reader :models
|
|
attr_reader :offset
|
|
attr_reader :rotation
|
|
attr_reader :pCutsceneEventList
|
|
|
|
attr_writer :shotName
|
|
attr_writer :shotPath
|
|
attr_writer :duration
|
|
attr_writer :frames
|
|
attr_writer :flags
|
|
attr_writer :iRangeStart
|
|
attr_writer :iRangeEnd
|
|
attr_writer :errorMsg
|
|
attr_writer :models
|
|
attr_writer :offset
|
|
attr_writer :rotation
|
|
|
|
def initialize()
|
|
@shotName = nil
|
|
@shotPath = nil
|
|
@relativePath = nil
|
|
@duration = 0 #fTotalDuration
|
|
@frames = 0
|
|
@flags = 0 #iCutsceneFlags
|
|
@iRangeStart = 0
|
|
@iRangeEnd = 0
|
|
@errorMsg = ''
|
|
@models = [] #Hold a list of Model Objects
|
|
@bBlockingBounds = false
|
|
@offset = [0,0,0]
|
|
@rotation = 0
|
|
@decalsList = []
|
|
@vfxList = []
|
|
@pCutsceneEventList = []
|
|
end
|
|
|
|
def parse(metadataUtils, log=nil)
|
|
if @shotPath != nil
|
|
begin
|
|
setRelativePath() # Relative Path (this is to support different different branches)
|
|
readMetafile(metadataUtils)
|
|
rescue => e
|
|
puts e
|
|
if log
|
|
log.error(e)
|
|
end
|
|
@errorMsg = e.to_s.gsub("'"," ")
|
|
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
private
|
|
def setRelativePath()
|
|
safe_path = Pathname.new(File.expand_path(@shotPath)).to_s
|
|
pathSplit = safe_path.split('/')
|
|
sceneIndex = pathSplit.index("cuts")
|
|
|
|
filePath = ''
|
|
(sceneIndex..pathSplit.length-1).each do |n|
|
|
filePath+='/'+pathSplit[n]
|
|
end
|
|
@relativePath = filePath
|
|
end
|
|
|
|
# Read our Shot Info
|
|
def readMetafile(metadataUtils)
|
|
#BASIC DATA
|
|
shotDef = metadataUtils.ParseMetaFile( @shotPath )
|
|
@duration = metadataUtils.FindFirstStructureNamed( shotDef, "fTotalDuration" ).value.to_f
|
|
|
|
@iRangeStart = metadataUtils.FindFirstStructureNamed( shotDef, "iRangeStart" ).value.to_i
|
|
@iRangeEnd = metadataUtils.FindFirstStructureNamed( shotDef, "iRangeEnd" ).value.to_i
|
|
@frames = @iRangeEnd-@iRangeStart+1 # (@duration * 30).to_i
|
|
|
|
|
|
@flags = metadataUtils.FindFirstStructureNamed(shotDef, "iCutsceneFlags")[0].value.to_i
|
|
|
|
offset = metadataUtils.FindFirstStructureNamed(shotDef, "vOffset")
|
|
@offset = [offset.x, offset.y, offset.z]
|
|
|
|
|
|
@rotation = metadataUtils.FindFirstStructureNamed(shotDef, "fRotation").value.to_f
|
|
|
|
#hasBlocking = metadataUtils.FindFirstStructureNamed(shotDef, "fRotation")
|
|
|
|
# GET OUR MODEL OBJECTS
|
|
readModels(metadataUtils, shotDef)
|
|
# GET OUR SHOT EVENTS
|
|
readEvents(metadataUtils, shotDef)
|
|
end
|
|
|
|
def readModels(metadataUtils, shotDef)
|
|
cutscneObjs = metadataUtils.FindFirstStructureNamed( shotDef, "pCutsceneObjects" )
|
|
if cutscneObjs
|
|
cutscneObjs.each do |object|
|
|
|
|
if object.value.name == PED_TYPE
|
|
|
|
modelInfo = ModelInfo.new( metadataUtils, object.value, PED_TYPE )
|
|
models.push(modelInfo)
|
|
elsif object.value.name == VEHICLE_TYPE
|
|
modelInfo = ModelInfo.new( metadataUtils, object.value, VEHICLE_TYPE )
|
|
models.push(modelInfo)
|
|
elsif object.value.name == PROP_TYPE
|
|
modelInfo = ModelInfo.new( metadataUtils, object.value, PROP_TYPE )
|
|
models.push(modelInfo)
|
|
elsif object.value.name == WEAPON_TYPE
|
|
modelInfo = ModelInfo.new( metadataUtils, object.value, WEAPON_TYPE )
|
|
models.push(modelInfo)
|
|
#elsif object.value.name == HIDDENPROP_TYPE
|
|
# modelInfo = ModelInfo.new( metadataUtils, object.value, HIDDENPROP_TYPE )
|
|
# models.push(modelInfo)
|
|
#elsif object.value.name == BLOCKINGBOUNDS_TYPE
|
|
# blockingInfo = BlockingInfo.new( metadataUtils, object.value, BLOCKINGBOUNDS_TYPE )
|
|
# models.push(blockingInfo)
|
|
elsif object.value.name == AUDIO_TYPE
|
|
#puts '/n##############################################/n'
|
|
audioInfo = AudioInfo.new( metadataUtils, object.value, AUDIO_TYPE )
|
|
|
|
models.push(audioInfo)
|
|
# DEBUG INFO
|
|
#audioInfo.instance_variables.map do |var|
|
|
# puts [var, audioInfo.instance_variable_get(var)].join(":")
|
|
#end
|
|
#puts '\n##############################################\n'
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
end
|
|
|
|
def readEvents(metadataUtils, shotDef)
|
|
cutsceneEventList = metadataUtils.FindFirstStructureNamed( shotDef, "pCutsceneEventList" )
|
|
if cutsceneEventList
|
|
cutsceneEventList.each do |object|
|
|
if object.value.name == EVENTOBJECTID_TYPE
|
|
eventInfo = CutfObjectIdEvent.new( metadataUtils, object.value )
|
|
@pCutsceneEventList.push(eventInfo)
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end |