
fn report =	
(
	-----------		-----------		-----------		-----------		-----------		-----------		-----------		-----------		-----------		-----------
	format "\n -------------::g_FILE_HEADER-------------:\n"
	print ::g_FILE_HEADER
	Append ::g_report ::g_FILE_HEADER
	
	format "\n -------------::g_CHUNKTABLE_FILE_CONSTANTS-------------:\n"
	print ::g_CHUNKTABLE_FILE_CONSTANTS
	Append ::g_report ::g_CHUNKTABLE_FILE_CONSTANTS
	
	-----------------------------------------------------------------------------
	format "\n -------------::g_CHUNKTABLE_0744_0745-------------:\n"
	print ::g_CHUNKTABLE_0744_0745
	Append ::g_report ::g_CHUNKTABLE_0744_0745
					
		format "\n -------------::g_CHUNKTABLE_0744_0745[i].ChunkType-------------: \n"
		print ::g_CHUNKTABLE_0744_0745[1].ChunkType
		Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkType
						
		format "\n -------------::g_CHUNKTABLE_0744_0745[i].ChunkVersion-------------: \n"
		print ::g_CHUNKTABLE_0744_0745[1].ChunkVersion
		Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkVersion
						
		format "\n -------------::g_CHUNKTABLE_0744_0745[i].FileOffset-------------: \n"
		print ::g_CHUNKTABLE_0744_0745[1].FileOffset
		Append ::g_report ::g_CHUNKTABLE_0744_0745[1].FileOffset
						
		format "\n -------------::g_CHUNKTABLE_0744_0745[i].ChunkID-------------: \n"
		print ::g_CHUNKTABLE_0744_0745[1].ChunkID
		Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkID
						
		format "\n -------------::g_CHUNKTABLE_0744_0745[i].ChunkPlusDescr_size-------------: \n"
		print ::g_CHUNKTABLE_0744_0745[1].ChunkPlusDescr_size
		Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkPlusDescr_size			
		-----------------------------------------------------------------------------
					
	format "\n -------------::g_MTL_NAME_CHUNK_DESC_0802-------------:\n"
	print ::g_MTL_NAME_CHUNK_DESC_0802
	Append ::g_report ::g_MTL_NAME_CHUNK_DESC_0802
	
	format "\n -------------::g_MTL_NAME_CHUNK_DESC_0800-------------:\n"
	print ::g_MTL_NAME_CHUNK_DESC_0800
	Append ::g_report ::g_MTL_NAME_CHUNK_DESC_0800

	format "\n -------------::g_MESH_SUBSETS_CHUNK_DESC_0800-------------:\n"
	print ::g_MESH_SUBSETS_CHUNK_DESC_0800
	Append ::g_report ::g_MESH_SUBSETS_CHUNK_DESC_0800
					
	for s=1 to ::g_MESH_SUBSETS_CHUNK_DESC_0800.count do
	(
		format "\n -------------::g_MESH_SUBSETS_CHUNK_DESC_0800[s].MeshSubsetsArr-------------:\n"			
		print ::g_MESH_SUBSETS_CHUNK_DESC_0800[s].MeshSubsetsArr
		Append ::g_report ::g_MESH_SUBSETS_CHUNK_DESC_0800[s].MeshSubsetsArr
						
		format "\n -------------::g_MESH_SUBSETS_CHUNK_DESC_0800[s].ChunkHeadersArr-------------:\n"
		print ::g_MESH_SUBSETS_CHUNK_DESC_0800[s].ChunkHeadersArr
		Append ::g_report ::g_MESH_SUBSETS_CHUNK_DESC_0800[s].ChunkHeadersArr
	)			
					
	format "\n -------------::g_NODE_CHUNK_DESC_0824-------------:\n"
	print ::g_NODE_CHUNK_DESC_0824
	Append ::g_report ::g_NODE_CHUNK_DESC_0824
					
	format "\n -------------::g_MESH_CHUNK_DESC_0801-------------:\n"
	print ::g_MESH_CHUNK_DESC_0801
	Append ::g_report ::g_MESH_CHUNK_DESC_0801
					
	format "\n -------------::g_FOLIAGE_INFO_CHUNK_DESC-------------:\n"
	print ::g_FOLIAGE_INFO_CHUNK_DESC
	Append ::g_report ::g_FOLIAGE_INFO_CHUNK_DESC
	-----------		-----------		-----------		-----------		-----------		-----------		-----------		-----------		-----------		-----------
)

fn store_report =	
(
	if ::_LOADEDm != unsupplied then
	(
		try
		(
			-----------		-----------		-----------		-----------		-----------		-----------		-----------
			Append ::g_report ::g_FILE_HEADER
			Append ::g_report ::g_CHUNKTABLE_FILE_CONSTANTS
			-----------------------------------------------------------------------------
			Append ::g_report ::g_CHUNKTABLE_0744_0745					
			(
				Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkType
				Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkVersion
				Append ::g_report ::g_CHUNKTABLE_0744_0745[1].FileOffset
				Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkID
				Append ::g_report ::g_CHUNKTABLE_0744_0745[1].ChunkPlusDescr_size			
				-----------------------------------------------------------------------------	
			)	

			Append ::g_report ::g_MTL_NAME_CHUNK_DESC_0802
			Append ::g_report ::g_MTL_NAME_CHUNK_DESC_0800
			Append ::g_report ::g_MESH_SUBSETS_CHUNK_DESC_0800
							
			for s=1 to ::g_MESH_SUBSETS_CHUNK_DESC_0800.count do
			(
				Append ::g_report ::g_MESH_SUBSETS_CHUNK_DESC_0800[s].MeshSubsetsArr
				Append ::g_report ::g_MESH_SUBSETS_CHUNK_DESC_0800[s].ChunkHeadersArr
			)

			Append ::g_report ::g_NODE_CHUNK_DESC_0824
			Append ::g_report ::g_MESH_CHUNK_DESC_0801
			Append ::g_report ::g_FOLIAGE_INFO_CHUNK_DESC
			-----------		-----------		-----------		-----------		-----------		-----------		-----------
		)
		catch
		(
			format "\n\n\n\n*** *** *** *** *** ***  Could not store report ***  *** *** *** *** *** ***\n"
			format "%" (getCurrentException())
			format "\n*** *** *** *** *** *** END OF Could not store report *** *** *** *** *** *** *** ***\n\n\n\n"
		)
	)
)

fn cryxmlB_loader \							
							caller: \
							g_cryFile: \
							mtlFile: =
(
	g_dirpath = getINISetting ::g_iniFile "paths" "g_dirpath"
		
	if NOT (doesfileexist g_dirpath) then
	(
		confirm = yesNoCancelBox "You must choose a root game directory, do you want to do it now?" \
												title:"WARNING" \
												beep:true		
		if confirm == #yes then
		(
			::g_dirpath = getSavePath caption:"Choose Game directory"
		)
	)
	
	if g_dirpath != undefined then
	(
		if pathConfig.isLegalPath g_dirpath then
		(
			g_cryFile = getINISetting ::g_iniFile "paths" "last_loaded"--The last file we loaded
			
			if g_cryFile != undefined then 
			(
				if doesfileexist g_cryFile then
				(
					inst_s_OPTIONS = s_OPTIONS()	--create instance
					
					if ::g_dds then
					(
						inst_s_OPTIONS.chk_dds = ::g_dds 		
					)

					inst_xmlB_PROCESSOR = xmlB_PROCESSOR() --create struct instance
					
					local CHUNK_DESC = 0 --we set to 0, because we will pass this as a & reference					
					CHUNK_DESC = inst_xmlB_PROCESSOR.ret_CHUNK_DESC \
																								CHUNK_DESC:&CHUNK_DESC
					
					if ::g_xmlB_Report 						then 	( inst_xmlB_PROCESSOR.report 							= true )
					if ::g_xmlB_Debug_Report				then 	( inst_xmlB_PROCESSOR.xmlB_Debug_Report 		= true )
					if ::g_Build_Material_Report 			then 	( inst_xmlB_PROCESSOR.Build_Material_Report 		= true )
					if ::g_skip_Lod_Materials				then 	( inst_xmlB_PROCESSOR.skip_Lod_Materials 			= true )
					if ::g_xmlB_Report_v2					then 	( inst_xmlB_PROCESSOR.xmlB_Report_v2 				= true )
					
					--CGFM
					if (getFilenameType g_cryFile) == ".cgfm" then
					(
						------------------------------ Process xmlB .mtl Material and Textures ------------------------------				
						inst_xmlB_PROCESSOR.cry_xmlB_ReaderV \
																				g_curr_MaterialRef_node_counter:	&g_curr_MaterialRef_node_counter \																				
																				inst_s_OPTIONS:							&inst_s_OPTIONS \
																				CHUNK_DESC:								&CHUNK_DESC \
																				type:											".cgf" \
																				mtl_File:										&mtlFile
					)
					--SKINM
					else if (getFilenameType g_cryFile) == ".skinm" then
					(
						------------------------------ Process xmlB .mtl Material and Textures ------------------------------
						inst_xmlB_PROCESSOR.cry_xmlB_ReaderV \
																				g_curr_MaterialRef_node_counter:	&g_curr_MaterialRef_node_counter \																				
																				inst_s_OPTIONS:							&inst_s_OPTIONS \
																				CHUNK_DESC:								&CHUNK_DESC \
																				type:											".skin" \
																				mtl_File:										&mtlFile
					)
					--CHRM
					else if (getFilenameType g_cryFile) == ".chrm" then
					(				
						------------------------------ Process xmlB .mtl Material and Textures ------------------------------
						inst_xmlB_PROCESSOR.cry_xmlB_ReaderV \	
																				g_curr_MaterialRef_node_counter:	&g_curr_MaterialRef_node_counter \																				
																				inst_s_OPTIONS:							&inst_s_OPTIONS \
																				CHUNK_DESC:								&CHUNK_DESC \
																				type:											".chr" \
																				mtl_File:										&mtlFile				
					)
					--CHRPARAMS
					else if (getFilenameType g_cryFile) == ".chrparams" then
					(				
						inst_xmlB_PROCESSOR.cry_general_xmlB_ReaderV \
																							xmlBFile:					&g_cryFile \
																							inst_s_OPTIONS:		&inst_s_OPTIONS \
																							type:						".chrparams"
					)
					--CDF
					else if (getFilenameType g_cryFile) == ".cdf" then
					(
						inst_xmlB_PROCESSOR.cry_general_xmlB_ReaderV \
																							xmlBFile:					&g_cryFile \
																							inst_s_OPTIONS:		&inst_s_OPTIONS \
																							type:						".cdf"
					)
					--MTL
					else if (getFilenameType g_cryFile) == ".mtl" then
					(
						inst_xmlB_PROCESSOR.cry_general_xmlB_ReaderV \
																							xmlBFile:					&g_cryFile \
																							inst_s_OPTIONS:		&inst_s_OPTIONS \
																							type:						".mtl"
					)
					--XML
					else if (getFilenameType g_cryFile) == ".xml" then
					(
						inst_xmlB_PROCESSOR.cry_general_xmlB_ReaderV \
																							xmlBFile:					&g_cryFile \
																							inst_s_OPTIONS:		&inst_s_OPTIONS \
																							type:						".xml"
					)
				)
			)
		)
	)	
)

fn isolated_CHRPARAMS_Attribs \
											isolated_Node: =
(
	
	if isolated_Node.count == 2 then
	(
		for i=1 to isolated_Node.count do
		(
			attribName 		= isolated_Node[i][1]
			attribVal		 	= isolated_Node[i][2]
			
			--i==1 because "name" should always come before "path"
			if (stricmp attribName "name") == 0 AND \
				i == 1 then
			(
				case of
				(
					--If we discover more tokens, then we will add them, but these are all I have found so far.
					--In newer versions of CryEngine, I think the .caf files will be deprecated, but they are still used as ***on-demand assets***
					
					( stricmp attribVal "$TracksDatabase" == 0)	:
					(
						TracksDatabase 			= isolated_Node[i+1][2]
						TracksDatabase_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath TracksDatabase) --build full path
						format "TracksDatabase_path ($TracksDatabase): %\n" TracksDatabase_path						
					)
					( stricmp attribVal "#filepath" == 0):
					(
						filepath 			= isolated_Node[i+1][2]
						filepath_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath filepath) --build full path
						format "filepath_path (#filepath): %\n" filepath_path
					)
					( stricmp attribVal "$AnimEventDatabase" == 0):
					(
						AnimEventDatabase 			= isolated_Node[i+1][2]
						AnimEventDatabase_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath AnimEventDatabase) --build full path
						format "AnimEventDatabase_path ($AnimEventDatabase): %\n" AnimEventDatabase_path
					)
					( stricmp attribVal "\x2A" == 0): -- \x2A == *
					(
						CAF_pattern 			= isolated_Node[i+1][2]						
						format "CAF_pattern: %\n" CAF_pattern
					)
					default:
					(
						CAF_File 			= isolated_Node[i+1][2]
						CAF_File_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath CAF_File) --build full path
						format "CAF_File_path: %\n" CAF_File_path
					)					
				)
			)
		)
	)
	
)

fn populate_Animation_Tracks =
(
	local arr 			= #()
	local chrParams 	= ::g_inst_CHRPARAMS_Attribs	
	local unique_nodeIDs = #()
				
	for i=1 to chrParams.count do
	(
		local nodeID = 0		
		nodeID = chrParams[i].nodeID		
		AppendifUnique unique_nodeIDs nodeID
	)
	
	for i=1 to unique_nodeIDs.count do
	(			
		local UnodeID = unique_nodeIDs[i]		
		local isolated_Node = #()
		local nTagString = ""
		
		if ::rollout_Report.chk_Anim_Report.state then ( print "//////////////////////////////////////////////\n" ) --report
		for idx=1 to chrParams.count do
		(
			if chrParams[idx].nodeID == UnodeID then
			(
				local attribName 		= chrParams[idx].attribName[1]
				local attribVal			= chrParams[idx].attribVal[1]
				
				nTagString 				= chrParams[idx].nTagString
				
				Append isolated_Node #(attribName, attribVal)
				
				if ::rollout_Report.chk_Anim_Report.state then --report
				(				
					print chrParams[idx].nodeID
					print chrParams[idx].nTagString
					print chrParams[idx].attribName[1]
					print chrParams[idx].attribVal[1]
				)				
			)
		)
		if ::rollout_Report.chk_Anim_Report.state then ( print "\n" ) --report
		
		if (stricmp nTagString "Animation") == 0 then
		(
			print "//////////////////////////////////////////////\n"		
			isolated_CHRPARAMS_Attribs \
													isolated_Node:isolated_Node
			print "\n"
		)
	)	
)

fn load_CHRPARAMS_into_List =
(
	------------------------------------------------------------------------------
	try
	(
		RemoveRollout  	::rollout_AnimationTracks 		::CRYOP			
	)
	catch
	()
	rollout rollout_AnimationTracks "Animation Tracks" width:290 height:20 category:5
	(
		dropdownList 'ddl_Animation_Tracks' "Animation Tracks" pos:[8,20] width:265 height:30 items:#() align:#left
			
		on rollout_AnimationTracks open do
		(
			populate_Animation_Tracks ()
				
-- 			ddl_Animation_Tracks.items = populate_Animation_Tracks()
		)
	)				
	AddRollout  	::rollout_AnimationTracks 		::CRYOP rolledUp:true		
	------------------------------------------------------------------------------
)

fn CAF_read \
					caller: \
					g_cryFile: =
(
	load_global_CAF_arrays()	
	-----------------------------------------------------------------------------------
	inst_GAHCAF_PROCESSOR = GAHCAF_PROCESSOR()
	inst_GAHCAF_PROCESSOR.load_CAF \
													caller:caller \
													CAF_file:g_cryFile
	-----------------------------------------------------------------------------------
	store_global_CAF_arrays \
										fileType:(getFilenameType g_cryFile)
	set_CAF_states \
							type:(getFilenameType g_cryFile)
)

fn cryFile_loader \
						g_cryFile: \
						caller: \
						mtlFile: \
						assetName_From_CDF: =
(
	if caller == "CAF" OR \
		caller == ".caf" then
	(		
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
		
	)
	else if caller == "IMG" OR \
				caller == ".img" then
	(
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
	)
	else
	(
		--///////////////////// Reset Arrays and vars /////////////////////
		::g_assetName_From_CDF	= ""	
		
		g_xmlB_Parsed					=	#( \
														#(), 	-- 1
														#(), 	-- 2
														#(), 	-- 3
														#(), 	-- 4
														#() 	-- 5 MaterialRef
													)

		g_xmlB_MatNodesSet		= #()


		g_cdf_xmlB_Parsed			=	#( \
														#(), 	-- 1
														#(), 	-- 2
														#(), 	-- 3
														#(), 	-- 4
														#() 	-- 5 MaterialRef
													)

		g_cdf_xmlB_MatNodesSet 	= #()
													
		inst_LOADED 					= LOADED()
		inst_xmlB_LOADED 			= xmlB_LOADED()

		_LOADED 						= unsupplied
		_LOADEDm 						= unsupplied
		--/////////////////////////////////////////////////////////////////
		
		-- Set the AName from the CDF if we found any
		if assetName_From_CDF != unsupplied then
		(
			if iskindof assetName_From_CDF string then
			(
				if assetName_From_CDF != "" then
				(
					::g_assetName_From_CDF = assetName_From_CDF
				)
			)
		)
		
		--//////////////////////////////////////////////////////////////////////////////////
		setINISetting 	::g_iniFile 	"paths" 		("g_cryFile"+(getFilenameType g_cryFile)) 		g_cryFile
		setINISetting 	::g_iniFile 	"paths" 		("last_loaded") 											g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"paths" 		("first_loaded") 											g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType1") 												(getFilenameType g_cryFile) --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType2_loaded") 									"false" --we set this to true later if it has been read
					
		load_global_arrays()
		-----------------------------------Load--------------------------------------
		g_bs = fopen g_cryFile "rb" --open binary stream

		--//////////////////////////
		load_cryFile bstream:g_bs						
		--//////////////////////////					
		
		--------------------------------End of Load---------------------------------
		fclose g_bs	--Close & Flush Binary Stream
			
		store_global_arrays fileType:(getFilenameType g_cryFile)			
		
		
		------------------ Try to read *.charparams if it exists (we read it here, but will use it later when and if we process the .caf ------------------
		local g_cryFile_chrparams 				= g_cryFile + "params"
		if doesfileexist g_cryFile_chrparams then
		(
			::g_inst_CHRPARAMS_Attribs 			= #() --reset global array
			
			format "g_cryFile_chrparams: %\n" g_cryFile_chrparams
			
			inst_xmlB_PROCESSOR = xmlB_PROCESSOR()
			inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																								CDF_File:				g_cryFile_chrparams \
																								inst_s_OPTIONS:		inst_s_OPTIONS \
																								type:						(getFilenameType g_cryFile_chrparams)
		)
		-------------------------------------------------------------------------------------------------------------------------------------------------------------
		
				
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		store_report ()	
		if ::g_Mesh_Report then
		(
			report()
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		--/////////////////////////////////////////////////////////////////////////////////	
		
		--Now we attempt to load the mesh version of the file above - in Ryse(at least), the file suffixes have an *m* added to the suffix
		g_cryFile_m = (g_cryFile + "m")	

		if doesfileexist g_cryFile_m then
		(
			--//////////////////////////////////////////////////////////////////////////////////
			setINISetting 	::g_iniFile 	"paths" ("g_cryFile"+(getFilenameType g_cryFile_m)) 	g_cryFile_m
			setINISetting 	::g_iniFile 	"paths" ("last_loaded") 												g_cryFile_m --we will use this for loading the material xmlB
			setINISetting 	::g_iniFile 	"fileType" ("fileType2") 												(getFilenameType g_cryFile_m) --we will use this for loading the material xmlB
						
			load_global_arrays()
			-----------------------------------Load--------------------------------------
			g_bs = fopen g_cryFile_m "rb" --open binary stream			

			--//////////////////////////
			load_cryFile bstream:&g_bs
			--//////////////////////////		
							
			fclose g_bs	--Close & Flush Binary Stream
			--------------------------------End of Load---------------------------------				
			
			store_global_arrays 		fileType:	(getFilenameType g_cryFile_m)
			set_modelStates 			type:			(getFilenameType g_cryFile_m)
			
			--/*
			--//////////////////////////////////// Build Bones ////////////////////////////////////	
			if NOT ::g_Dont_Load_Skeleton then
			(
				local has_bones = getINISetting ::g_iniFile "boneinfo" "has_bones" --this will tell us if there are bones present
				
				--Only if there are bones present, we try to build the bones
				if (stricmp has_bones "true") == 0 then
				(
					inst_create_bones = create_bones() --create struct
					if ::g_Create_Bones_Report then ( inst_create_bones.Create_Bones_Report = true )			

					inst_create_bones.CONSTRUCT_BONES \
																				LOADED:	::_LOADED \
																				LOADEDm:	::_LOADEDm				
				)
				
				--Once we are done with the bones methods, we set the *has_bones* back to false
				setINISetting 	::g_iniFile 	"boneinfo" "has_bones" 	"false"	
			)
			--/////////////////////////////////////////////////////////////////////////////////
			--*/
			
			if mtlFile == unsupplied then
			(				
				--Note, for .cgf(m) we do not supply a g_cryFile, because the .mtl name will be loaded from within the .cgfm file, from the chunk 0xCCCC0014
				--on the other hand, if we were loading from a Character Definition File (.cdf) then we would supply the file we read from within the .cdf
				cryxmlB_loader()
				
			)
			else
			(
				if mtlFile != undefined then
				(				
					if doesfileexist mtlFile then
					(
						cryxmlB_loader \
												mtlFile:mtlFile
					)
				)
			)
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		store_report ()
		if ::g_Mesh_Report then
		(
			report()
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
	)	
)

fn cryFile_Crysis_loader \
								g_cryFile: \
								caller: \
								mtlFile: \
								assetName_From_CDF: =
(
	if caller == "CAF" OR \
		caller == ".caf" then
	(		
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
		
	)
	else if caller == "IMG" OR \
				caller == ".img" then
	(
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
	)
	else
	(
		--///////////////////// Reset Arrays and vars /////////////////////
		::g_assetName_From_CDF	= ""	
		
		g_xmlB_Parsed					=	#( \
														#(), 	-- 1
														#(), 	-- 2
														#(), 	-- 3
														#(), 	-- 4
														#() 	-- 5 MaterialRef
													)

		g_xmlB_MatNodesSet		= #()


		g_cdf_xmlB_Parsed			=	#( \
														#(), 	-- 1
														#(), 	-- 2
														#(), 	-- 3
														#(), 	-- 4
														#() 	-- 5 MaterialRef
													)

		g_cdf_xmlB_MatNodesSet 	= #()
													
		inst_LOADED 					= LOADED()
		inst_xmlB_LOADED 			= xmlB_LOADED()

		_LOADED 						= unsupplied
		_LOADEDm 						= unsupplied
		--/////////////////////////////////////////////////////////////////
		
		/*
		-- Set the AName from the CDF if we found any
		if assetName_From_CDF != unsupplied then
		(
			if iskindof assetName_From_CDF string then
			(
				if assetName_From_CDF != "" then
				(
					::g_assetName_From_CDF = assetName_From_CDF
				)
			)
		)
		
		--//////////////////////////////////////////////////////////////////////////////////
		setINISetting 	::g_iniFile 	"paths" 		("g_cryFile"+(getFilenameType g_cryFile)) 		g_cryFile
		setINISetting 	::g_iniFile 	"paths" 		("last_loaded") 											g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"paths" 		("first_loaded") 											g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType1") 												(getFilenameType g_cryFile) --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType2_loaded") 									"false" --we set this to true later if it has been read
		--*/	
			
		load_global_arrays()
		-----------------------------------Load--------------------------------------
		g_bs = fopen g_cryFile "rb" --open binary stream

		--//////////////////////////
		load_cryFile bstream:g_bs						
		--//////////////////////////					
		
		--------------------------------End of Load---------------------------------
		fclose g_bs	--Close & Flush Binary Stream
			
		store_global_arrays fileType:(getFilenameType g_cryFile)			
		
		
		/*
		------------------ Try to read *.charparams if it exists (we read it here, but will use it later when and if we process the .caf ------------------
		local g_cryFile_chrparams 				= g_cryFile + "params"
		if doesfileexist g_cryFile_chrparams then
		(
			::g_inst_CHRPARAMS_Attribs 			= #() --reset global array
			
			format "g_cryFile_chrparams: %\n" g_cryFile_chrparams
			
			inst_xmlB_PROCESSOR = xmlB_PROCESSOR()
			inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																								CDF_File:				g_cryFile_chrparams \
																								inst_s_OPTIONS:		inst_s_OPTIONS \
																								type:						(getFilenameType g_cryFile_chrparams)
		
		)
		-------------------------------------------------------------------------------------------------------------------------------------------------------------
		
				
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		store_report ()	
		if ::g_Mesh_Report then
		(
			report()
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		--/////////////////////////////////////////////////////////////////////////////////	
		
		--Now we attempt to load the mesh version of the file above - in Ryse(at least), the file suffixes have an *m* added to the suffix
		g_cryFile_m = (g_cryFile + "m")	

		if doesfileexist g_cryFile_m then
		(
			--//////////////////////////////////////////////////////////////////////////////////
			setINISetting 	::g_iniFile 	"paths" ("g_cryFile"+(getFilenameType g_cryFile_m)) 	g_cryFile_m
			setINISetting 	::g_iniFile 	"paths" ("last_loaded") 												g_cryFile_m --we will use this for loading the material xmlB
			setINISetting 	::g_iniFile 	"fileType" ("fileType2") 												(getFilenameType g_cryFile_m) --we will use this for loading the material xmlB
						
			load_global_arrays()
			-----------------------------------Load--------------------------------------
			g_bs = fopen g_cryFile_m "rb" --open binary stream			

			--//////////////////////////
			load_cryFile bstream:&g_bs
			--//////////////////////////		
							
			fclose g_bs	--Close & Flush Binary Stream
			--------------------------------End of Load---------------------------------				
			
			store_global_arrays 		fileType:	(getFilenameType g_cryFile_m)
			set_modelStates 			type:			(getFilenameType g_cryFile_m)
			
			--//////////////////////////////////// Build Bones ////////////////////////////////////	
			if NOT ::g_Dont_Load_Skeleton then
			(
				local has_bones = getINISetting ::g_iniFile "boneinfo" "has_bones" --this will tell us if there are bones present
				
				--Only if there are bones present, we try to build the bones
				if (stricmp has_bones "true") == 0 then
				(
					inst_create_bones = create_bones() --create struct
					if ::g_Create_Bones_Report then ( inst_create_bones.Create_Bones_Report = true )			

					inst_create_bones.CONSTRUCT_BONES \
																				LOADED:	::_LOADED \
																				LOADEDm:	::_LOADEDm				
				)
				
				--Once we are done with the bones methods, we set the *has_bones* back to false
				setINISetting 	::g_iniFile 	"boneinfo" "has_bones" 	"false"	
			)
			--/////////////////////////////////////////////////////////////////////////////////
			
			if mtlFile == unsupplied then
			(				
				--Note, for .cgf(m) we do not supply a g_cryFile, because the .mtl name will be loaded from within the .cgfm file, from the chunk 0xCCCC0014
				--on the other hand, if we were loading from a Character Definition File (.cdf) then we would supply the file we read from within the .cdf
				cryxmlB_loader \
										g_MaterialRef_Bool:		&g_MaterialRef_Bool \
				
			)
			else
			(
				if mtlFile != undefined then
				(				
					if doesfileexist mtlFile then
					(
						cryxmlB_loader \
												g_MaterialRef_Bool:		&g_MaterialRef_Bool \
												mtlFile:mtlFile
					)
				)
			)
		)		
		--*/
		
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------		
		store_report ()
		if ::g_Mesh_Report then
		(
			report()
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
	)	
)

struct CA_SKIN
(
	n_File		 		= "",
	n_Material 			= "",
	n_Type 				= "",
	n_AName 			= "",							
	n_Binding 			= "",
	n_LodDistances 	= "",
	n_Flags			 	= ""
)

fn mtlName_deepCheck \
								&_Material_: =
(
	if _Material_ != unsupplied then
	(
		if _Material_ != undefined then
		(
			if NOT doesfileexist _Material_ then
			(
				check_4_mtl_suffix \
											filePath:&_Material_
				
				local newMtlBuild 		= ""
				local finalMtlPath 		= ""
								
				local mtlDir 				= getFilenamePath _Material_					
				local stringFiltered 		= filterString (filenameFromPath _Material_) "_"
								
				for i=1 to stringFiltered.count do
				(
					subS 					= stringFiltered[i]
									
					if ((stricmp subS "mat.mtl") == 0) OR \
						(matchpattern subS pattern:"*_mat") then
					(
						newMtlBuild = ""
						for s=1 to stringFiltered.count do
						(
							if s != i then
							(
								newMtlBuild += stringFiltered[s] 
							)
						)
					)
				)		
					
				finalMtlPath = pathConfig.ResolvePathSymbols (pathConfig.AppendPath mtlDir (newMtlBuild + ".mtl"))				
				
				if doesfileexist finalMtlPath then
				(
					_Material_ = finalMtlPath
				)				
			)
		)
	)
)

fn ISOLATED_CDF_NODE_LOADER \	
												inst_xmlB_PROCESSOR: \
												inst_s_OPTIONS: \
												g_cryFile: \
												nodeIsolation_arr: =
(
	--------------------Predeclare--------------------
	local _File_Name 				= ""
	local _File_							= ""
		
	local _Material_Name 			= ""
	local _Material_ 					= ""
		
	local _Type_Name 				= ""
	local _Type_						= ""
					
	local _AName_Name				= ""
	local _AName_ 					= ""					
		
	local _Binding_Name				= ""
	local _Binding_					= ""
					
	local _LodDistances_Name 	= ""
	local _LodDistances_ 			= ""
				
	local _Flags_Name 				= ""
	local _Flags_ 						= ""
	-----------------------------------------------------
	
	print "////////////////////////////////++++++++++"
	print nodeIsolation_arr
	print "////////////////////////////////++++++++++"
	
	
	for i=1 to nodeIsolation_arr.count do
	(
		local nTagString					= nodeIsolation_arr[i].nTagString
		
		if ::g_CDF_Report then ( format "\nCDF nTagString: %\n" nTagString ) --report		
		
		for x=1 to nodeIsolation_arr[i].attribName.count do
		(
			--------------------------------------------------------------------------------------------
			local attribName				= nodeIsolation_arr[i].attribName[x]
			local attribVal					= nodeIsolation_arr[i].attribVal[x]
			--------------------------------------------------------------------------------------------
			
			if ::g_CDF_Report then ( format "\t% = %\n" 	attribName		attribVal ) --report
			
			if stricmp nTagString "Model" == 0 then
			(
				case of
				(
					(stricmp attribName "File" == 0):
					(
						_File_Name		= attribName
						_File_			= attribVal	
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_File_ --Note this is a reference and will update the g_cryFile above
					)
					(stricmp attribName "Material" == 0):
					(
						_Material_Name		= attribName
						_Material_				= attribVal
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_Material_ --Note this is a reference and will update the g_cryFile above
						
						mtlName_deepCheck \
													_Material_:&_Material_
					)
				)
			)			
			else if stricmp nTagString "AttachmentList" == 0 then
			(
				--// Put code here
			)
			else if stricmp nTagString "Attachment" == 0 then
			(					
				case of
				(
					(stricmp attribName "Type" == 0):
					(
						_Type_Name				= attribName
						_Type_						= attribVal									
						if ::g_CDF_Report then ( format "\tType: % = %\n"	_Type_Name	_Type_ ) --report
					)
					(stricmp attribName "AName" == 0):
					(
						_AName_Name				= attribName
						_AName_					= attribVal									
						if ::g_CDF_Report then ( format "\tAName: % = %\n"	_AName_Name	_AName_ ) --report
					)
					(stricmp attribName "Binding" == 0):
					(
						_Binding_Name			= attribName
						_Binding_					= attribVal
						if ::g_CDF_Report then ( format "\tBinding: % = %\n"	_Binding_Name	_Binding_ ) --report
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_Binding_ --Note this is a reference and will update the g_cryFile above
					)
					(stricmp attribName "Material" == 0):
					(
						_Material_Name		= attribName
						_Material_				= attribVal
						
						check_4_mtl_suffix filePath:&_Material_
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_Material_ --Note this is a reference and will update the g_cryFile above

						mtlName_deepCheck \
													_Material_:&_Material_
					)
					(stricmp attribName "LodDistances" == 0):
					(
						_LodDistances_Name	= attribName
						_LodDistances_			= attribVal									
						if ::g_CDF_Report then ( format "\tLodDistances: % = %\n"	_LodDistances_Name	_LodDistances_ ) --report
					)
					(stricmp attribName "Flags" == 0):
					(
						_Flags_Name				= attribName
						_Flags_						= attribVal									
						if ::g_CDF_Report then ( format "\tFlags: % = %\n"	_Flags_Name	_Flags_ ) --report
					)
					default:
					(									
					)
				)			
			)			
		)
	)
	
	format "########################################################\n"
	format "########################################################\n"
	format "########################################################\n"
	format "_Material_: %\n" _Material_
	format "_File_: %\n" _File_
	format "_Binding_: %\n" _Binding_
	format "########################################################\n"
	format "########################################################\n"
	format "########################################################\n"
	
	--///////////////////////////////////// Load Model file /////////////////////////////////////				
	if  NOT (Binary_CryTek_check File:_File_) then --if the xml file is not Crytek Binary XML
	(
		if ::g_CDF_Report then ( format "This is not a valid CryTek file, aborting!\n" ) --report
	)
	else
	(													
		if ::g_CDF_Report then ( format "We will now attempt to load _File_: % ...\n" _File_ )	--report										
		
		if (Binary_XML_check _Material_) then
		(
			
			
			cryFile_loader \
								g_cryFile:		_File_ \
								caller:			"CDF"	\
								mtlFile:			_Material_
		)
		else
		(
			cryFile_loader \
								g_cryFile:		_File_ \
								caller:			"CDF"
		)
																	
		------------------ Try to read *.charparams if it exists (we read it here, but will use it later when and if we process the .caf ------------------
		local g_cryFile_chrparams 				= _File_ + "params"
		if doesfileexist g_cryFile_chrparams then
		(
			::g_inst_CHRPARAMS_Attribs 			= #() --reset global array
			
			format "g_cryFile_chrparams: %\n" g_cryFile_chrparams
			inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																								CDF_File:				g_cryFile_chrparams \
																								inst_s_OPTIONS:		inst_s_OPTIONS \
																								type:						(getFilenameType g_cryFile_chrparams)
			
			
			 load_CHRPARAMS_into_List ()
			
			
			--Perhaps we should load the .dba for each file into the list instead
			--And if there is no .dba, there should be pure .caf files to load into the list
			
			--We should do all the CAF loading in here
			--Above we have read the .chrparams
			
			--So having read the .chrparams, we check and look for the .img and .dba inside the struct which we appended to this global array ::g_inst_CHRPARAMS_Attribs
			
			--load the caf animation pointers found in ::g_inst_CHRPARAMS_Attribs into a UI list
			
			--Let's say we pick a track, take the name of that track, and search the .img and read the CAF INFO
			--Then search the .dba and read the Controllers
		)
		-------------------------------------------------------------------------------------------------------------------------------------------------------------
	)
	--////////////////////////////////////////////////////////////////////////////////////////////	
	
	
	--////////////////////// Load Model Node Attachment( of type *CA_SKIN*) //////////////////////
	if stricmp _Type_ "CA_SKIN" == 0 then
	(
		if  NOT (Binary_CryTek_check File:_Binding_) then --if the xml file is not Crytek Binary XML
		(
			if ::g_CDF_Report then ( format "This is not a valid CryTek file, aborting!\n" ) --report
		)
		else
		(													
			if ::g_CDF_Report then ( format "We will now attempt to load _File_: % ...\n" _Binding_ )	--report
			
			if (Binary_XML_check _Material_) then
			(
				cryFile_loader \
									g_cryFile:		_Binding_ \
									caller:			"CDF" \
									mtlFile:			_Material_
			)
			else
			(
				cryFile_loader \
									g_cryFile:		_Binding_ \
									caller:			"CDF"
			)
		)
	)
	--//////////////////////////////////////////////////////////////////////////////////////////////
	
)

fn LOAD_CDF_ASSETS \
								inst_xmlB_PROCESSOR: \
								g_cryFile: \
								inst_s_OPTIONS: =
(
	inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																						CDF_File:				g_cryFile \
																						inst_s_OPTIONS:		inst_s_OPTIONS \
																						type:						(getFilenameType g_cryFile)
	if ::g_inst_CDF_Attribs.count > 0 then
	(
		format "We have successfully filled the ::g_inst_CDF_Attribs!\n"
		format "We are now ready to load the assets from the .cdf file...\n\n"
		
		local uniqueNodes_arr = #()
		for i=1 to ::g_inst_CDF_Attribs.count do
		(
			--Model Node will be = 0, and so will all its associated attributes
			--However, "Attachment" nodes are more than one, and will have different idx's
			local idx							= ::g_inst_CDF_Attribs[i].idx
			
			AppendifUnique uniqueNodes_arr idx
		)
		
		print uniqueNodes_arr
				
		for i=1 to uniqueNodes_arr.count do
		(
			local nodeIsolation_arr = #()				
			local uIDX					= uniqueNodes_arr[i]
				
			for ii=1 to ::g_inst_CDF_Attribs.count do
			(
				if uIDX == ::g_inst_CDF_Attribs[ii].idx do
				(
					Append nodeIsolation_arr ::g_inst_CDF_Attribs[ii]
				)
			)
			
			ISOLATED_CDF_NODE_LOADER \
														inst_xmlB_PROCESSOR:		inst_xmlB_PROCESSOR \
														inst_s_OPTIONS:				inst_s_OPTIONS \
														g_cryFile:						g_cryFile \										
														nodeIsolation_arr:			nodeIsolation_arr
		)	
	)
)

fn cryFile_CDF_loader \
								g_cryFile: =
(
	if g_cryFile == unsupplied then
	(
		::g_dirpath = getINISetting ::g_iniFile "paths" "g_dirpath"
	)
		
	if ::g_dirpath == "" then
	(
		confirm = yesNoCancelBox "You must choose a root game directory, do you want to do it now?" \
												title:"WARNING" \
												beep:true		
		if confirm == #yes then
		(
			::g_dirpath = getSavePath caption:"Choose Game directory"
		)
	)
	
	if ::g_dirpath != undefined then
	(
		if pathConfig.isLegalPath ::g_dirpath then
		(
			if g_cryFile != undefined then
			(
				if doesfileexist g_cryFile then
				(
					--///////////////////// Reset Arrays /////////////////////
					g_xmlB_Parsed							=	#( \
																		#(), 	-- 1
																		#(), 	-- 2
																		#(), 	-- 3
																		#(), 	-- 4
																		#() 	-- 5 MaterialRef
																		)
																
					g_xmlB_MatNodesSet				= #()

																
					g_cdf_xmlB_Parsed					=	#( \
																		#(), 	-- 1
																		#(), 	-- 2
																		#(), 	-- 3
																		#(), 	-- 4
																		#() 	-- 5 MaterialRef
																		)
																		
					g_cdf_xmlB_MatNodesSet 			= #()
																
					inst_LOADED 							= LOADED()
					inst_xmlB_LOADED 					= xmlB_LOADED()

					_LOADED 								= unsupplied
					_LOADEDm 								= unsupplied
					
					::g_inst_CDF_Attribs					= #()
					::g_inst_CHRPARAMS_Attribs 		= #()
					--/////////////////////////////////////////////////////////
					
					--//////////////////////////////////////////////////////////////////////////////////
					setINISetting 	::g_iniFile 	"paths" ("g_cryFile"+(getFilenameType g_cryFile)) 	::g_cryFile
					
					if (stricmp (getFilenameType g_cryFile) ".cdf") == 0 then
					(
						setINISetting 	::g_iniFile 	"paths" ("CDF_load") 										::g_cryFile --we will use this for loading the material xmlB
					)
					else if (stricmp (getFilenameType g_cryFile) ".chrparams") == 0 then
					(
						setINISetting 	::g_iniFile 	"paths" ("CHRPARAMS_load") 								::g_cryFile --we will use this for loading the material xmlB
					)
					
					inst_s_OPTIONS = s_OPTIONS()	--create instance			
					if ::g_dds then
					(
						inst_s_OPTIONS.chk_dds = ::g_dds 		
					)

					inst_xmlB_PROCESSOR = xmlB_PROCESSOR()
					
					if ::g_xmlB_Report 						then 	( inst_xmlB_PROCESSOR.report 							= true )				
					if ::g_xmlB_Debug_Report				then 	( inst_xmlB_PROCESSOR.xmlB_Debug_Report 		= true )
					if ::g_Build_Material_Report 			then 	( inst_xmlB_PROCESSOR.Build_Material_Report 		= true )	
					if ::g_skip_Lod_Materials				then 	( inst_xmlB_PROCESSOR.skip_Lod_Materials 			= true )	
					if ::g_xmlB_Report_v2					then 	( inst_xmlB_PROCESSOR.xmlB_Report_v2 				= true )

					--CDF
					if (stricmp (getFilenameType g_cryFile) ".cdf" ) == 0 OR \
						(stricmp (getFilenameType g_cryFile) ".chrparams" ) == 0 then --Character Definition File .cdf or .chrparams
					(
						----------------------------------- Load CDF Assets -----------------------------------
						LOAD_CDF_ASSETS \
													inst_xmlB_PROCESSOR:		inst_xmlB_PROCESSOR \
													g_cryFile:						::g_cryFile \
													inst_s_OPTIONS:				inst_s_OPTIONS
						-------------------------------------------------------------------------------------------				
					)
				)
			)
		)
	)	
)
