From 2a0d506f51de73ec8b3ab449f1ef52700ae2c91c Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Sun, 27 May 2007 02:27:18 +0000
Subject: [PATCH] Finished new MatTexCollection helper class which makes it
 possible to manipulate material properties and texture objects with the same
 classes regardless of the intended NIF version. Realized that only read was
 implemented for files with version < 3.3.0.13, so implemented write for those
 old versions as well.

---
 include/MatTexCollection.h                   | 335 ++++++++++
 include/NIF_IO.h                             |  48 ++
 include/gen/enums.h                          |   7 +-
 include/obj/NiAlphaProperty.h                |  38 +-
 include/obj/NiSpecularProperty.h             |  12 +
 niflib.vcproj                                |   4 +-
 src/MatTexCollection.cpp                     | 619 +++++++++++++++++++
 src/NIF_IO.cpp                               |   6 +-
 src/gen/Footer.cpp                           |  13 +-
 src/gen/enums.cpp                            |   5 +-
 src/niflib.cpp                               |  75 ++-
 src/obj/AParticleModifier.cpp                |  26 +-
 src/obj/BSKeyframeController.cpp             |  13 +-
 src/obj/FxRadioButton.cpp                    |  13 +-
 src/obj/NiAVObject.cpp                       |  26 +-
 src/obj/NiAlphaController.cpp                |  13 +-
 src/obj/NiAlphaProperty.cpp                  |  30 +-
 src/obj/NiBSplineInterpolator.cpp            |  26 +-
 src/obj/NiBinaryVoxelExtraData.cpp           |  13 +-
 src/obj/NiBoneLODController.cpp              |  52 +-
 src/obj/NiBoolInterpolator.cpp               |  13 +-
 src/obj/NiCamera.cpp                         |  13 +-
 src/obj/NiCollisionObject.cpp                |  26 +-
 src/obj/NiControllerManager.cpp              |  26 +-
 src/obj/NiControllerSequence.cpp             |  39 +-
 src/obj/NiDefaultAVObjectPalette.cpp         |  13 +-
 src/obj/NiDynamicEffect.cpp                  |  13 +-
 src/obj/NiExtraData.cpp                      |  13 +-
 src/obj/NiFlipController.cpp                 |  26 +-
 src/obj/NiFloatInterpolator.cpp              |  13 +-
 src/obj/NiGeomMorpherController.cpp          |  26 +-
 src/obj/NiGeometry.cpp                       |  39 +-
 src/obj/NiGeometryData.cpp                   |  13 +-
 src/obj/NiImage.cpp                          |  13 +-
 src/obj/NiKeyframeController.cpp             |  13 +-
 src/obj/NiLODNode.cpp                        |  13 +-
 src/obj/NiLookAtController.cpp               |  13 +-
 src/obj/NiLookAtInterpolator.cpp             |  52 +-
 src/obj/NiMeshPSysData.cpp                   |  39 +-
 src/obj/NiMultiTargetTransformController.cpp |  13 +-
 src/obj/NiMultiTextureProperty.cpp           |  13 +-
 src/obj/NiNode.cpp                           |  26 +-
 src/obj/NiObjectNET.cpp                      |  39 +-
 src/obj/NiPSysAgeDeathModifier.cpp           |  13 +-
 src/obj/NiPSysBombModifier.cpp               |  13 +-
 src/obj/NiPSysCollider.cpp                   |  52 +-
 src/obj/NiPSysColliderManager.cpp            |  13 +-
 src/obj/NiPSysColorModifier.cpp              |  13 +-
 src/obj/NiPSysDragModifier.cpp               |  13 +-
 src/obj/NiPSysEmitterCtlr.cpp                |  26 +-
 src/obj/NiPSysGravityModifier.cpp            |  13 +-
 src/obj/NiPSysMeshEmitter.cpp                |  13 +-
 src/obj/NiPSysMeshUpdateModifier.cpp         |  13 +-
 src/obj/NiPSysModifier.cpp                   |  13 +-
 src/obj/NiPSysModifierActiveCtlr.cpp         |  13 +-
 src/obj/NiPSysModifierFloatCtlr.cpp          |  13 +-
 src/obj/NiPSysVolumeEmitter.cpp              |  13 +-
 src/obj/NiParticleColorModifier.cpp          |  13 +-
 src/obj/NiParticleMeshModifier.cpp           |  13 +-
 src/obj/NiParticleMeshesData.cpp             |  13 +-
 src/obj/NiParticleSystem.cpp                 |  13 +-
 src/obj/NiParticleSystemController.cpp       |  65 +-
 src/obj/NiPathController.cpp                 |  26 +-
 src/obj/NiPathInterpolator.cpp               |  26 +-
 src/obj/NiPixelData.cpp                      |  13 +-
 src/obj/NiPoint3InterpController.cpp         |  13 +-
 src/obj/NiPoint3Interpolator.cpp             |  13 +-
 src/obj/NiRollController.cpp                 |  13 +-
 src/obj/NiSequence.cpp                       |  78 ++-
 src/obj/NiSingleInterpController.cpp         |  13 +-
 src/obj/NiSkinData.cpp                       |  13 +-
 src/obj/NiSkinInstance.cpp                   |  52 +-
 src/obj/NiSourceTexture.cpp                  |  26 +-
 src/obj/NiSpecularProperty.cpp               |   8 +
 src/obj/NiTextureEffect.cpp                  |  13 +-
 src/obj/NiTextureProperty.cpp                |  13 +-
 src/obj/NiTextureTransformController.cpp     |  13 +-
 src/obj/NiTexturingProperty.cpp              | 143 +++--
 src/obj/NiTimeController.cpp                 |  26 +-
 src/obj/NiTransformInterpolator.cpp          |  13 +-
 src/obj/NiTriShapeSkinController.cpp         |  13 +-
 src/obj/NiUVController.cpp                   |  13 +-
 src/obj/NiVisController.cpp                  |  13 +-
 src/obj/bhkConstraint.cpp                    |  13 +-
 src/obj/bhkListShape.cpp                     |  13 +-
 src/obj/bhkMalleableConstraint.cpp           |  26 +-
 src/obj/bhkMoppBvTreeShape.cpp               |  13 +-
 src/obj/bhkNiTriStripsShape.cpp              |  13 +-
 src/obj/bhkPackedNiTriStripsShape.cpp        |  13 +-
 src/obj/bhkRigidBody.cpp                     |  13 +-
 src/obj/bhkTransformShape.cpp                |  13 +-
 src/obj/bhkWorldObject.cpp                   |  13 +-
 92 files changed, 2312 insertions(+), 604 deletions(-)
 create mode 100644 include/MatTexCollection.h
 create mode 100644 src/MatTexCollection.cpp

diff --git a/include/MatTexCollection.h b/include/MatTexCollection.h
new file mode 100644
index 00000000..4f9d57c3
--- /dev/null
+++ b/include/MatTexCollection.h
@@ -0,0 +1,335 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _MATERIAL_COLLECTION_H_
+#define _MATERIAL_COLLECTION_H_
+
+#include "Ref.h"
+#include "gen/enums.h"
+#include "dll_export.h"
+#include "nif_versions.h"
+#include <vector>
+#include <string>
+
+namespace Niflib {
+
+using namespace std;
+
+const unsigned int NO_MATERIAL = 0xFFFFFFFF;
+const unsigned int NO_TEXTURE = 0xFFFFFFFF;
+
+class MaterialWrapper;
+class TextureWrapper;
+
+class NiProperty;
+class NiSpecularProperty;
+class NiAlphaProperty;
+class NiGeometry;
+class NiAVObject;
+class NiMaterialProperty;
+class NiTexturingProperty;
+class NiTextureProperty;
+class NiMultiTextureProperty;
+class NiSourceTexture;
+class NiImage;
+
+/*!
+ * A helper class used to gather and create material and texturing information
+ * in a NIF version independant way.
+ */
+class MatTexCollection {
+public:
+
+	/*
+	 * Constructor which optionally allows you to specify the root of a scene
+	 * to gather material information from.  This is equivalent to creating the
+	 * object and then calling the GatherMaterials function as a separate step.
+	 * \param[in] scene_root The root node of the scene to gather material
+	 * information from.  If set to NULL (the default) no information will be
+	 * gathered.
+	 */
+	NIFLIB_API MatTexCollection( NiAVObject * scene_root = NULL );
+
+	/*! Destructor */
+	NIFLIB_API ~MatTexCollection();
+
+	/*
+	 * This function gathers material data from the objects in the scene graph
+	 * rooted by the given AV object.  This will create associations between
+	 * the material and texturing properties and the objects that use them,
+	 * which then can be browsed or searched using the collection's other functions.
+	 * \param[in] scene_root The root node of the scene to gather material
+	 * information from.
+	 */
+	NIFLIB_API void GatherMaterials( NiAVObject * scene_root );
+
+	/*!
+	 * Clears all materials and textures stored in this collection.
+	 */
+	NIFLIB_API void Clear();
+
+	/*
+	 * Reports the number of materials indexed by this collection.
+	 * \return The number of materials for which data have been gathered in this
+	 * collection.
+	 */
+	NIFLIB_API unsigned int GetNumMaterials();
+
+	/*
+	 * Retrieves a specific material wrapper by index.  This is a class which
+	 * allows the attributes of the material and texturing properties to be
+	 * manipulated.
+	 * \param[in] index The index of the material wrapper to retrieve.  Must
+	 * be less than the number reported by GetNumMaterials.
+	 * \return The material wrapper stored at the specified index.
+	 */
+	NIFLIB_API MaterialWrapper GetMaterial( unsigned int index );
+
+	/*
+	 * Reports the number of textures indexed by this collection.
+	 * \return The number of textures for which data have been gathered in this
+	 * collection.
+	 */
+	NIFLIB_API unsigned int GetNumTextures();
+
+	/*
+	 * Retrieves a specific texture wrapper by index.  This is a class which
+	 * allows the attributes of the texture to be manipulated.
+	 * \param[in] index The index of the texture wrapper to retrieve.  Must
+	 * be less than the number reported by GetNumTextures.
+	 * \return The texture wrapper stored at the specified index.
+	 */
+	NIFLIB_API TextureWrapper GetTexture( unsigned int index );
+
+	/*
+	 * Retrieves the texture index of the texture wrapper that encloses the
+	 * specified NiSouceTexture, if any.
+	 * \param[in] src_tex The NiSourceTexture property to match in the search.
+	 * \return The index of the matching texture, or NO_TEXTURE if a match is
+	 * not found.
+	 */
+	NIFLIB_API unsigned int GetTextureIndex( NiSourceTexture * src_tex );
+
+	/*
+	 * Retrieves the texture index of the texture wrapper that encloses the
+	 * specified NiImage, if any.
+	 * \param[in] image The NiImage property to match in the search.
+	 * \return The index of the matching texture, or NO_TEXTURE if a match is
+	 * not found.
+	 */
+	NIFLIB_API unsigned int GetTextureIndex( NiImage * image );
+
+	/*!
+	 * Creates a new material and adds it to the end of the array of materials
+	 * contained in this collection with an internal format matching the version
+	 * number specified.
+	 * \param[in] version The NIF version to target when creating the underlying NIF
+	 * objects that store the texture data.
+	 * \return The index of the newly created texture.
+	 */
+	NIFLIB_API unsigned int CreateTexture( unsigned int version = VER_4_0_0_2 );
+
+	/*
+	 * Retrieves the material index of the material that affects a specified
+	 * NiAVObject, if any.
+	 * \param[in] obj The AV object to find the material index for.
+	 * \return The index of the material that affects the specified object or
+	 * NO_MATERIAL if no match is found.
+	 */
+	NIFLIB_API unsigned int GetMaterialIndex( NiAVObject * obj );
+
+	/*
+	 * Retrieves the material index of the material that matches the given list
+	 * of properties, if any.
+	 * \param[in] mat The NiMaterialProperty to match.
+	 * \param[in] texing The NiTexturingProperty to match.
+	 * \param[in] tex The NiTextureProperty to match.
+	 * \param[in] multi The NiMultiTextureProperty to match.
+	 * \return The index of the material that matches the specified properties,
+	 * or NO_MATERIAL if no match is found.
+	 */
+	NIFLIB_API unsigned int GetMaterialIndex( NiMaterialProperty * mat, NiTexturingProperty * texing, NiTextureProperty * tex, NiMultiTextureProperty * multi, NiSpecularProperty * spec, NiAlphaProperty * alpha );
+
+	/*
+	 * Retrieves the material index of the material that matches the given list
+	 * of properties, if any.
+	 * \param[in] properties An unsorted list of properties that is thought to contain some related to materials.
+	 * \return The index of the material that matches the given properties,
+	 * or NO_MATERIAL if no match is found.
+	 */
+	NIFLIB_API unsigned int GetMaterialIndex( const vector< Ref<NiProperty> > & properties );
+
+	/*
+	 * Creates a new material and adds it to the end of the array of materials
+	 * contained in this collection.  The type of material data that will
+	 * appear in the new material must be specified, and a version number can be
+	 * used to determine how the data will be stored in the eventual NIF file.
+	 * Note that the multi_tex option is only a suggestion, as later NIF versions
+	 * combine the texture and multi-texture data into one NIF object.
+	 * \param[in] color Whether or not to include color data in the new
+	 * material.
+	 * \param[in] texture Whether or not to include base texture data in the
+	 * new material.
+	 * \param[in] multi_tex Whether or not to include multi-texture data in the
+	 * new material.
+	 * \param[in] multi_tex Whether or not to include multi-texture data in the
+	 * new material.  This is only a suggestion as some NIF versions cannot
+	 * separate this from base texture information.
+	 * \param[in] specular Whether or not to include specular lighting data in
+	 * the new material.
+	 * \param[in] translucenty Whether or not to include alpha translucenty
+	 * data in the new material.
+	 * \param[in] version The NIF version to target when creating the underlying NIF
+	 * objects that store the requested types of data.
+	 * \return The index of the newly created material.
+	 */
+	NIFLIB_API unsigned int CreateMaterial( bool color, bool texture, bool multi_tex, bool specular, bool translucenty, unsigned int version = VER_4_0_0_2 );
+private:
+	/*! The vector of materials that this collection holds. */
+	vector<MaterialWrapper> materials;
+	/*! The vector of textures that this collection holds. */
+	vector<TextureWrapper> textures;
+};
+
+class MaterialWrapper {
+public:
+	/*! NIFLIB_HIDDEN function.  For internal use only. */
+	NIFLIB_HIDDEN MaterialWrapper( NiMaterialProperty * mat, NiTexturingProperty * texing, NiTextureProperty * tex, NiMultiTextureProperty * multi, NiSpecularProperty * spec, NiAlphaProperty * alpha, MatTexCollection * creator );
+	/*! NIFLIB_HIDDEN function.  For internal use only. */
+	NIFLIB_API ~MaterialWrapper();
+
+	/*!
+	 *	Applies the material and texture properties controlled by this wrapper
+	 * to the specified AV object.  Note that properties affect any child
+	 * objects in the scene graph as well.
+	 * \param[in] target The AV object to apply the material and texture
+	 * properties to.
+	 */
+	NIFLIB_API void ApplyToObject( NiAVObject * target );
+
+	/*!
+	 * Returns a list of all the properties stored in this material wrapper.
+	 * \return All the properties controlled by this wrapper.
+	 */
+	NIFLIB_API vector< Ref<NiProperty> > GetProperties();
+
+	//--Color Functions--//
+
+	/*!
+	 * This function simply returns a reference to the NiMaterialProperty that
+	 * this wrapper uses to store color information, if any.  Since all
+	 * supported NIF versions currently use the same material property object,
+	 * these funtions are not wrapped.
+	 * \return The material property that this wrapper uses to store color
+	 * information, or NULL if there is no color information stored.
+	 */
+	NIFLIB_API Ref<NiMaterialProperty> GetColorInfo();
+
+	/*!
+	 * This function simply returns a reference to the NiSpecularProperty that
+	 * this wrapper uses to store specular information, if any.  Since all
+	 * supported NIF versions currently use the same specular property object,
+	 * these funtions are not wrapped.
+	 * \return The specular property that this wrapper uses to specular
+	 * information, or NULL if there is no specular information stored.
+	 */
+	NIFLIB_API Ref<NiSpecularProperty> GetSpecularInfo();
+
+	/*!
+	 * This function simply returns a reference to the NiAlphaProperty that
+	 * this wrapper uses to store translucency information, if any.  Since all
+	 * supported NIF versions currently use the same alpha property object,
+	 * these funtions are not wrapped.
+	 * \return The alpha property that this wrapper uses to store translucency
+	 * information, or NULL if there is no translucency information stored.
+	 */
+	NIFLIB_API Ref<NiAlphaProperty> GetTranslucencyInfo();
+
+
+	//--Texturing Functions--//
+
+	NIFLIB_API bool HasTexture( TexType tex );
+
+	/*
+	 * Retrieves the texture index of the texture that is used by the specified
+	 * texture slot.
+	 * \param[in] slot The type of texture slot to get the texture index of.
+	 * \return The index of the texture used by the specified material at the
+	 * given slot, or NO_TEXTURE if no match is found.
+	 */
+	NIFLIB_API unsigned int GetTextureIndex( TexType slot );
+
+	NIFLIB_API void SetTextureIndex( TexType slot, unsigned int tex_index );
+
+	NIFLIB_API unsigned int GetTexUVSetIndex( TexType tex );
+
+	NIFLIB_API void SetTexUVSetIndex( TexType tex, unsigned int uv_set );
+
+	NIFLIB_API TexClampMode GetTexClampMode( TexType tex );
+
+	NIFLIB_API void SetTexClampMode( TexType tex, TexClampMode mode );
+
+	NIFLIB_API TexFilterMode GetTexFilterMode( TexType tex );
+
+	NIFLIB_API void SetTexFilterMode( TexType tex, TexFilterMode mode );
+
+private:
+	friend class MatTexCollection;
+
+	/*! The NiMaterialProperty that this object wraps, if any. */
+	Ref<NiMaterialProperty> mat_prop;
+	/*! The NiTexturingProperty that this object wraps, if any. */
+	Ref<NiTexturingProperty> texing_prop;
+	/*! The NiTextureProperty that this object wraps, if any. */
+	Ref<NiTextureProperty> tex_prop;
+	/*! The NiMultiTextureProperty that this object wraps, if any. */
+	Ref<NiMultiTextureProperty> multi_prop;
+	/*! The NiSpecularProperty that this object wraps, if any. */
+	Ref<NiSpecularProperty> spec_prop;
+	/*! The NiAlphaProperty that this object wraps, if any. */
+	Ref<NiAlphaProperty> alpha_prop;
+	/*! A pointer back to the MatTexCollection that created this wrapper */
+	MatTexCollection * _creator;
+};
+
+class TextureWrapper {
+public:
+	NIFLIB_HIDDEN TextureWrapper( NiSourceTexture * src );
+	NIFLIB_HIDDEN TextureWrapper( NiImage * img );
+	NIFLIB_API ~TextureWrapper();
+
+	NIFLIB_API bool IsTextureExternal();
+
+	NIFLIB_API string GetTextureFileName();
+
+	NIFLIB_API void SetExternalTexture( const string & file_name );
+
+	NIFLIB_API PixelLayout GetPixelLayout();
+
+	NIFLIB_API void SetPixelLayout( PixelLayout layout );
+
+	NIFLIB_API MipMapFormat GetMipMapFormat();
+
+	NIFLIB_API void SetMipMapFormat( MipMapFormat format );
+
+	NIFLIB_API AlphaFormat GetAlphaFormat();
+
+	NIFLIB_API void SetAlphaFormat( AlphaFormat format );
+
+	NIFLIB_API string GetObjectName();
+
+	NIFLIB_API void SetObjectName( const string & name );
+
+private:
+	friend class MatTexCollection;
+	friend class MaterialWrapper;
+
+	/*! The NiSourceTexture that this object wraps, if any. */
+	Ref<NiSourceTexture> src_tex;
+	/*! The NiImage that this object wraps, if any. */
+	Ref<NiImage> image;
+};
+
+} //End namspace Niflib
+
+#endif
\ No newline at end of file
diff --git a/include/NIF_IO.h b/include/NIF_IO.h
index 887889ad..898ac3b3 100644
--- a/include/NIF_IO.h
+++ b/include/NIF_IO.h
@@ -43,6 +43,54 @@ void WriteFloat( float val, ostream& out );
 void WriteString( string const & val, ostream& out );
 void WriteBool( bool val, ostream& out, unsigned int version );
 
+//-- BitField Helper functions --//
+
+template <class storage>
+bool UnpackFlag( storage src, size_t lshift ) {
+	//Generate mask
+	storage mask = 1 << lshift;
+
+	return (( src & mask) << lshift) != 0;
+}
+
+template <class storage>
+void PackFlag( storage & dest, bool new_value, size_t lshift ) {
+	//Generate mask
+	storage mask = 1 << lshift;
+
+	//Clear current value of requested flag
+	dest &= ~mask;
+
+	//Pack in the new value
+	dest |= ( ((storage)new_value << lshift) & mask );
+}
+
+template <class storage>
+storage UnpackField( storage src, size_t lshift, size_t num_bits ) {
+	//Generate mask
+	storage mask = 0;
+	for ( size_t i = lshift; i < num_bits + lshift; ++i ) {
+		mask |= (1 << i);
+	}
+
+	return (storage)(( src & mask) << lshift);
+}
+
+template <class storage, class T>
+void PackField( storage & dest, T new_value, size_t lshift, size_t num_bits ) {
+	//Generate Mask
+	storage mask = 0;
+	for ( size_t i = lshift; i < num_bits + lshift; ++i ) {
+		mask |= (1 << i);
+	}
+
+	//Clear current value of requested field
+	dest &= ~mask;
+
+	//Pack in the new value
+	dest |= ( ((storage)new_value << lshift) & mask );
+}
+
 //-- NifStream And ostream Functions --//
 // The NifStream functions allow each built-in type to be streamed to and from a file.
 // The ostream functions are for writing out a debug string.
diff --git a/include/gen/enums.h b/include/gen/enums.h
index 38f4923d..39fd11ee 100644
--- a/include/gen/enums.h
+++ b/include/gen/enums.h
@@ -63,10 +63,11 @@ enum CompareMode {
 	TEST_NEVER = 0, /*!< Test will allways return false. Nothing is drawn at all. */
 	TEST_LESS = 1, /*!< The test will only succeed if the pixel is nearer than the previous pixel. */
 	TEST_EQUAL = 2, /*!< Test will only succeed if the z value of the pixel to be drawn is equal to the value of the previous drawn pixel. */
-	TEST_LESSEQUAL = 3, /*!< Test will succeed if the z value of the pixel to be drawn is smaller than or equal to the value in the Z Buffer. */
+	TEST_LESS_EQUAL = 3, /*!< Test will succeed if the z value of the pixel to be drawn is smaller than or equal to the value in the Z Buffer. */
 	TEST_GREATER = 4, /*!< Opposite of TEST_LESS. */
-	TEST_GREATEREQUAL = 5, /*!< Opposite of TEST_LESSEQUAL. */
-	TEST_ALWAYS = 6, /*!< Test will allways succeed. The Z Buffer value is ignored. */
+	TEST_NOT_EQUAL = 5, /*!< Test will succeed if the z value of the pixel to be drawn is NOT equal to the value of the previously drawn pixel. */
+	TEST_GREATER_EQUAL = 6, /*!< Opposite of TEST_LESS_EQUAL. */
+	TEST_ALWAYS = 7, /*!< Test will allways succeed. The Z Buffer value is ignored. */
 };
 
 ostream & operator<<( ostream & out, CompareMode const & val );
diff --git a/include/obj/NiAlphaProperty.h b/include/obj/NiAlphaProperty.h
index 83ab3982..7338592f 100644
--- a/include/obj/NiAlphaProperty.h
+++ b/include/obj/NiAlphaProperty.h
@@ -56,29 +56,29 @@ public:
 
 	/*! Used to specify the source and destination blending functions.  The function of each value is equivalent to the OpenGL blending function of similar name. */
 	enum BlendFunc {
-		BF_ONE = 0x00, 
-		BF_ZERO = 0x01,
-		BF_SRC_COLOR = 0x02,
-		BF_ONE_MINUS_SRC_COLOR = 0x03,
-		BF_DST_COLOR = 0x04,
-		BF_ONE_MINUS_DST_COLOR = 0x05,
-		BF_SRC_ALPHA = 0x06,
-		BF_ONE_MINUS_SRC_ALPHA = 0x07,
-		BF_DST_ALPHA = 0x08,
-		BF_ONE_MINUS_DST_ALPHA = 0x08,
-		BF_SRC_ALPHA_SATURATE = 0x09,
+		BF_ONE = 0, 
+		BF_ZERO = 1,
+		BF_SRC_COLOR = 2,
+		BF_ONE_MINUS_SRC_COLOR = 3,
+		BF_DST_COLOR = 4,
+		BF_ONE_MINUS_DST_COLOR = 5,
+		BF_SRC_ALPHA = 6,
+		BF_ONE_MINUS_SRC_ALPHA = 7,
+		BF_DST_ALPHA = 8,
+		BF_ONE_MINUS_DST_ALPHA = 9,
+		BF_SRC_ALPHA_SATURATE = 10
 	};
 
 	/*! Used to set the alpha test function.  The function of each value is equivalent to the OpenGL test function of similar name. */
 	enum TestFunc {
-		TF_ALWAYS = 0x00,
-		TF_LESS = 0x01,
-		TF_EQUAL = 0x02,
-		TF_LEQUAL = 0x03,
-		TF_GREATER = 0x04,
-		TF_NOTEQUAL = 0x05,
-		TF_GEQUAL = 0x06,
-		TF_NEVER = 0x07,
+		TF_ALWAYS = 0,
+		TF_LESS = 1,
+		TF_EQUAL = 2,
+		TF_LEQUAL = 3,
+		TF_GREATER = 4,
+		TF_NOTEQUAL = 5,
+		TF_GEQUAL = 6,
+		TF_NEVER = 7
 	};
 
 	/*!
diff --git a/include/obj/NiSpecularProperty.h b/include/obj/NiSpecularProperty.h
index 69c27c5e..80477773 100644
--- a/include/obj/NiSpecularProperty.h
+++ b/include/obj/NiSpecularProperty.h
@@ -54,6 +54,18 @@ public:
 
 	//--BEGIN MISC CUSTOM CODE--//
 
+	/*!
+	 * Used to check whether this specular proprety enables or disables specular lighting.
+	 * \return True if this property enables specular lighting, false if it disables it.
+	 */
+	NIFLIB_API bool GetSpecularState() const;
+
+	/*!
+	 * Used to set whether this specular property enables or disables specular lighting.
+	 * \param[in] n True to enable specular lighting with this property, false to disable it.
+	 */
+	NIFLIB_API void SetSpecularState( bool n );
+
 	/*!
 	 * Can be used to get the data stored in the flags field for this object.  It is usually better to call more specific flag-toggle functions if they are availiable.
 	 * \return The flag data.
diff --git a/niflib.vcproj b/niflib.vcproj
index ab6bc6a2..157a77ac 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -314,7 +314,7 @@
 				>
 			</File>
 			<File
-				RelativePath=".\src\MaterialCollection.cpp"
+				RelativePath=".\src\MatTexCollection.cpp"
 				>
 			</File>
 			<File
@@ -1556,7 +1556,7 @@
 				>
 			</File>
 			<File
-				RelativePath=".\include\MaterialCollection.h"
+				RelativePath=".\include\MatTexCollection.h"
 				>
 			</File>
 			<File
diff --git a/src/MatTexCollection.cpp b/src/MatTexCollection.cpp
new file mode 100644
index 00000000..29b70236
--- /dev/null
+++ b/src/MatTexCollection.cpp
@@ -0,0 +1,619 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "MatTexCollection.h"
+#include "obj/NiGeometry.h"
+#include "obj/NiAVObject.h"
+#include "obj/NiNode.h"
+#include "obj/NiMaterialProperty.h"
+#include "obj/NiTexturingProperty.h"
+#include "obj/NiTextureProperty.h"
+#include "obj/NiMultiTextureProperty.h"
+#include "obj/NiSpecularProperty.h"
+#include "obj/NiAlphaProperty.h"
+#include "obj/NiSourceTexture.h"
+#include "obj/NiImage.h"
+
+namespace Niflib {
+
+MatTexCollection::MatTexCollection( NiAVObject * scene_root ) {
+	if ( scene_root != NULL ) {
+		GatherMaterials( scene_root );
+	}
+}
+
+MatTexCollection::~MatTexCollection() {}
+
+void MatTexCollection::GatherMaterials( NiAVObject * scene_root ) {	
+	if ( scene_root == NULL ) {
+		throw runtime_error( "MatTexCollection::GatherMaterials was called on a NULL scene root." );
+	}
+
+	//Check and see if this object is a geometry object
+	if ( scene_root->IsDerivedType( NiGeometry::TYPE ) ) {
+
+		//Check and see if this geometry's unique combination of material and texture properties has already been found
+		if ( GetMaterialIndex( scene_root ) == NO_MATERIAL ) {
+			//Material was not already found.  Look for material/texture related properties.
+			NiPropertyRef mat = scene_root->GetPropertyByType( NiMaterialProperty::TYPE );
+			NiPropertyRef texing = scene_root->GetPropertyByType( NiTexturingProperty::TYPE );
+			NiPropertyRef tex = scene_root->GetPropertyByType( NiTextureProperty::TYPE );
+			NiPropertyRef multi = scene_root->GetPropertyByType( NiMultiTextureProperty::TYPE );
+			NiPropertyRef spec = scene_root->GetPropertyByType( NiSpecularProperty::TYPE );
+			NiPropertyRef alpha = scene_root->GetPropertyByType( NiAlphaProperty::TYPE );
+
+			//Make sure at least one isn't NULL
+			if ( mat != NULL || texing != NULL || tex != NULL || multi != NULL ) {
+				//One isn't NULL, so create a new Material
+
+				NiMaterialPropertyRef matC = DynamicCast<NiMaterialProperty>(mat);
+				NiTexturingPropertyRef texingC = DynamicCast<NiTexturingProperty>(texing);
+				NiTexturePropertyRef texC = DynamicCast<NiTextureProperty>(tex);
+				NiMultiTexturePropertyRef multiC = DynamicCast<NiMultiTextureProperty>(multi);
+				NiSpecularPropertyRef specC = DynamicCast<NiSpecularProperty>(spec);
+				NiAlphaPropertyRef alphaC = DynamicCast<NiAlphaProperty>(alpha);
+
+				//First, check if the material's textures have been found yet
+
+				if ( texingC != NULL ) {
+					for ( int i = 0; i < 8; ++i ) {
+						if ( texingC->HasTexture(i) ) {
+							TexDesc td = texingC->GetTexture(i);
+							if ( td.source != NULL ) {
+								unsigned int index = GetTextureIndex( td.source );
+								if ( index == NO_TEXTURE ) {
+									//Texture has not yet been found.  Create a new one.
+									textures.push_back( TextureWrapper( td.source ) );
+								}
+							}
+						}
+					}
+				} else if ( texC != NULL ) {
+					NiImageRef image = texC->GetImage();
+					if ( image != NULL ) {
+						unsigned int index = GetTextureIndex( image );
+						if ( index == NO_TEXTURE ) {
+							//Texture has not yet been found.  Create a new one.
+							textures.push_back( TextureWrapper( image ) );
+						}
+					}
+				}
+
+				//TODO: Implement this for NiMultiTextureProperty as well
+
+
+				materials.push_back( MaterialWrapper( matC, texingC, texC, multiC, specC, alphaC, this ) );
+			}
+		}
+		//Done with this branch, so return.
+		return;
+	}
+
+	//If this object is a NiNode, then call this function on its children
+	NiNodeRef node = DynamicCast<NiNode>(scene_root);
+	if ( node != NULL ) {
+		vector<NiAVObjectRef> children = node->GetChildren();
+
+		for ( size_t i = 0; i < children.size(); ++i ) {
+			GatherMaterials( children[i] );
+		}
+	}
+
+}
+
+void MatTexCollection::Clear() {
+	materials.clear();
+	textures.clear();
+}
+
+unsigned int MatTexCollection::GetNumMaterials() {
+	return materials.size();
+}
+
+unsigned int MatTexCollection::GetNumTextures() {
+	return textures.size();
+}
+
+MaterialWrapper MatTexCollection::GetMaterial( unsigned int index ) {
+	if ( index >= materials.size() ) {
+		throw runtime_error("The index passed to MatTexCollection::GetMaterial was out of range.");
+	}
+
+	return materials[index];
+}
+
+TextureWrapper MatTexCollection::GetTexture( unsigned int index ) {
+	if ( index >= textures.size() ) {
+		throw runtime_error("The index passed to MatTexCollection::GetTexture was out of range.");
+	}
+
+	return textures[index];
+}
+	
+unsigned int MatTexCollection::GetMaterialIndex( NiAVObject * obj ) {
+	//Search for a material that matches the properties that the NiAVObject has.
+	vector< Ref<NiProperty> > properties = obj->GetProperties();
+
+	return GetMaterialIndex( properties );
+}
+
+unsigned int MatTexCollection::GetMaterialIndex( NiMaterialProperty * mat, NiTexturingProperty * texing, NiTextureProperty * tex, NiMultiTextureProperty * multi, NiSpecularProperty * spec, NiAlphaProperty * alpha ) {
+	for( size_t i = 0; i < materials.size(); ++i ) {
+		if ( materials[i].mat_prop == mat &&
+			 materials[i].texing_prop == texing &&
+			 materials[i].tex_prop == tex &&
+			 materials[i].multi_prop == multi &&
+			 materials[i].spec_prop == spec &&
+			 materials[i].alpha_prop == alpha ) {
+				 //Match found, return its index
+				 return i;
+		}
+	}
+
+	//No match was found, return NO_MATERIAL
+	return NO_MATERIAL;
+}
+
+unsigned int MatTexCollection::GetTextureIndex( NiSourceTexture * src_tex ) {
+	for( size_t i = 0; i < textures.size(); ++i ) {
+		if ( textures[i].src_tex == src_tex  ) {
+				 //Match found, return its index
+				 return i;
+		}
+	}
+
+	//No match was found, return NO_MATERIAL
+	return NO_TEXTURE;
+}
+
+unsigned int MatTexCollection::GetTextureIndex( NiImage * image ) {
+	for( size_t i = 0; i < textures.size(); ++i ) {
+		if ( textures[i].image == image  ) {
+				 //Match found, return its index
+				 return i;
+		}
+	}
+
+	//No match was found, return NO_MATERIAL
+	return NO_TEXTURE;
+}
+
+unsigned int MatTexCollection::GetMaterialIndex( const vector< Ref<NiProperty> > & properties ) {
+	//Get Material and Texturing properties, if any
+	NiMaterialPropertyRef mat = NULL;
+	NiTexturingPropertyRef texing = NULL;
+	NiTexturePropertyRef tex = NULL;
+	NiMultiTexturePropertyRef multi = NULL;
+	NiSpecularPropertyRef spec = NULL;
+	NiAlphaPropertyRef alpha = NULL;
+
+	for ( unsigned i = 0; i < properties.size(); ++i ) {
+		if ( properties[i]->IsDerivedType( NiMaterialProperty::TYPE ) ) {
+			mat = DynamicCast<NiMaterialProperty>( properties[i] );
+		} else if ( properties[i]->IsDerivedType( NiTexturingProperty::TYPE ) ) {
+			texing = DynamicCast<NiTexturingProperty>( properties[i] );
+		} else if ( properties[i]->IsDerivedType( NiTextureProperty::TYPE ) ) {
+			tex = DynamicCast<NiTextureProperty>( properties[i] );
+		} else if ( properties[i]->IsDerivedType( NiMultiTextureProperty::TYPE ) ) {
+			multi = DynamicCast<NiMultiTextureProperty>( properties[i] );
+		} else if ( properties[i]->IsDerivedType( NiSpecularProperty::TYPE ) ) {
+			spec = DynamicCast<NiSpecularProperty>( properties[i] );
+		} else if ( properties[i]->IsDerivedType( NiAlphaProperty::TYPE ) ) {
+			alpha = DynamicCast<NiAlphaProperty>( properties[i] );
+		}
+	}
+
+	//Do the search
+	return GetMaterialIndex( mat, texing, tex, multi, spec, alpha );
+}
+
+unsigned int MatTexCollection::CreateTexture( unsigned int version ) {
+	if ( version < VER_3_3_0_13 ) {
+		//Old image object style
+		NiImageRef image = new NiImage;
+
+		//Create texture wrapper and add it to the array
+		textures.push_back( TextureWrapper( image ) );
+	} else {
+		//New iamge object style
+		NiSourceTextureRef src_tex = new NiSourceTexture;
+
+		//Create texture wrapper and add it to the array
+		textures.push_back( TextureWrapper( src_tex ) );
+	}
+
+	//Return the index of the newly created texture
+	return textures.size() - 1;
+}
+
+unsigned int MatTexCollection::CreateMaterial( bool color, bool texture, bool multi_tex, bool specular, bool translucency, unsigned int version ) {
+	//Make sure at least one option is set to true
+	if ( color == false && texture == false && multi_tex == false && specular == false && translucency == false ) {
+		throw runtime_error( "At least one of the types of texture/material info needs to be stored in a new material.  All the argumetns to MatTexCollection::CreateMaterial cannot be false." );
+	}
+	
+	NiMaterialPropertyRef mat = NULL;
+	NiTexturingPropertyRef texing = NULL;
+	NiTexturePropertyRef tex = NULL;
+	NiMultiTexturePropertyRef multi = NULL;
+	NiSpecularPropertyRef spec = NULL;
+	NiAlphaPropertyRef alpha = NULL;
+
+	if ( color == true ) {
+		mat = new NiMaterialProperty;
+	}
+	if ( specular == true ) {
+		spec = new NiSpecularProperty;
+	}
+	if ( translucency == true ) {
+		alpha = new NiAlphaProperty;
+	}
+
+	if ( version < VER_3_3_0_13 ) {
+		//Old texturing property style
+		if ( texture == true ) {
+			tex = new NiTextureProperty;
+		}
+		if ( multi_tex == true ) {
+			multi = new NiMultiTextureProperty;
+		}
+	} else {
+		//New texturing property style
+		if ( texture == true ) {
+			texing = new NiTexturingProperty;
+		}
+	}
+
+	//Create Material and add it to the array
+	materials.push_back( MaterialWrapper( mat, texing, tex, multi, spec, alpha, this ) );
+
+	//Return the index of the newly created material
+	return materials.size() - 1;
+}
+
+//MaterialWrapper//////////////////////////////////////////////////////////////
+
+MaterialWrapper::MaterialWrapper( NiMaterialProperty * mat, NiTexturingProperty * texing, NiTextureProperty * tex, NiMultiTextureProperty * multi, NiSpecularProperty * spec, NiAlphaProperty * alpha, MatTexCollection * creator ) {
+	mat_prop = mat;
+	texing_prop = texing;
+	tex_prop = tex;
+	multi_prop = multi;
+	spec_prop = spec;
+	alpha_prop = alpha;
+	_creator = creator;
+}
+
+MaterialWrapper::~MaterialWrapper() {}
+
+void MaterialWrapper::ApplyToObject( NiAVObject * target ) {
+	//Add any non-NULL properties to the target object
+	if ( mat_prop != NULL ) {
+		target->AddProperty( mat_prop );
+	}
+	if ( texing_prop != NULL ) {
+		target->AddProperty( texing_prop );
+	}
+	if ( tex_prop != NULL ) {
+		target->AddProperty( tex_prop );
+	}
+	if ( multi_prop != NULL ) {
+		target->AddProperty( multi_prop );
+	}
+	if ( spec_prop != NULL ) {
+		target->AddProperty( spec_prop );
+	}
+	if ( alpha_prop != NULL ) {
+		target->AddProperty( alpha_prop );
+	}
+}
+
+vector< Ref<NiProperty> > MaterialWrapper::GetProperties() {
+	vector<NiPropertyRef> properties;
+	NiPropertyRef prop;
+
+	if ( mat_prop != NULL ) {
+		prop = StaticCast<NiProperty>(mat_prop);
+		properties.push_back(prop);
+	}
+	if ( texing_prop != NULL ) {
+		prop = StaticCast<NiProperty>(texing_prop);
+		properties.push_back(prop);
+	}
+	if ( tex_prop != NULL ) {
+		prop = StaticCast<NiProperty>(tex_prop);
+		properties.push_back(prop);
+	}
+	if ( multi_prop != NULL ) {
+		prop = StaticCast<NiProperty>(multi_prop);
+		properties.push_back(prop);
+	}
+	if ( spec_prop != NULL ) {
+		prop = StaticCast<NiProperty>(spec_prop);
+		properties.push_back(prop);
+	}
+	if ( alpha_prop != NULL ) {
+		prop = StaticCast<NiProperty>(alpha_prop);
+		properties.push_back(prop);
+	}
+
+	return properties;
+}
+
+
+//--Color Function--//
+
+Ref<NiMaterialProperty> MaterialWrapper::GetColorInfo() {
+	return mat_prop;
+}
+
+Ref<NiSpecularProperty> MaterialWrapper::GetSpecularInfo() {
+	return spec_prop;
+}
+
+Ref<NiAlphaProperty> MaterialWrapper::GetTranslucencyInfo() {
+	return alpha_prop;
+}
+
+//--Texture Functions--//
+
+bool MaterialWrapper::HasTexture( TexType tex ) {
+	if ( texing_prop != NULL ) {
+		return texing_prop->HasTexture( int(tex) );
+	}
+	if ( tex_prop != NULL && tex == BASE_MAP ) {
+		if ( tex_prop->GetImage() != NULL ) {
+			return true;
+		}
+	}
+	//TODO:  Figure out which slots are what in NiMultiTextureProperty so this can be implemented for that too
+
+	//Texture not found
+	return false;;
+}
+
+unsigned int MaterialWrapper::GetTextureIndex( TexType slot ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(slot) ) == false ) {
+			return NO_TEXTURE;
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(slot) );
+
+		if ( td.source == NULL ) {
+			return NO_TEXTURE;
+		}
+
+		return _creator->GetTextureIndex( td.source );
+	}
+	if ( tex_prop != NULL && slot == BASE_MAP ) {
+		NiImageRef img = tex_prop->GetImage();
+		if ( img == NULL ) {
+			return NO_TEXTURE;
+		}
+
+		return _creator->GetTextureIndex(img);
+
+	}
+	//TODO:  Figure out which slots are what in NiMultiTextureProperty so this can be implemented for that too
+
+	//Texture not found
+	return NO_TEXTURE;
+}
+
+void MaterialWrapper::SetTextureIndex( TexType slot, unsigned int tex_index ) {
+	//Get the texture from the creator.  This will cause an exception if it fails.
+	TextureWrapper tw = _creator->GetTexture(tex_index);
+	
+	if ( texing_prop != NULL ) {
+		TexDesc td;
+
+		td.source = tw.src_tex;
+
+		texing_prop->SetTexture( int(slot), td );
+	}
+	if ( tex_prop != NULL && slot == BASE_MAP ) {
+		tex_prop->SetImage( tw.image );
+	}
+	//TODO:  Figure out which slots are what in NiMultiTextureProperty so this can be implemented for that too
+}
+
+unsigned int MaterialWrapper::GetTexUVSetIndex( TexType tex ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(tex) ) == false ) {
+			throw runtime_error("The texture at the specified index does not exist.");
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(tex) );
+		return td.uvSet;
+	}
+
+	//Just return default value for now.  Not sure where this data may or may not be stored in the old style texture properties.
+	return 0;
+}
+
+void MaterialWrapper::SetTexUVSetIndex( TexType tex, unsigned int uv_set ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(tex) ) == false ) {
+			throw runtime_error("The texture at the specified index does not exist.");
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(tex) );
+		td.uvSet = uv_set;
+		texing_prop->SetTexture( int(tex), td );
+	}
+
+	//Just silently fail for now.  Not sure where this data may or may not be stored in the old style texture properties.
+}
+
+TexClampMode MaterialWrapper::GetTexClampMode( TexType tex ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(tex) ) == false ) {
+			throw runtime_error("The texture at the specified index does not exist.");
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(tex) );
+		return td.clampMode;
+	}
+
+	//Just return default value for now.  Not sure where this data may or may not be stored in the old style texture properties.
+	return WRAP_S_WRAP_T;
+}
+
+void MaterialWrapper::SetTexClampMode( TexType tex, TexClampMode mode ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(tex) ) == false ) {
+			throw runtime_error("The texture at the specified index does not exist.");
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(tex) );
+		td.clampMode = mode;
+		texing_prop->SetTexture( int(tex), td );
+	}
+
+	//Just silently fail for now.  Not sure where this data may or may not be stored in the old style texture properties.
+}
+
+TexFilterMode MaterialWrapper::GetTexFilterMode( TexType tex ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(tex) ) == false ) {
+			throw runtime_error("The texture at the specified index does not exist.");
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(tex) );
+		return td.filterMode;
+	}
+
+	//Just return default value for now.  Not sure where this data may or may not be stored in the old style texture properties.
+	return FILTER_BILERP;
+}
+
+void MaterialWrapper::SetTexFilterMode( TexType tex, TexFilterMode mode ) {
+	if ( texing_prop != NULL ) {
+		if ( texing_prop->HasTexture( int(tex) ) == false ) {
+			throw runtime_error("The texture at the specified index does not exist.");
+		}
+
+		TexDesc td = texing_prop->GetTexture( int(tex) );
+		td.filterMode = mode;
+		texing_prop->SetTexture( int(tex), td );
+	}
+
+	//Just silently fail for now.  Not sure where this data may or may not be stored in the old style texture properties.
+}
+
+///Texture Wrapper/////////////////////////////////////////////////////////////
+
+TextureWrapper::TextureWrapper( NiSourceTexture * src ) {
+	src_tex = src;
+}
+
+TextureWrapper::TextureWrapper( NiImage * img ) {
+	image = img;
+}
+
+TextureWrapper::~TextureWrapper() {}
+
+bool TextureWrapper::IsTextureExternal() {
+	if ( src_tex != NULL ) {
+		return src_tex->IsTextureExternal();
+	} else if ( image != NULL ) {
+		return image->IsTextureExternal();
+	} else {
+		//Texture not found
+		throw runtime_error("TextureWrapper holds no data.  This should not be able to happen.");
+	}
+}
+
+string TextureWrapper::GetTextureFileName() {
+	if ( src_tex != NULL ) {
+		return src_tex->GetTextureFileName();
+	} else if ( image != NULL ) {
+		return image->GetTextureFileName();
+	} else {
+		//Texture not found
+		throw runtime_error("TextureWrapper holds no data.  This should not be able to happen.");
+	}
+}
+
+void TextureWrapper::SetExternalTexture( const string & file_name ) {
+	if ( src_tex != NULL ) {
+		src_tex->SetExternalTexture( file_name );
+		return;
+	} else if ( image != NULL ) {
+		image->SetExternalTexture( file_name );
+
+	} else {
+		//Texture not found
+		throw runtime_error("TextureWrapper holds no data.  This should not be able to happen.");
+	}
+}
+
+PixelLayout TextureWrapper::GetPixelLayout() {
+	if ( src_tex != NULL ) {
+		return src_tex->GetPixelLayout();
+	}
+
+	//Just return default value for now.  Not sure where this data may or may not be stored in the old style image object.
+	return PIX_LAY_DEFAULT;
+}
+
+void TextureWrapper::SetPixelLayout( PixelLayout layout ) {
+	if ( src_tex != NULL ) {
+		src_tex->SetPixelLayout(layout);
+	}
+
+	//Just silently fail for now.  Not sure where this data may or may not be stored in the old style image object.
+}
+
+MipMapFormat TextureWrapper::GetMipMapFormat() {
+	if ( src_tex != NULL ) {
+		return src_tex->GetMipMapFormat();
+	}
+
+	//Just return default value for now.  Not sure where this data may or may not be stored in the old style image object.
+	return MIP_FMT_DEFAULT;
+}
+
+void TextureWrapper::SetMipMapFormat( MipMapFormat format ) {
+	if ( src_tex != NULL ) {
+		src_tex->SetMipMapFormat(format);
+	}
+
+	//Just silently fail for now.  Not sure where this data may or may not be stored in the old style image objects.
+}
+
+AlphaFormat TextureWrapper::GetAlphaFormat() {
+	if ( src_tex != NULL ) {
+		return src_tex->GetAlphaFormat();
+	}
+
+	//Just return default value for now.  Not sure where this data may or may not be stored in the old style image object.
+	return ALPHA_DEFAULT;
+}
+
+void TextureWrapper::SetAlphaFormat( AlphaFormat format ) {
+	if ( src_tex != NULL ) {
+		src_tex->SetAlphaFormat(format);
+	}
+
+	//Just silently fail for now.  Not sure where this data may or may not be stored in the old style image objects.
+}
+
+string TextureWrapper::GetObjectName() {
+	if ( src_tex != NULL ) {
+		return src_tex->GetName();
+	}
+
+	//NiImage objects don't seem to have a name since they derive from NiObject.  Return an empty string.
+	return string();
+}
+
+void TextureWrapper::SetObjectName( const string & name ) {
+	if ( src_tex != NULL ) {
+		src_tex->SetName( name );
+	}
+
+	//NiImage objects don't seem to have a name since they derive from NiObject.  Do nothing.
+}
+
+} //End namespace Niflib
\ No newline at end of file
diff --git a/src/NIF_IO.cpp b/src/NIF_IO.cpp
index fc91ae86..084b195c 100644
--- a/src/NIF_IO.cpp
+++ b/src/NIF_IO.cpp
@@ -383,11 +383,11 @@ void NifStream( HeaderString const & val, ostream& out, const NifInfo & info ) {
 	} else {
 		header_string << "Gamebryo File Format, Version ";
 	}
-	char * byte_ver = (char*)&(info.version);
-	int int_ver[4] = { byte_ver[3], byte_ver[2], byte_ver[1], byte_ver[0] };
 
+	header_string << FormatVersionString(info.version);
 
-	header_string << int_ver[0] << "." << int_ver[1] << "." << int_ver[2] << "." << int_ver[3];
+	char * byte_ver = (char*)&(info.version);
+	int int_ver[4] = { byte_ver[3], byte_ver[2], byte_ver[1], byte_ver[0] };
 
 	out << header_string.str() << "\n";
 };
diff --git a/src/gen/Footer.cpp b/src/gen/Footer.cpp
index 37aa34c0..f47d935f 100644
--- a/src/gen/Footer.cpp
+++ b/src/gen/Footer.cpp
@@ -44,10 +44,15 @@ void Footer::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map
 	if ( info.version >= 0x0303000D ) {
 		NifStream( numRoots, out, info );
 		for (unsigned int i2 = 0; i2 < roots.size(); i2++) {
-			if ( roots[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(roots[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*roots[i2]), out, info );
+			} else {
+				if ( roots[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(roots[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 }
diff --git a/src/gen/enums.cpp b/src/gen/enums.cpp
index 9e2566f7..f83efb49 100644
--- a/src/gen/enums.cpp
+++ b/src/gen/enums.cpp
@@ -106,9 +106,10 @@ ostream & operator<<( ostream & out, CompareMode const & val ) {
 		case TEST_NEVER: return out << "TEST_NEVER";
 		case TEST_LESS: return out << "TEST_LESS";
 		case TEST_EQUAL: return out << "TEST_EQUAL";
-		case TEST_LESSEQUAL: return out << "TEST_LESSEQUAL";
+		case TEST_LESS_EQUAL: return out << "TEST_LESS_EQUAL";
 		case TEST_GREATER: return out << "TEST_GREATER";
-		case TEST_GREATEREQUAL: return out << "TEST_GREATEREQUAL";
+		case TEST_NOT_EQUAL: return out << "TEST_NOT_EQUAL";
+		case TEST_GREATER_EQUAL: return out << "TEST_GREATER_EQUAL";
 		case TEST_ALWAYS: return out << "TEST_ALWAYS";
 		default: return out << "Invalid Value! - " << (unsigned int)(val);
 	}
diff --git a/src/niflib.cpp b/src/niflib.cpp
index 7ae981ae..7bf4e580 100644
--- a/src/niflib.cpp
+++ b/src/niflib.cpp
@@ -359,9 +359,9 @@ void WriteNifTree( ostream & out, list<NiObjectRef> const & roots, const NifInfo
 	map<Type*,unsigned int> type_map;
 	map<NiObjectRef, unsigned int> link_map;
 
-   for (list<NiObjectRef>::const_iterator it = roots.begin(); it != roots.end(); ++it) {
-	   EnumerateObjects( (*it), type_map, link_map );
-   }
+	for (list<NiObjectRef>::const_iterator it = roots.begin(); it != roots.end(); ++it) {
+		EnumerateObjects( (*it), type_map, link_map );
+	}
 
 	//Build vectors for reverse look-up
 	vector<NiObjectRef> objects(link_map.size());
@@ -386,6 +386,9 @@ void WriteNifTree( ostream & out, list<NiObjectRef> const & roots, const NifInfo
 	header.creator.str = info.creator;
 	header.exportInfo1.str = info.exportInfo1;
 	header.exportInfo2.str = info.exportInfo2;
+	header.copyright[0].line = "Numerical Design Limited, Chapel Hill, NC 27514";
+	header.copyright[1].line = "Copyright (c) 1996-2000";
+	header.copyright[2].line = "All Rights Reserved";
 	
 	//Set Type Names
 	header.blockTypes.resize( types.size() );
@@ -414,7 +417,23 @@ void WriteNifTree( ostream & out, list<NiObjectRef> const & roots, const NifInfo
 		cout << endl << i << ":  " << objects[i]->GetType().GetTypeName();
 #endif
 
-		if (version < 0x05000001) {
+		if ( version < VER_3_3_0_13 ) {
+			//Check if this object is one of the roots.
+			for ( list<NiObjectRef>::const_iterator it = roots.begin(); it != roots.end(); ++it ) {
+				if ( objects[i] == *it ) {
+					//Write "Top Level Object"
+					WriteString( "Top Level Object", out );
+					break;
+				}
+			}
+
+			//Write Object Type
+			WriteString( objects[i]->GetType().GetTypeName() , out );
+			//Write pointer number of object
+			WriteUInt( (unsigned int)&(*objects[i]), out );
+
+			
+		} else if (version < 0x05000001) {
 			//Write Object Type
 			WriteString( objects[i]->GetType().GetTypeName() , out );
 		} else if (version >= 0x05000001 && version <= VER_10_1_0_0 ) {
@@ -425,27 +444,33 @@ void WriteNifTree( ostream & out, list<NiObjectRef> const & roots, const NifInfo
 	}
 
 	//--Write Footer--//
-	Footer footer;
-   footer.numRoots = 0;
-   if (roots.size() == 1) {
-      const NiObjectRef& root = roots.front();
-      if (root->IsDerivedType(NiControllerSequence::TYPE)) {
-         // KF animation files allow for multiple roots of type NiControllerSequence
-         for ( unsigned int i = 0; i < objects.size(); ++i ) {
-            if (objects[i]->IsDerivedType(NiControllerSequence::TYPE)) {
-               footer.roots.push_back(objects[i]);
-            }
-         }
-      } else { // just assume its correctly passed in 
-         footer.numRoots = 1;
-         footer.roots.resize(1);
-         footer.roots[0] = root;
-      }
-   } else {
-      footer.numRoots = roots.size();
-      footer.roots.insert(footer.roots.end(), roots.begin(), roots.end());
-   }
-	footer.Write( out, link_map, info );
+
+	if ( version < VER_3_3_0_13 ) {
+		//Write "End Of File"
+		WriteString( "End Of File", out );
+	} else {
+		Footer footer;
+		footer.numRoots = 0;
+		if (roots.size() == 1) {
+			const NiObjectRef& root = roots.front();
+			if (root->IsDerivedType(NiControllerSequence::TYPE)) {
+				// KF animation files allow for multiple roots of type NiControllerSequence
+				for ( unsigned int i = 0; i < objects.size(); ++i ) {
+					if (objects[i]->IsDerivedType(NiControllerSequence::TYPE)) {
+						footer.roots.push_back(objects[i]);
+					}
+				}
+			} else { // just assume its correctly passed in 
+				footer.numRoots = 1;
+				footer.roots.resize(1);
+				footer.roots[0] = root;
+			}
+		} else {
+			footer.numRoots = roots.size();
+			footer.roots.insert(footer.roots.end(), roots.begin(), roots.end());
+		}
+		footer.Write( out, link_map, info );
+	}
 }
 
 // Writes a valid Nif File given a file name, a pointer to the root object of a file tree
diff --git a/src/obj/AParticleModifier.cpp b/src/obj/AParticleModifier.cpp
index 62faf9f0..5a14c221 100644
--- a/src/obj/AParticleModifier.cpp
+++ b/src/obj/AParticleModifier.cpp
@@ -60,15 +60,25 @@ void AParticleModifier::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	//--END CUSTOM CODE--//
 
 	NiObject::Write( out, link_map, info );
-	if ( nextModifier != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(nextModifier) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*nextModifier), out, info );
+	} else {
+		if ( nextModifier != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(nextModifier) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version >= 0x04000002 ) {
-		if ( controller != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(controller) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*controller), out, info );
+		} else {
+			if ( controller != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(controller) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/BSKeyframeController.cpp b/src/obj/BSKeyframeController.cpp
index d72276db..250d1231 100644
--- a/src/obj/BSKeyframeController.cpp
+++ b/src/obj/BSKeyframeController.cpp
@@ -56,10 +56,15 @@ void BSKeyframeController::Write( ostream& out, const map<NiObjectRef,unsigned i
 	//--END CUSTOM CODE--//
 
 	NiKeyframeController::Write( out, link_map, info );
-	if ( data2 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data2) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data2), out, info );
+	} else {
+		if ( data2 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data2) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/FxRadioButton.cpp b/src/obj/FxRadioButton.cpp
index b34173e0..3c0122f2 100644
--- a/src/obj/FxRadioButton.cpp
+++ b/src/obj/FxRadioButton.cpp
@@ -68,10 +68,15 @@ void FxRadioButton::Write( ostream& out, const map<NiObjectRef,unsigned int> & l
 	NifStream( unknownInt3, out, info );
 	NifStream( numButtons, out, info );
 	for (unsigned int i1 = 0; i1 < buttons.size(); i1++) {
-		if ( buttons[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(buttons[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*buttons[i1]), out, info );
+		} else {
+			if ( buttons[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(buttons[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiAVObject.cpp b/src/obj/NiAVObject.cpp
index 3f04fd6b..417d18a9 100644
--- a/src/obj/NiAVObject.cpp
+++ b/src/obj/NiAVObject.cpp
@@ -105,10 +105,15 @@ void NiAVObject::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 	};
 	NifStream( numProperties, out, info );
 	for (unsigned int i1 = 0; i1 < properties.size(); i1++) {
-		if ( properties[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(properties[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*properties[i1]), out, info );
+		} else {
+			if ( properties[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(properties[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	if ( info.version <= 0x04020200 ) {
 		NifStream( hasBoundingBox, out, info );
@@ -120,10 +125,15 @@ void NiAVObject::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 		};
 	};
 	if ( info.version >= 0x0A000100 ) {
-		if ( collisionObject != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(collisionObject) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*collisionObject), out, info );
+		} else {
+			if ( collisionObject != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(collisionObject) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiAlphaController.cpp b/src/obj/NiAlphaController.cpp
index 81f6ad80..6836fe7c 100644
--- a/src/obj/NiAlphaController.cpp
+++ b/src/obj/NiAlphaController.cpp
@@ -59,10 +59,15 @@ void NiAlphaController::Write( ostream& out, const map<NiObjectRef,unsigned int>
 
 	NiFloatInterpController::Write( out, link_map, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiAlphaProperty.cpp b/src/obj/NiAlphaProperty.cpp
index 16583f1d..fbcc8fd1 100644
--- a/src/obj/NiAlphaProperty.cpp
+++ b/src/obj/NiAlphaProperty.cpp
@@ -110,57 +110,51 @@ void NiAlphaProperty::SetTestThreshold( byte n ) {
 	threshold = n;
 }
 
-#define NIFLIB_GET_FLAG(value, shift, mask) \
-   (( value >> shift ) & mask)
-
-#define NIFLIB_MASK_FLAG(flag, value, shift, mask) \
-   ((flag & ~(mask << shift)) | ((value & mask) << shift))
-
 NiAlphaProperty::BlendFunc NiAlphaProperty::GetSourceBlendFunc() const {
-   return (NiAlphaProperty::BlendFunc)NIFLIB_GET_FLAG(flags, 1, 0x0f);
+	return (BlendFunc)UnpackField( flags, 1, 4 );
 }
 
 void NiAlphaProperty::SetSourceBlendFunc(BlendFunc value) {
-   flags = NIFLIB_MASK_FLAG(flags, value, 1, 0x0f);
+	PackField( flags, value, 1, 4 );
 }
 
 NiAlphaProperty::BlendFunc NiAlphaProperty::GetDestBlendFunc() const {
-   return (NiAlphaProperty::BlendFunc)(( flags >> 5 ) & 0x0f);
+	return (BlendFunc)UnpackField( flags, 5, 4 );
 }
 
 void NiAlphaProperty::SetDestBlendFunc(BlendFunc value) {
-   flags = NIFLIB_MASK_FLAG(flags, value, 5, 0x0f);
+   PackField( flags, value, 5, 4 );
 }
 
 NiAlphaProperty::TestFunc NiAlphaProperty::GetTestFunc() const {
-   return (NiAlphaProperty::TestFunc)NIFLIB_GET_FLAG(flags, 10, 0x7);
+	return (TestFunc)UnpackField( flags, 10, 3 );
 }
 
 void NiAlphaProperty::SetTestFunc(TestFunc value) {
-   flags = NIFLIB_MASK_FLAG(flags, value, 10, 0x7);
+	PackField( flags, value, 10, 3 );
 }
 
 bool NiAlphaProperty::GetBlendState() const {
-   return NIFLIB_GET_FLAG(flags, 0, 0x1) ? true : false;
+   return UnpackFlag( flags, 0);
 }
 
 void NiAlphaProperty::SetBlendState(bool value) {
-   flags = NIFLIB_MASK_FLAG(flags, value?1:0, 0, 0x1);
+	PackFlag( flags, value, 0 );
 }
 
 bool NiAlphaProperty::GetTestState() const {
-   return NIFLIB_GET_FLAG(flags, 9, 0x1) ? true : false;
+	return UnpackFlag( flags, 9 );
 }
 
 void NiAlphaProperty::SetTestState(bool value) {
-   flags = NIFLIB_MASK_FLAG(flags, value?1:0, 9, 0x1);
+	PackFlag( flags, value, 9 );
 }
 
 bool NiAlphaProperty::GetTriangleSortMode() const {
-   return NIFLIB_GET_FLAG(flags, 13, 0x1) ? false : true;
+	return UnpackFlag( flags, 13 );
 }
 void NiAlphaProperty::SetTriangleSortMode(bool value) {
-   flags = NIFLIB_MASK_FLAG(flags, value?0:1, 13, 0x1);
+	PackFlag( flags, value, 13 );
 }
 
 //--END CUSTOM CODE--//
diff --git a/src/obj/NiBSplineInterpolator.cpp b/src/obj/NiBSplineInterpolator.cpp
index 31ddacc4..ba5235b1 100644
--- a/src/obj/NiBSplineInterpolator.cpp
+++ b/src/obj/NiBSplineInterpolator.cpp
@@ -63,14 +63,24 @@ void NiBSplineInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned
 	NiInterpolator::Write( out, link_map, info );
 	NifStream( startTime, out, info );
 	NifStream( stopTime, out, info );
-	if ( splineData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(splineData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( basisData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(basisData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*splineData), out, info );
+	} else {
+		if ( splineData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(splineData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*basisData), out, info );
+	} else {
+		if ( basisData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(basisData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiBinaryVoxelExtraData.cpp b/src/obj/NiBinaryVoxelExtraData.cpp
index d6407c14..35ac1cd1 100644
--- a/src/obj/NiBinaryVoxelExtraData.cpp
+++ b/src/obj/NiBinaryVoxelExtraData.cpp
@@ -58,10 +58,15 @@ void NiBinaryVoxelExtraData::Write( ostream& out, const map<NiObjectRef,unsigned
 
 	NiExtraData::Write( out, link_map, info );
 	NifStream( unknownInt, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiBoneLODController.cpp b/src/obj/NiBoneLODController.cpp
index d0dcde5a..aa5c562e 100644
--- a/src/obj/NiBoneLODController.cpp
+++ b/src/obj/NiBoneLODController.cpp
@@ -103,10 +103,15 @@ void NiBoneLODController::Write( ostream& out, const map<NiObjectRef,unsigned in
 		nodeGroups[i1].numNodes = (unsigned int)(nodeGroups[i1].nodes.size());
 		NifStream( nodeGroups[i1].numNodes, out, info );
 		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
-			if ( nodeGroups[i1].nodes[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(nodeGroups[i1].nodes[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*nodeGroups[i1].nodes[i2]), out, info );
+			} else {
+				if ( nodeGroups[i1].nodes[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(nodeGroups[i1].nodes[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 	if ( info.version <= 0x0A000100 ) {
@@ -115,22 +120,37 @@ void NiBoneLODController::Write( ostream& out, const map<NiObjectRef,unsigned in
 			shapeGroups1[i2].numLinkPairs = (unsigned int)(shapeGroups1[i2].linkPairs.size());
 			NifStream( shapeGroups1[i2].numLinkPairs, out, info );
 			for (unsigned int i3 = 0; i3 < shapeGroups1[i2].linkPairs.size(); i3++) {
-				if ( shapeGroups1[i2].linkPairs[i3].shape != NULL )
-					NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i2].linkPairs[i3].shape) )->second, out, info );
-				else
-					NifStream( 0xffffffff, out, info );
-				if ( shapeGroups1[i2].linkPairs[i3].skinInstance != NULL )
-					NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i2].linkPairs[i3].skinInstance) )->second, out, info );
-				else
-					NifStream( 0xffffffff, out, info );
+				if ( info.version < VER_3_3_0_13 ) {
+					NifStream( (unsigned int)&(*shapeGroups1[i2].linkPairs[i3].shape), out, info );
+				} else {
+					if ( shapeGroups1[i2].linkPairs[i3].shape != NULL ) {
+						NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i2].linkPairs[i3].shape) )->second, out, info );
+					} else {
+						NifStream( 0xFFFFFFFF, out, info );
+					}
+				}
+				if ( info.version < VER_3_3_0_13 ) {
+					NifStream( (unsigned int)&(*shapeGroups1[i2].linkPairs[i3].skinInstance), out, info );
+				} else {
+					if ( shapeGroups1[i2].linkPairs[i3].skinInstance != NULL ) {
+						NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i2].linkPairs[i3].skinInstance) )->second, out, info );
+					} else {
+						NifStream( 0xFFFFFFFF, out, info );
+					}
+				}
 			};
 		};
 		NifStream( numShapeGroups2, out, info );
 		for (unsigned int i2 = 0; i2 < shapeGroups2.size(); i2++) {
-			if ( shapeGroups2[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(shapeGroups2[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*shapeGroups2[i2]), out, info );
+			} else {
+				if ( shapeGroups2[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(shapeGroups2[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 
diff --git a/src/obj/NiBoolInterpolator.cpp b/src/obj/NiBoolInterpolator.cpp
index d03315c5..4ab70f14 100644
--- a/src/obj/NiBoolInterpolator.cpp
+++ b/src/obj/NiBoolInterpolator.cpp
@@ -58,10 +58,15 @@ void NiBoolInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned int
 
 	NiKeyBasedInterpolator::Write( out, link_map, info );
 	NifStream( boolValue, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiCamera.cpp b/src/obj/NiCamera.cpp
index 3449168a..f53b0aec 100644
--- a/src/obj/NiCamera.cpp
+++ b/src/obj/NiCamera.cpp
@@ -97,10 +97,15 @@ void NiCamera::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_m
 	NifStream( viewportTop, out, info );
 	NifStream( viewportBottom, out, info );
 	NifStream( lodAdjust, out, info );
-	if ( unknownLink_ != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink_) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink_), out, info );
+	} else {
+		if ( unknownLink_ != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink_) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( unknownInt, out, info );
 	if ( info.version >= 0x04020100 ) {
 		NifStream( unknownInt2, out, info );
diff --git a/src/obj/NiCollisionObject.cpp b/src/obj/NiCollisionObject.cpp
index 97d0105f..c04dd62d 100644
--- a/src/obj/NiCollisionObject.cpp
+++ b/src/obj/NiCollisionObject.cpp
@@ -62,16 +62,26 @@ void NiCollisionObject::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	//--END CUSTOM CODE--//
 
 	NiObject::Write( out, link_map, info );
-	if ( target != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*target), out, info );
+	} else {
+		if ( target != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version >= 0x14000004 ) {
 		NifStream( unknownShort, out, info );
-		if ( body != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(body) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*body), out, info );
+		} else {
+			if ( body != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(body) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiControllerManager.cpp b/src/obj/NiControllerManager.cpp
index 15d04135..735d11a8 100644
--- a/src/obj/NiControllerManager.cpp
+++ b/src/obj/NiControllerManager.cpp
@@ -69,15 +69,25 @@ void NiControllerManager::Write( ostream& out, const map<NiObjectRef,unsigned in
 	NifStream( cumulative, out, info );
 	NifStream( numControllerSequences, out, info );
 	for (unsigned int i1 = 0; i1 < controllerSequences.size(); i1++) {
-		if ( controllerSequences[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(controllerSequences[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*controllerSequences[i1]), out, info );
+		} else {
+			if ( controllerSequences[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(controllerSequences[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
-	if ( objectPalette != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(objectPalette) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*objectPalette), out, info );
+	} else {
+		if ( objectPalette != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(objectPalette) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiControllerSequence.cpp b/src/obj/NiControllerSequence.cpp
index 4d6b7c55..f2112bb5 100644
--- a/src/obj/NiControllerSequence.cpp
+++ b/src/obj/NiControllerSequence.cpp
@@ -91,10 +91,15 @@ void NiControllerSequence::Write( ostream& out, const map<NiObjectRef,unsigned i
 	NiSequence::Write( out, link_map, info );
 	if ( info.version >= 0x0A01006A ) {
 		NifStream( weight, out, info );
-		if ( textKeys != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(textKeys) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*textKeys), out, info );
+		} else {
+			if ( textKeys != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(textKeys) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( cycleType, out, info );
 	};
 	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
@@ -112,17 +117,27 @@ void NiControllerSequence::Write( ostream& out, const map<NiObjectRef,unsigned i
 		NifStream( unknownByte, out, info );
 	};
 	if ( info.version >= 0x0A01006A ) {
-		if ( manager != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(manager) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*manager), out, info );
+		} else {
+			if ( manager != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(manager) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( targetName, out, info );
 	};
 	if ( info.version >= 0x0A020000 ) {
-		if ( stringPalette != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(stringPalette) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*stringPalette), out, info );
+		} else {
+			if ( stringPalette != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(stringPalette) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiDefaultAVObjectPalette.cpp b/src/obj/NiDefaultAVObjectPalette.cpp
index 0bf509bc..933f3a74 100644
--- a/src/obj/NiDefaultAVObjectPalette.cpp
+++ b/src/obj/NiDefaultAVObjectPalette.cpp
@@ -68,10 +68,15 @@ void NiDefaultAVObjectPalette::Write( ostream& out, const map<NiObjectRef,unsign
 	NifStream( numObjs, out, info );
 	for (unsigned int i1 = 0; i1 < objs.size(); i1++) {
 		NifStream( objs[i1].name, out, info );
-		if ( objs[i1].avObject != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(objs[i1].avObject) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*objs[i1].avObject), out, info );
+		} else {
+			if ( objs[i1].avObject != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(objs[i1].avObject) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiDynamicEffect.cpp b/src/obj/NiDynamicEffect.cpp
index 7259e5ad..48893bd7 100644
--- a/src/obj/NiDynamicEffect.cpp
+++ b/src/obj/NiDynamicEffect.cpp
@@ -94,10 +94,15 @@ void NiDynamicEffect::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	};
 	if ( info.version >= 0x0A010000 ) {
 		for (unsigned int i2 = 0; i2 < affectedNodes.size(); i2++) {
-			if ( affectedNodes[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(affectedNodes[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*affectedNodes[i2]), out, info );
+			} else {
+				if ( affectedNodes[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(affectedNodes[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 
diff --git a/src/obj/NiExtraData.cpp b/src/obj/NiExtraData.cpp
index 90b65ad1..cbc82af0 100644
--- a/src/obj/NiExtraData.cpp
+++ b/src/obj/NiExtraData.cpp
@@ -64,10 +64,15 @@ void NiExtraData::Write( ostream& out, const map<NiObjectRef,unsigned int> & lin
 		NifStream( name, out, info );
 	};
 	if ( info.version <= 0x04020200 ) {
-		if ( nextExtraData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(nextExtraData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*nextExtraData), out, info );
+		} else {
+			if ( nextExtraData != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(nextExtraData) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiFlipController.cpp b/src/obj/NiFlipController.cpp
index a86b27c0..8f5ba872 100644
--- a/src/obj/NiFlipController.cpp
+++ b/src/obj/NiFlipController.cpp
@@ -88,18 +88,28 @@ void NiFlipController::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	NifStream( numSources, out, info );
 	if ( info.version >= 0x04000000 ) {
 		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
-			if ( sources[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(sources[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*sources[i2]), out, info );
+			} else {
+				if ( sources[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(sources[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 	if ( info.version <= 0x03010000 ) {
 		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
-			if ( image[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(image[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*image[i2]), out, info );
+			} else {
+				if ( image[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(image[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 
diff --git a/src/obj/NiFloatInterpolator.cpp b/src/obj/NiFloatInterpolator.cpp
index f65ca089..057de098 100644
--- a/src/obj/NiFloatInterpolator.cpp
+++ b/src/obj/NiFloatInterpolator.cpp
@@ -58,10 +58,15 @@ void NiFloatInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned in
 
 	NiKeyBasedInterpolator::Write( out, link_map, info );
 	NifStream( floatValue, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiGeomMorpherController.cpp b/src/obj/NiGeomMorpherController.cpp
index 2b817bfb..cf2aecbd 100644
--- a/src/obj/NiGeomMorpherController.cpp
+++ b/src/obj/NiGeomMorpherController.cpp
@@ -87,18 +87,28 @@ void NiGeomMorpherController::Write( ostream& out, const map<NiObjectRef,unsigne
 	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
 		NifStream( unknown2, out, info );
 	};
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( unknownByte, out, info );
 	if ( info.version >= 0x0A01006A ) {
 		NifStream( numInterpolators, out, info );
 		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
-			if ( interpolators[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(interpolators[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*interpolators[i2]), out, info );
+			} else {
+				if ( interpolators[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(interpolators[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 	if ( info.version >= 0x0A020000 ) {
diff --git a/src/obj/NiGeometry.cpp b/src/obj/NiGeometry.cpp
index 74480996..8e6bd9a6 100644
--- a/src/obj/NiGeometry.cpp
+++ b/src/obj/NiGeometry.cpp
@@ -73,24 +73,39 @@ void NiGeometry::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 	//--END CUSTOM CODE--//
 
 	NiAVObject::Write( out, link_map, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version >= 0x0303000D ) {
-		if ( skinInstance != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(skinInstance) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*skinInstance), out, info );
+		} else {
+			if ( skinInstance != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(skinInstance) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	if ( info.version >= 0x0A000100 ) {
 		NifStream( hasShader, out, info );
 		if ( (hasShader != 0) ) {
 			NifStream( shaderName, out, info );
-			if ( unknownLink != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*unknownLink), out, info );
+			} else {
+				if ( unknownLink != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 
diff --git a/src/obj/NiGeometryData.cpp b/src/obj/NiGeometryData.cpp
index 34d51f07..36813b38 100644
--- a/src/obj/NiGeometryData.cpp
+++ b/src/obj/NiGeometryData.cpp
@@ -195,10 +195,15 @@ void NiGeometryData::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 		NifStream( unknownShort2, out, info );
 	};
 	if ( info.version >= 0x14000004 ) {
-		if ( unknownLink1 != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*unknownLink1), out, info );
+		} else {
+			if ( unknownLink1 != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiImage.cpp b/src/obj/NiImage.cpp
index ccd41fab..8362b1b4 100644
--- a/src/obj/NiImage.cpp
+++ b/src/obj/NiImage.cpp
@@ -71,10 +71,15 @@ void NiImage::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_ma
 		NifStream( fileName, out, info );
 	};
 	if ( (external == 0) ) {
-		if ( imageData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(imageData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*imageData), out, info );
+		} else {
+			if ( imageData != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(imageData) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( unknownInt1, out, info );
 	if ( info.version >= 0x03010000 ) {
diff --git a/src/obj/NiKeyframeController.cpp b/src/obj/NiKeyframeController.cpp
index ab0bcaf8..b14a5523 100644
--- a/src/obj/NiKeyframeController.cpp
+++ b/src/obj/NiKeyframeController.cpp
@@ -56,10 +56,15 @@ void NiKeyframeController::Write( ostream& out, const map<NiObjectRef,unsigned i
 	//--END CUSTOM CODE--//
 
 	NiTimeController::Write( out, link_map, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiLODNode.cpp b/src/obj/NiLODNode.cpp
index 636b0216..11739f95 100644
--- a/src/obj/NiLODNode.cpp
+++ b/src/obj/NiLODNode.cpp
@@ -100,10 +100,15 @@ void NiLODNode::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_
 	};
 	if ( info.version >= 0x0A010000 ) {
 		NifStream( unknownShort, out, info );
-		if ( lodLevelData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(lodLevelData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*lodLevelData), out, info );
+		} else {
+			if ( lodLevelData != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(lodLevelData) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiLookAtController.cpp b/src/obj/NiLookAtController.cpp
index f4e5fec4..018e5f52 100644
--- a/src/obj/NiLookAtController.cpp
+++ b/src/obj/NiLookAtController.cpp
@@ -62,10 +62,15 @@ void NiLookAtController::Write( ostream& out, const map<NiObjectRef,unsigned int
 	if ( info.version >= 0x0A010000 ) {
 		NifStream( unknown1, out, info );
 	};
-	if ( lookAtNode != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(lookAtNode) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*lookAtNode), out, info );
+	} else {
+		if ( lookAtNode != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(lookAtNode) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiLookAtInterpolator.cpp b/src/obj/NiLookAtInterpolator.cpp
index 8cfcea87..16d906f9 100644
--- a/src/obj/NiLookAtInterpolator.cpp
+++ b/src/obj/NiLookAtInterpolator.cpp
@@ -70,26 +70,46 @@ void NiLookAtInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned i
 
 	NiInterpolator::Write( out, link_map, info );
 	NifStream( unknownShort, out, info );
-	if ( lookAt != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(lookAt) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*lookAt), out, info );
+	} else {
+		if ( lookAt != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(lookAt) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( unknownFloat, out, info );
 	NifStream( translation, out, info );
 	NifStream( rotation, out, info );
 	NifStream( scale, out, info );
-	if ( unknownLink1 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( unknownLink2 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( unknownLink3 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink3) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink1), out, info );
+	} else {
+		if ( unknownLink1 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink2), out, info );
+	} else {
+		if ( unknownLink2 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink3), out, info );
+	} else {
+		if ( unknownLink3 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink3) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiMeshPSysData.cpp b/src/obj/NiMeshPSysData.cpp
index 8cf7ebb9..bfdbf0ed 100644
--- a/src/obj/NiMeshPSysData.cpp
+++ b/src/obj/NiMeshPSysData.cpp
@@ -80,19 +80,29 @@ void NiMeshPSysData::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	NiPSysData::Write( out, link_map, info );
 	numUnknownLinks = (unsigned int)(unknownLinks.size());
 	if ( info.version <= 0x14000004 ) {
-		if ( modifier != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(modifier) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*modifier), out, info );
+		} else {
+			if ( modifier != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(modifier) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
 		NifStream( unknownByte2, out, info );
 		NifStream( numUnknownLinks, out, info );
 		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
-			if ( unknownLinks[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(unknownLinks[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*unknownLinks[i2]), out, info );
+			} else {
+				if ( unknownLinks[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(unknownLinks[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 	if ( info.version >= 0x14000005 ) {
@@ -102,10 +112,15 @@ void NiMeshPSysData::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 		NifStream( numVertices3, out, info );
 	};
 	if ( info.version >= 0x0A020000 ) {
-		if ( unknownLink2 != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*unknownLink2), out, info );
+		} else {
+			if ( unknownLink2 != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiMultiTargetTransformController.cpp b/src/obj/NiMultiTargetTransformController.cpp
index 0229a935..21531896 100644
--- a/src/obj/NiMultiTargetTransformController.cpp
+++ b/src/obj/NiMultiTargetTransformController.cpp
@@ -64,10 +64,15 @@ void NiMultiTargetTransformController::Write( ostream& out, const map<NiObjectRe
 	numExtraTargets = (unsigned short)(extraTargets.size());
 	NifStream( numExtraTargets, out, info );
 	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
-		if ( extraTargets[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(extraTargets[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*extraTargets[i1]), out, info );
+		} else {
+			if ( extraTargets[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(extraTargets[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiMultiTextureProperty.cpp b/src/obj/NiMultiTextureProperty.cpp
index ff091fcf..462d7814 100644
--- a/src/obj/NiMultiTextureProperty.cpp
+++ b/src/obj/NiMultiTextureProperty.cpp
@@ -75,10 +75,15 @@ void NiMultiTextureProperty::Write( ostream& out, const map<NiObjectRef,unsigned
 	for (unsigned int i1 = 0; i1 < 5; i1++) {
 		NifStream( textureElements[i1].hasImage, out, info );
 		if ( textureElements[i1].hasImage ) {
-			if ( textureElements[i1].image != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(textureElements[i1].image) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*textureElements[i1].image), out, info );
+			} else {
+				if ( textureElements[i1].image != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(textureElements[i1].image) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 			NifStream( textureElements[i1].unknownInt1, out, info );
 			NifStream( textureElements[i1].unknownInt2, out, info );
 			NifStream( textureElements[i1].unknownInt3, out, info );
diff --git a/src/obj/NiNode.cpp b/src/obj/NiNode.cpp
index a818134f..f615597d 100644
--- a/src/obj/NiNode.cpp
+++ b/src/obj/NiNode.cpp
@@ -87,17 +87,27 @@ void NiNode::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map
 	numChildren = (unsigned int)(children.size());
 	NifStream( numChildren, out, info );
 	for (unsigned int i1 = 0; i1 < children.size(); i1++) {
-		if ( children[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(children[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*children[i1]), out, info );
+		} else {
+			if ( children[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(children[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( numEffects, out, info );
 	for (unsigned int i1 = 0; i1 < effects.size(); i1++) {
-		if ( effects[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(effects[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*effects[i1]), out, info );
+		} else {
+			if ( effects[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(effects[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiObjectNET.cpp b/src/obj/NiObjectNET.cpp
index 988266e1..5e33ae52 100644
--- a/src/obj/NiObjectNET.cpp
+++ b/src/obj/NiObjectNET.cpp
@@ -78,24 +78,39 @@ void NiObjectNET::Write( ostream& out, const map<NiObjectRef,unsigned int> & lin
 	numExtraDataList = (unsigned int)(extraDataList.size());
 	NifStream( name, out, info );
 	if ( info.version <= 0x04020200 ) {
-		if ( extraData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(extraData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*extraData), out, info );
+		} else {
+			if ( extraData != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(extraData) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	if ( info.version >= 0x0A000100 ) {
 		NifStream( numExtraDataList, out, info );
 		for (unsigned int i2 = 0; i2 < extraDataList.size(); i2++) {
-			if ( extraDataList[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(extraDataList[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*extraDataList[i2]), out, info );
+			} else {
+				if ( extraDataList[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(extraDataList[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
-	if ( controller != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(controller) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*controller), out, info );
+	} else {
+		if ( controller != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(controller) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPSysAgeDeathModifier.cpp b/src/obj/NiPSysAgeDeathModifier.cpp
index 36d58058..0580ecd3 100644
--- a/src/obj/NiPSysAgeDeathModifier.cpp
+++ b/src/obj/NiPSysAgeDeathModifier.cpp
@@ -58,10 +58,15 @@ void NiPSysAgeDeathModifier::Write( ostream& out, const map<NiObjectRef,unsigned
 
 	NiPSysModifier::Write( out, link_map, info );
 	NifStream( spawnOnDeath, out, info );
-	if ( spawnModifier != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(spawnModifier) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*spawnModifier), out, info );
+	} else {
+		if ( spawnModifier != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(spawnModifier) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPSysBombModifier.cpp b/src/obj/NiPSysBombModifier.cpp
index 094248a4..348a3343 100644
--- a/src/obj/NiPSysBombModifier.cpp
+++ b/src/obj/NiPSysBombModifier.cpp
@@ -65,10 +65,15 @@ void NiPSysBombModifier::Write( ostream& out, const map<NiObjectRef,unsigned int
 	//--END CUSTOM CODE--//
 
 	NiPSysModifier::Write( out, link_map, info );
-	if ( unknownLink != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink), out, info );
+	} else {
+		if ( unknownLink != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	for (unsigned int i1 = 0; i1 < 2; i1++) {
 		NifStream( unknownInts1[i1], out, info );
 	};
diff --git a/src/obj/NiPSysCollider.cpp b/src/obj/NiPSysCollider.cpp
index 977d85fb..6b5cab3e 100644
--- a/src/obj/NiPSysCollider.cpp
+++ b/src/obj/NiPSysCollider.cpp
@@ -70,22 +70,42 @@ void NiPSysCollider::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	NifStream( bounce, out, info );
 	NifStream( spawnOnCollide, out, info );
 	NifStream( dieOnCollide, out, info );
-	if ( spawnModifier != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(spawnModifier) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( parent != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( nextCollider != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(nextCollider) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( colliderObject != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(colliderObject) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*spawnModifier), out, info );
+	} else {
+		if ( spawnModifier != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(spawnModifier) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*parent), out, info );
+	} else {
+		if ( parent != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*nextCollider), out, info );
+	} else {
+		if ( nextCollider != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(nextCollider) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*colliderObject), out, info );
+	} else {
+		if ( colliderObject != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(colliderObject) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPSysColliderManager.cpp b/src/obj/NiPSysColliderManager.cpp
index 88fcae2f..fa9060eb 100644
--- a/src/obj/NiPSysColliderManager.cpp
+++ b/src/obj/NiPSysColliderManager.cpp
@@ -56,10 +56,15 @@ void NiPSysColliderManager::Write( ostream& out, const map<NiObjectRef,unsigned
 	//--END CUSTOM CODE--//
 
 	NiPSysModifier::Write( out, link_map, info );
-	if ( collider != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(collider) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*collider), out, info );
+	} else {
+		if ( collider != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(collider) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPSysColorModifier.cpp b/src/obj/NiPSysColorModifier.cpp
index 4fb30de3..e674f39c 100644
--- a/src/obj/NiPSysColorModifier.cpp
+++ b/src/obj/NiPSysColorModifier.cpp
@@ -56,10 +56,15 @@ void NiPSysColorModifier::Write( ostream& out, const map<NiObjectRef,unsigned in
 	//--END CUSTOM CODE--//
 
 	NiPSysModifier::Write( out, link_map, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPSysDragModifier.cpp b/src/obj/NiPSysDragModifier.cpp
index 765db5ad..1fd8e0b7 100644
--- a/src/obj/NiPSysDragModifier.cpp
+++ b/src/obj/NiPSysDragModifier.cpp
@@ -60,10 +60,15 @@ void NiPSysDragModifier::Write( ostream& out, const map<NiObjectRef,unsigned int
 	//--END CUSTOM CODE--//
 
 	NiPSysModifier::Write( out, link_map, info );
-	if ( parent != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*parent), out, info );
+	} else {
+		if ( parent != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( dragAxis, out, info );
 	NifStream( percentage, out, info );
 	NifStream( range, out, info );
diff --git a/src/obj/NiPSysEmitterCtlr.cpp b/src/obj/NiPSysEmitterCtlr.cpp
index 655789cb..c28a6d1a 100644
--- a/src/obj/NiPSysEmitterCtlr.cpp
+++ b/src/obj/NiPSysEmitterCtlr.cpp
@@ -64,16 +64,26 @@ void NiPSysEmitterCtlr::Write( ostream& out, const map<NiObjectRef,unsigned int>
 
 	NiPSysModifierCtlr::Write( out, link_map, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	if ( info.version >= 0x0A020000 ) {
-		if ( visibilityInterpolator != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(visibilityInterpolator) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*visibilityInterpolator), out, info );
+		} else {
+			if ( visibilityInterpolator != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(visibilityInterpolator) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiPSysGravityModifier.cpp b/src/obj/NiPSysGravityModifier.cpp
index 20641a6f..4f86d85d 100644
--- a/src/obj/NiPSysGravityModifier.cpp
+++ b/src/obj/NiPSysGravityModifier.cpp
@@ -62,10 +62,15 @@ void NiPSysGravityModifier::Write( ostream& out, const map<NiObjectRef,unsigned
 	//--END CUSTOM CODE--//
 
 	NiPSysModifier::Write( out, link_map, info );
-	if ( gravityObject != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(gravityObject) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*gravityObject), out, info );
+	} else {
+		if ( gravityObject != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(gravityObject) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( gravityAxis, out, info );
 	NifStream( decay, out, info );
 	NifStream( strength, out, info );
diff --git a/src/obj/NiPSysMeshEmitter.cpp b/src/obj/NiPSysMeshEmitter.cpp
index 745bf655..daf59d6f 100644
--- a/src/obj/NiPSysMeshEmitter.cpp
+++ b/src/obj/NiPSysMeshEmitter.cpp
@@ -66,10 +66,15 @@ void NiPSysMeshEmitter::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	numEmitterMeshes = (unsigned int)(emitterMeshes.size());
 	NifStream( numEmitterMeshes, out, info );
 	for (unsigned int i1 = 0; i1 < emitterMeshes.size(); i1++) {
-		if ( emitterMeshes[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(emitterMeshes[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*emitterMeshes[i1]), out, info );
+		} else {
+			if ( emitterMeshes[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(emitterMeshes[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( initialVelocityType, out, info );
 	NifStream( emissionType, out, info );
diff --git a/src/obj/NiPSysMeshUpdateModifier.cpp b/src/obj/NiPSysMeshUpdateModifier.cpp
index 0197e323..e1315654 100644
--- a/src/obj/NiPSysMeshUpdateModifier.cpp
+++ b/src/obj/NiPSysMeshUpdateModifier.cpp
@@ -63,10 +63,15 @@ void NiPSysMeshUpdateModifier::Write( ostream& out, const map<NiObjectRef,unsign
 	numMeshes = (unsigned int)(meshes.size());
 	NifStream( numMeshes, out, info );
 	for (unsigned int i1 = 0; i1 < meshes.size(); i1++) {
-		if ( meshes[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(meshes[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*meshes[i1]), out, info );
+		} else {
+			if ( meshes[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(meshes[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiPSysModifier.cpp b/src/obj/NiPSysModifier.cpp
index 0fd22277..7353b096 100644
--- a/src/obj/NiPSysModifier.cpp
+++ b/src/obj/NiPSysModifier.cpp
@@ -61,10 +61,15 @@ void NiPSysModifier::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	NiObject::Write( out, link_map, info );
 	NifStream( name, out, info );
 	NifStream( order, out, info );
-	if ( target != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*target), out, info );
+	} else {
+		if ( target != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( active, out, info );
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiPSysModifierActiveCtlr.cpp b/src/obj/NiPSysModifierActiveCtlr.cpp
index 77e41a23..80c2849a 100644
--- a/src/obj/NiPSysModifierActiveCtlr.cpp
+++ b/src/obj/NiPSysModifierActiveCtlr.cpp
@@ -59,10 +59,15 @@ void NiPSysModifierActiveCtlr::Write( ostream& out, const map<NiObjectRef,unsign
 
 	NiPSysModifierBoolCtlr::Write( out, link_map, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiPSysModifierFloatCtlr.cpp b/src/obj/NiPSysModifierFloatCtlr.cpp
index 0e936520..0627fb15 100644
--- a/src/obj/NiPSysModifierFloatCtlr.cpp
+++ b/src/obj/NiPSysModifierFloatCtlr.cpp
@@ -59,10 +59,15 @@ void NiPSysModifierFloatCtlr::Write( ostream& out, const map<NiObjectRef,unsigne
 
 	NiPSysModifierCtlr::Write( out, link_map, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiPSysVolumeEmitter.cpp b/src/obj/NiPSysVolumeEmitter.cpp
index 27bafaf4..694572d4 100644
--- a/src/obj/NiPSysVolumeEmitter.cpp
+++ b/src/obj/NiPSysVolumeEmitter.cpp
@@ -59,10 +59,15 @@ void NiPSysVolumeEmitter::Write( ostream& out, const map<NiObjectRef,unsigned in
 
 	NiPSysEmitter::Write( out, link_map, info );
 	if ( info.version >= 0x0A010000 ) {
-		if ( emitterObject != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(emitterObject) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*emitterObject), out, info );
+		} else {
+			if ( emitterObject != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(emitterObject) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiParticleColorModifier.cpp b/src/obj/NiParticleColorModifier.cpp
index 3948f202..aac4db4c 100644
--- a/src/obj/NiParticleColorModifier.cpp
+++ b/src/obj/NiParticleColorModifier.cpp
@@ -56,10 +56,15 @@ void NiParticleColorModifier::Write( ostream& out, const map<NiObjectRef,unsigne
 	//--END CUSTOM CODE--//
 
 	AParticleModifier::Write( out, link_map, info );
-	if ( colorData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(colorData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*colorData), out, info );
+	} else {
+		if ( colorData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(colorData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiParticleMeshModifier.cpp b/src/obj/NiParticleMeshModifier.cpp
index bb3ce052..2e572d51 100644
--- a/src/obj/NiParticleMeshModifier.cpp
+++ b/src/obj/NiParticleMeshModifier.cpp
@@ -63,10 +63,15 @@ void NiParticleMeshModifier::Write( ostream& out, const map<NiObjectRef,unsigned
 	numParticleMeshes = (unsigned int)(particleMeshes.size());
 	NifStream( numParticleMeshes, out, info );
 	for (unsigned int i1 = 0; i1 < particleMeshes.size(); i1++) {
-		if ( particleMeshes[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(particleMeshes[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*particleMeshes[i1]), out, info );
+		} else {
+			if ( particleMeshes[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(particleMeshes[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiParticleMeshesData.cpp b/src/obj/NiParticleMeshesData.cpp
index e4903b3e..d20ff243 100644
--- a/src/obj/NiParticleMeshesData.cpp
+++ b/src/obj/NiParticleMeshesData.cpp
@@ -56,10 +56,15 @@ void NiParticleMeshesData::Write( ostream& out, const map<NiObjectRef,unsigned i
 	//--END CUSTOM CODE--//
 
 	NiRotatingParticlesData::Write( out, link_map, info );
-	if ( unknownLink2 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink2), out, info );
+	} else {
+		if ( unknownLink2 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiParticleSystem.cpp b/src/obj/NiParticleSystem.cpp
index b85c1ab6..e354e412 100644
--- a/src/obj/NiParticleSystem.cpp
+++ b/src/obj/NiParticleSystem.cpp
@@ -68,10 +68,15 @@ void NiParticleSystem::Write( ostream& out, const map<NiObjectRef,unsigned int>
 		NifStream( unknownBool, out, info );
 		NifStream( numModifiers, out, info );
 		for (unsigned int i2 = 0; i2 < modifiers.size(); i2++) {
-			if ( modifiers[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(modifiers[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*modifiers[i2]), out, info );
+			} else {
+				if ( modifiers[i2] != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(modifiers[i2]) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 
diff --git a/src/obj/NiParticleSystemController.cpp b/src/obj/NiParticleSystemController.cpp
index e847ee5f..188dce34 100644
--- a/src/obj/NiParticleSystemController.cpp
+++ b/src/obj/NiParticleSystemController.cpp
@@ -159,10 +159,15 @@ void NiParticleSystemController::Write( ostream& out, const map<NiObjectRef,unsi
 		NifStream( emitFlags, out, info );
 	};
 	NifStream( startRandom, out, info );
-	if ( emitter != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(emitter) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*emitter), out, info );
+	} else {
+		if ( emitter != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(emitter) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version >= 0x04000002 ) {
 		NifStream( unknownShort2_, out, info );
 		NifStream( unknownFloat13_, out, info );
@@ -191,27 +196,47 @@ void NiParticleSystemController::Write( ostream& out, const map<NiObjectRef,unsi
 			NifStream( particles[i2].unknownShort, out, info );
 			NifStream( particles[i2].vertexId, out, info );
 		};
-		if ( unknownLink != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*unknownLink), out, info );
+		} else {
+			if ( unknownLink != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
-	if ( particleExtra != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(particleExtra) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( unknownLink2 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*particleExtra), out, info );
+	} else {
+		if ( particleExtra != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(particleExtra) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink2), out, info );
+	} else {
+		if ( unknownLink2 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version >= 0x04000002 ) {
 		NifStream( trailer, out, info );
 	};
 	if ( info.version <= 0x03010000 ) {
-		if ( colorData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(colorData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*colorData), out, info );
+		} else {
+			if ( colorData != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(colorData) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		for (unsigned int i2 = 0; i2 < 2; i2++) {
 			NifStream( unkownFloats[i2], out, info );
 		};
diff --git a/src/obj/NiPathController.cpp b/src/obj/NiPathController.cpp
index 31880c8e..63b18d4f 100644
--- a/src/obj/NiPathController.cpp
+++ b/src/obj/NiPathController.cpp
@@ -73,14 +73,24 @@ void NiPathController::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	NifStream( unknownInt2, out, info );
 	NifStream( unknownInt3, out, info );
 	NifStream( unknownShort, out, info );
-	if ( posData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(posData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( floatData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(floatData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*posData), out, info );
+	} else {
+		if ( posData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(posData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*floatData), out, info );
+	} else {
+		if ( floatData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(floatData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPathInterpolator.cpp b/src/obj/NiPathInterpolator.cpp
index b2601f91..3c1a8d38 100644
--- a/src/obj/NiPathInterpolator.cpp
+++ b/src/obj/NiPathInterpolator.cpp
@@ -69,14 +69,24 @@ void NiPathInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned int
 	NifStream( unknownFloat1, out, info );
 	NifStream( unknownFloat2, out, info );
 	NifStream( unknownShort2, out, info );
-	if ( posData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(posData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( floatData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(floatData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*posData), out, info );
+	} else {
+		if ( posData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(posData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*floatData), out, info );
+	} else {
+		if ( floatData != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(floatData) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiPixelData.cpp b/src/obj/NiPixelData.cpp
index e5bf61a7..1c05d524 100644
--- a/src/obj/NiPixelData.cpp
+++ b/src/obj/NiPixelData.cpp
@@ -113,10 +113,15 @@ void NiPixelData::Write( ostream& out, const map<NiObjectRef,unsigned int> & lin
 			NifStream( unknown54Bytes[i2], out, info );
 		};
 	};
-	if ( palette != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(palette) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*palette), out, info );
+	} else {
+		if ( palette != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(palette) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( numMipmaps, out, info );
 	NifStream( bytesPerPixel, out, info );
 	for (unsigned int i1 = 0; i1 < mipmaps.size(); i1++) {
diff --git a/src/obj/NiPoint3InterpController.cpp b/src/obj/NiPoint3InterpController.cpp
index b6b5c986..cfa28749 100644
--- a/src/obj/NiPoint3InterpController.cpp
+++ b/src/obj/NiPoint3InterpController.cpp
@@ -65,10 +65,15 @@ void NiPoint3InterpController::Write( ostream& out, const map<NiObjectRef,unsign
 		NifStream( targetColor, out, info );
 	};
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiPoint3Interpolator.cpp b/src/obj/NiPoint3Interpolator.cpp
index 65a6dce9..b16d106f 100644
--- a/src/obj/NiPoint3Interpolator.cpp
+++ b/src/obj/NiPoint3Interpolator.cpp
@@ -58,10 +58,15 @@ void NiPoint3Interpolator::Write( ostream& out, const map<NiObjectRef,unsigned i
 
 	NiKeyBasedInterpolator::Write( out, link_map, info );
 	NifStream( point3Value, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiRollController.cpp b/src/obj/NiRollController.cpp
index 66d53e7d..aaae4c44 100644
--- a/src/obj/NiRollController.cpp
+++ b/src/obj/NiRollController.cpp
@@ -56,10 +56,15 @@ void NiRollController::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	//--END CUSTOM CODE--//
 
 	NiSingleInterpController::Write( out, link_map, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiSequence.cpp b/src/obj/NiSequence.cpp
index d423842e..3e6765e7 100644
--- a/src/obj/NiSequence.cpp
+++ b/src/obj/NiSequence.cpp
@@ -132,10 +132,15 @@ void NiSequence::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 	NifStream( name, out, info );
 	if ( info.version <= 0x0A010000 ) {
 		NifStream( textKeysName, out, info );
-		if ( textKeys != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(textKeys) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*textKeys), out, info );
+		} else {
+			if ( textKeys != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(textKeys) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( numControlledBlocks, out, info );
 	if ( info.version >= 0x0A01006A ) {
@@ -144,26 +149,46 @@ void NiSequence::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 	for (unsigned int i1 = 0; i1 < controlledBlocks.size(); i1++) {
 		if ( info.version <= 0x0A010000 ) {
 			NifStream( controlledBlocks[i1].targetName, out, info );
-			if ( controlledBlocks[i1].controller != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].controller) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*controlledBlocks[i1].controller), out, info );
+			} else {
+				if ( controlledBlocks[i1].controller != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].controller) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 		if ( info.version >= 0x0A01006A ) {
-			if ( controlledBlocks[i1].interpolator != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].interpolator) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-			if ( controlledBlocks[i1].controller != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].controller) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*controlledBlocks[i1].interpolator), out, info );
+			} else {
+				if ( controlledBlocks[i1].interpolator != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].interpolator) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*controlledBlocks[i1].controller), out, info );
+			} else {
+				if ( controlledBlocks[i1].controller != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].controller) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 		if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
-			if ( controlledBlocks[i1].unknownLink2 != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].unknownLink2) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*controlledBlocks[i1].unknownLink2), out, info );
+			} else {
+				if ( controlledBlocks[i1].unknownLink2 != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].unknownLink2) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 			NifStream( controlledBlocks[i1].unknownShort0, out, info );
 		};
 		if ( ( info.version >= 0x0A01006A ) && ( info.userVersion == 10 ) ) {
@@ -173,10 +198,15 @@ void NiSequence::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 			NifStream( controlledBlocks[i1].priority_, out, info );
 		};
 		if ( info.version >= 0x0A020000 ) {
-			if ( controlledBlocks[i1].stringPalette != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].stringPalette) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*controlledBlocks[i1].stringPalette), out, info );
+			} else {
+				if ( controlledBlocks[i1].stringPalette != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(controlledBlocks[i1].stringPalette) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 		if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
 			NifStream( controlledBlocks[i1].nodeName, out, info );
diff --git a/src/obj/NiSingleInterpController.cpp b/src/obj/NiSingleInterpController.cpp
index 247c7f06..a7b977d0 100644
--- a/src/obj/NiSingleInterpController.cpp
+++ b/src/obj/NiSingleInterpController.cpp
@@ -59,10 +59,15 @@ void NiSingleInterpController::Write( ostream& out, const map<NiObjectRef,unsign
 
 	NiInterpController::Write( out, link_map, info );
 	if ( info.version >= 0x0A020000 ) {
-		if ( interpolator != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(interpolator) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*interpolator), out, info );
+		} else {
+			if ( interpolator != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(interpolator) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiSkinData.cpp b/src/obj/NiSkinData.cpp
index 5334f235..bdefaeeb 100644
--- a/src/obj/NiSkinData.cpp
+++ b/src/obj/NiSkinData.cpp
@@ -102,10 +102,15 @@ void NiSkinData::Write( ostream& out, const map<NiObjectRef,unsigned int> & link
 	NifStream( scale, out, info );
 	NifStream( numBones, out, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( skinPartition != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(skinPartition) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*skinPartition), out, info );
+		} else {
+			if ( skinPartition != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(skinPartition) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	if ( info.version >= 0x04020100 ) {
 		NifStream( hasVertexWeights, out, info );
diff --git a/src/obj/NiSkinInstance.cpp b/src/obj/NiSkinInstance.cpp
index 363517fa..38bed632 100644
--- a/src/obj/NiSkinInstance.cpp
+++ b/src/obj/NiSkinInstance.cpp
@@ -83,26 +83,46 @@ void NiSkinInstance::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 
 	NiObject::Write( out, link_map, info );
 	numBones = (unsigned int)(bones.size());
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version >= 0x0A020000 ) {
-		if ( skinPartition != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(skinPartition) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*skinPartition), out, info );
+		} else {
+			if ( skinPartition != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(skinPartition) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
-	if ( skeletonRoot != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(skeletonRoot) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*skeletonRoot), out, info );
+	} else {
+		if ( skeletonRoot != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(skeletonRoot) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( numBones, out, info );
 	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
-		if ( bones[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(bones[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*bones[i1]), out, info );
+		} else {
+			if ( bones[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(bones[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiSourceTexture.cpp b/src/obj/NiSourceTexture.cpp
index 27527ee3..97cc2455 100644
--- a/src/obj/NiSourceTexture.cpp
+++ b/src/obj/NiSourceTexture.cpp
@@ -92,10 +92,15 @@ void NiSourceTexture::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	};
 	if ( info.version >= 0x0A010000 ) {
 		if ( (useExternal == 1) ) {
-			if ( unknownLink != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
+			if ( info.version < VER_3_3_0_13 ) {
+				NifStream( (unsigned int)&(*unknownLink), out, info );
+			} else {
+				if ( unknownLink != NULL ) {
+					NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
+				} else {
+					NifStream( 0xFFFFFFFF, out, info );
+				}
+			}
 		};
 	};
 	if ( info.version <= 0x0A000100 ) {
@@ -109,10 +114,15 @@ void NiSourceTexture::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 		};
 	};
 	if ( (useExternal == 0) ) {
-		if ( pixelData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(pixelData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*pixelData), out, info );
+		} else {
+			if ( pixelData != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(pixelData) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( pixelLayout, out, info );
 	NifStream( useMipmaps, out, info );
diff --git a/src/obj/NiSpecularProperty.cpp b/src/obj/NiSpecularProperty.cpp
index b5463298..b5306420 100644
--- a/src/obj/NiSpecularProperty.cpp
+++ b/src/obj/NiSpecularProperty.cpp
@@ -91,6 +91,14 @@ std::list<NiObjectRef> NiSpecularProperty::GetRefs() const {
 
 //--BEGIN MISC CUSTOM CODE--//
 
+bool NiSpecularProperty::GetSpecularState() const {
+	return UnpackFlag<unsigned short>( flags, 0 );
+}
+
+void NiSpecularProperty::SetSpecularState( bool n ) {
+	PackFlag<unsigned short>( flags, (unsigned short)n, 0 );
+}
+
 unsigned short NiSpecularProperty::GetFlags() const {
    return flags;
 }
diff --git a/src/obj/NiTextureEffect.cpp b/src/obj/NiTextureEffect.cpp
index e59809cc..592f3c15 100644
--- a/src/obj/NiTextureEffect.cpp
+++ b/src/obj/NiTextureEffect.cpp
@@ -78,10 +78,15 @@ void NiTextureEffect::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	NifStream( textureClamping, out, info );
 	NifStream( textureType, out, info );
 	NifStream( coordinateGenerationType, out, info );
-	if ( sourceTexture != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(sourceTexture) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*sourceTexture), out, info );
+	} else {
+		if ( sourceTexture != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(sourceTexture) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( clippingPlane, out, info );
 	NifStream( unknownVector, out, info );
 	NifStream( unknownFloat, out, info );
diff --git a/src/obj/NiTextureProperty.cpp b/src/obj/NiTextureProperty.cpp
index cff0b4af..358386b2 100644
--- a/src/obj/NiTextureProperty.cpp
+++ b/src/obj/NiTextureProperty.cpp
@@ -62,10 +62,15 @@ void NiTextureProperty::Write( ostream& out, const map<NiObjectRef,unsigned int>
 
 	NiProperty::Write( out, link_map, info );
 	NifStream( flags, out, info );
-	if ( image != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(image) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*image), out, info );
+	} else {
+		if ( image != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(image) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	if ( info.version <= 0x03000300 ) {
 		NifStream( unknownInt1, out, info );
 		NifStream( unknownInt2, out, info );
diff --git a/src/obj/NiTextureTransformController.cpp b/src/obj/NiTextureTransformController.cpp
index 2a3c2bcf..3c5ddd19 100644
--- a/src/obj/NiTextureTransformController.cpp
+++ b/src/obj/NiTextureTransformController.cpp
@@ -65,10 +65,15 @@ void NiTextureTransformController::Write( ostream& out, const map<NiObjectRef,un
 	NifStream( textureSlot, out, info );
 	NifStream( operation, out, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/NiTexturingProperty.cpp b/src/obj/NiTexturingProperty.cpp
index 55cdc60d..84ddeb31 100644
--- a/src/obj/NiTexturingProperty.cpp
+++ b/src/obj/NiTexturingProperty.cpp
@@ -380,10 +380,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	NifStream( textureCount, out, info );
 	NifStream( hasBaseTexture, out, info );
 	if ( (hasBaseTexture != 0) ) {
-		if ( baseTexture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(baseTexture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*baseTexture.source), out, info );
+		} else {
+			if ( baseTexture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(baseTexture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( baseTexture.clampMode, out, info );
 		NifStream( baseTexture.filterMode, out, info );
 		NifStream( baseTexture.uvSet, out, info );
@@ -407,10 +412,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	};
 	NifStream( hasDarkTexture, out, info );
 	if ( (hasDarkTexture != 0) ) {
-		if ( darkTexture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(darkTexture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*darkTexture.source), out, info );
+		} else {
+			if ( darkTexture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(darkTexture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( darkTexture.clampMode, out, info );
 		NifStream( darkTexture.filterMode, out, info );
 		NifStream( darkTexture.uvSet, out, info );
@@ -434,10 +444,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	};
 	NifStream( hasDetailTexture, out, info );
 	if ( (hasDetailTexture != 0) ) {
-		if ( detailTexture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(detailTexture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*detailTexture.source), out, info );
+		} else {
+			if ( detailTexture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(detailTexture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( detailTexture.clampMode, out, info );
 		NifStream( detailTexture.filterMode, out, info );
 		NifStream( detailTexture.uvSet, out, info );
@@ -461,10 +476,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	};
 	NifStream( hasGlossTexture, out, info );
 	if ( (hasGlossTexture != 0) ) {
-		if ( glossTexture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(glossTexture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*glossTexture.source), out, info );
+		} else {
+			if ( glossTexture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(glossTexture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( glossTexture.clampMode, out, info );
 		NifStream( glossTexture.filterMode, out, info );
 		NifStream( glossTexture.uvSet, out, info );
@@ -488,10 +508,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	};
 	NifStream( hasGlowTexture, out, info );
 	if ( (hasGlowTexture != 0) ) {
-		if ( glowTexture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(glowTexture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*glowTexture.source), out, info );
+		} else {
+			if ( glowTexture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(glowTexture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( glowTexture.clampMode, out, info );
 		NifStream( glowTexture.filterMode, out, info );
 		NifStream( glowTexture.uvSet, out, info );
@@ -515,10 +540,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	};
 	NifStream( hasBumpMapTexture, out, info );
 	if ( (hasBumpMapTexture != 0) ) {
-		if ( bumpMapTexture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(bumpMapTexture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*bumpMapTexture.source), out, info );
+		} else {
+			if ( bumpMapTexture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(bumpMapTexture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( bumpMapTexture.clampMode, out, info );
 		NifStream( bumpMapTexture.filterMode, out, info );
 		NifStream( bumpMapTexture.uvSet, out, info );
@@ -545,10 +575,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 	};
 	NifStream( hasDecal0Texture, out, info );
 	if ( (hasDecal0Texture != 0) ) {
-		if ( decal0Texture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(decal0Texture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*decal0Texture.source), out, info );
+		} else {
+			if ( decal0Texture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(decal0Texture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( decal0Texture.clampMode, out, info );
 		NifStream( decal0Texture.filterMode, out, info );
 		NifStream( decal0Texture.uvSet, out, info );
@@ -574,10 +609,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 		NifStream( hasDecal1Texture, out, info );
 	};
 	if ( (((textureCount >= 8)) && ((hasDecal1Texture != 0))) ) {
-		if ( decal1Texture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(decal1Texture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*decal1Texture.source), out, info );
+		} else {
+			if ( decal1Texture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(decal1Texture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( decal1Texture.clampMode, out, info );
 		NifStream( decal1Texture.filterMode, out, info );
 		NifStream( decal1Texture.uvSet, out, info );
@@ -603,10 +643,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 		NifStream( hasDecal2Texture, out, info );
 	};
 	if ( (((textureCount >= 9)) && ((hasDecal2Texture != 0))) ) {
-		if ( decal2Texture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(decal2Texture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*decal2Texture.source), out, info );
+		} else {
+			if ( decal2Texture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(decal2Texture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( decal2Texture.clampMode, out, info );
 		NifStream( decal2Texture.filterMode, out, info );
 		NifStream( decal2Texture.uvSet, out, info );
@@ -632,10 +677,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 		NifStream( hasDecal3Texture, out, info );
 	};
 	if ( (((textureCount >= 10)) && ((hasDecal3Texture != 0))) ) {
-		if ( decal3Texture.source != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(decal3Texture.source) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*decal3Texture.source), out, info );
+		} else {
+			if ( decal3Texture.source != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(decal3Texture.source) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 		NifStream( decal3Texture.clampMode, out, info );
 		NifStream( decal3Texture.filterMode, out, info );
 		NifStream( decal3Texture.uvSet, out, info );
@@ -662,10 +712,15 @@ void NiTexturingProperty::Write( ostream& out, const map<NiObjectRef,unsigned in
 		for (unsigned int i2 = 0; i2 < shaderTextures.size(); i2++) {
 			NifStream( shaderTextures[i2].isUsed, out, info );
 			if ( (shaderTextures[i2].isUsed != 0) ) {
-				if ( shaderTextures[i2].textureData.source != NULL )
-					NifStream( link_map.find( StaticCast<NiObject>(shaderTextures[i2].textureData.source) )->second, out, info );
-				else
-					NifStream( 0xffffffff, out, info );
+				if ( info.version < VER_3_3_0_13 ) {
+					NifStream( (unsigned int)&(*shaderTextures[i2].textureData.source), out, info );
+				} else {
+					if ( shaderTextures[i2].textureData.source != NULL ) {
+						NifStream( link_map.find( StaticCast<NiObject>(shaderTextures[i2].textureData.source) )->second, out, info );
+					} else {
+						NifStream( 0xFFFFFFFF, out, info );
+					}
+				}
 				NifStream( shaderTextures[i2].textureData.clampMode, out, info );
 				NifStream( shaderTextures[i2].textureData.filterMode, out, info );
 				NifStream( shaderTextures[i2].textureData.uvSet, out, info );
diff --git a/src/obj/NiTimeController.cpp b/src/obj/NiTimeController.cpp
index 0c623282..9cd08a93 100644
--- a/src/obj/NiTimeController.cpp
+++ b/src/obj/NiTimeController.cpp
@@ -63,19 +63,29 @@ void NiTimeController::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	//--END CUSTOM CODE--//
 
 	NiObject::Write( out, link_map, info );
-	if ( nextController != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(nextController) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*nextController), out, info );
+	} else {
+		if ( nextController != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(nextController) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( flags, out, info );
 	NifStream( frequency, out, info );
 	NifStream( phase, out, info );
 	NifStream( startTime, out, info );
 	NifStream( stopTime, out, info );
-	if ( target != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*target), out, info );
+	} else {
+		if ( target != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiTransformInterpolator.cpp b/src/obj/NiTransformInterpolator.cpp
index 2faaadef..2c75da73 100644
--- a/src/obj/NiTransformInterpolator.cpp
+++ b/src/obj/NiTransformInterpolator.cpp
@@ -72,10 +72,15 @@ void NiTransformInterpolator::Write( ostream& out, const map<NiObjectRef,unsigne
 			NifStream( unknownBytes[i2], out, info );
 		};
 	};
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiTriShapeSkinController.cpp b/src/obj/NiTriShapeSkinController.cpp
index b102668f..7ec16a9f 100644
--- a/src/obj/NiTriShapeSkinController.cpp
+++ b/src/obj/NiTriShapeSkinController.cpp
@@ -82,10 +82,15 @@ void NiTriShapeSkinController::Write( ostream& out, const map<NiObjectRef,unsign
 		NifStream( vertexCounts[i1], out, info );
 	};
 	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
-		if ( bones[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(bones[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*bones[i1]), out, info );
+		} else {
+			if ( bones[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(bones[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	for (unsigned int i1 = 0; i1 < boneData.size(); i1++) {
 		for (unsigned int i2 = 0; i2 < vertexCounts[i1]; i2++) {
diff --git a/src/obj/NiUVController.cpp b/src/obj/NiUVController.cpp
index e7b05440..abcef0ee 100644
--- a/src/obj/NiUVController.cpp
+++ b/src/obj/NiUVController.cpp
@@ -58,10 +58,15 @@ void NiUVController::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 
 	NiTimeController::Write( out, link_map, info );
 	NifStream( unknownShort, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/NiVisController.cpp b/src/obj/NiVisController.cpp
index e7f881dd..9b75c545 100644
--- a/src/obj/NiVisController.cpp
+++ b/src/obj/NiVisController.cpp
@@ -59,10 +59,15 @@ void NiVisController::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 
 	NiBoolInterpController::Write( out, link_map, info );
 	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
+		} else {
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
diff --git a/src/obj/bhkConstraint.cpp b/src/obj/bhkConstraint.cpp
index db542cd1..07676eb0 100644
--- a/src/obj/bhkConstraint.cpp
+++ b/src/obj/bhkConstraint.cpp
@@ -64,10 +64,15 @@ void bhkConstraint::Write( ostream& out, const map<NiObjectRef,unsigned int> & l
 	numEntities = (unsigned int)(entities.size());
 	NifStream( numEntities, out, info );
 	for (unsigned int i1 = 0; i1 < entities.size(); i1++) {
-		if ( entities[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(entities[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*entities[i1]), out, info );
+		} else {
+			if ( entities[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(entities[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( priority, out, info );
 
diff --git a/src/obj/bhkListShape.cpp b/src/obj/bhkListShape.cpp
index 2b109e83..4623e907 100644
--- a/src/obj/bhkListShape.cpp
+++ b/src/obj/bhkListShape.cpp
@@ -73,10 +73,15 @@ void bhkListShape::Write( ostream& out, const map<NiObjectRef,unsigned int> & li
 	numSubShapes = (unsigned int)(subShapes.size());
 	NifStream( numSubShapes, out, info );
 	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		if ( subShapes[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(subShapes[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*subShapes[i1]), out, info );
+		} else {
+			if ( subShapes[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(subShapes[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( material, out, info );
 	for (unsigned int i1 = 0; i1 < 6; i1++) {
diff --git a/src/obj/bhkMalleableConstraint.cpp b/src/obj/bhkMalleableConstraint.cpp
index c6db9325..ae401edb 100644
--- a/src/obj/bhkMalleableConstraint.cpp
+++ b/src/obj/bhkMalleableConstraint.cpp
@@ -93,14 +93,24 @@ void bhkMalleableConstraint::Write( ostream& out, const map<NiObjectRef,unsigned
 	bhkConstraint::Write( out, link_map, info );
 	NifStream( type, out, info );
 	NifStream( unknownInt2, out, info );
-	if ( unknownLink1 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( unknownLink2 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink1), out, info );
+	} else {
+		if ( unknownLink1 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*unknownLink2), out, info );
+	} else {
+		if ( unknownLink2 != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( unknownInt3, out, info );
 	if ( (type == 7) ) {
 		NifStream( ragdoll.pivotA, out, info );
diff --git a/src/obj/bhkMoppBvTreeShape.cpp b/src/obj/bhkMoppBvTreeShape.cpp
index 5928f5ad..0562d76a 100644
--- a/src/obj/bhkMoppBvTreeShape.cpp
+++ b/src/obj/bhkMoppBvTreeShape.cpp
@@ -71,10 +71,15 @@ void bhkMoppBvTreeShape::Write( ostream& out, const map<NiObjectRef,unsigned int
 
 	bhkBvTreeShape::Write( out, link_map, info );
 	moppDataSize = (unsigned int)(moppData.size());
-	if ( shape != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*shape), out, info );
+	} else {
+		if ( shape != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( material, out, info );
 	for (unsigned int i1 = 0; i1 < 8; i1++) {
 		NifStream( unknown8Bytes[i1], out, info );
diff --git a/src/obj/bhkNiTriStripsShape.cpp b/src/obj/bhkNiTriStripsShape.cpp
index 2b1e7fc1..6db9ad0f 100644
--- a/src/obj/bhkNiTriStripsShape.cpp
+++ b/src/obj/bhkNiTriStripsShape.cpp
@@ -90,10 +90,15 @@ void bhkNiTriStripsShape::Write( ostream& out, const map<NiObjectRef,unsigned in
 	NifStream( unknownInt3, out, info );
 	NifStream( numStripsData, out, info );
 	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
-		if ( stripsData[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(stripsData[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*stripsData[i1]), out, info );
+		} else {
+			if ( stripsData[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(stripsData[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( numDataLayers, out, info );
 	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
diff --git a/src/obj/bhkPackedNiTriStripsShape.cpp b/src/obj/bhkPackedNiTriStripsShape.cpp
index daa1256a..547bed2c 100644
--- a/src/obj/bhkPackedNiTriStripsShape.cpp
+++ b/src/obj/bhkPackedNiTriStripsShape.cpp
@@ -89,10 +89,15 @@ void bhkPackedNiTriStripsShape::Write( ostream& out, const map<NiObjectRef,unsig
 	for (unsigned int i1 = 0; i1 < 3; i1++) {
 		NifStream( unknownFloats2[i1], out, info );
 	};
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*data), out, info );
+	} else {
+		if ( data != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
diff --git a/src/obj/bhkRigidBody.cpp b/src/obj/bhkRigidBody.cpp
index 37317a0a..5e80d8d4 100644
--- a/src/obj/bhkRigidBody.cpp
+++ b/src/obj/bhkRigidBody.cpp
@@ -151,10 +151,15 @@ void bhkRigidBody::Write( ostream& out, const map<NiObjectRef,unsigned int> & li
 	NifStream( unknownInt8, out, info );
 	NifStream( numConstraints, out, info );
 	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
-		if ( constraints[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(constraints[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*constraints[i1]), out, info );
+		} else {
+			if ( constraints[i1] != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(constraints[i1]) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
+		}
 	};
 	NifStream( unknownInt6, out, info );
 
diff --git a/src/obj/bhkTransformShape.cpp b/src/obj/bhkTransformShape.cpp
index 040eabf6..b1bfbe7f 100644
--- a/src/obj/bhkTransformShape.cpp
+++ b/src/obj/bhkTransformShape.cpp
@@ -62,10 +62,15 @@ void bhkTransformShape::Write( ostream& out, const map<NiObjectRef,unsigned int>
 	//--END CUSTOM CODE--//
 
 	bhkShape::Write( out, link_map, info );
-	if ( shape != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*shape), out, info );
+	} else {
+		if ( shape != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( material, out, info );
 	NifStream( unknownFloat1, out, info );
 	for (unsigned int i1 = 0; i1 < 8; i1++) {
diff --git a/src/obj/bhkWorldObject.cpp b/src/obj/bhkWorldObject.cpp
index 556f659a..fa898854 100644
--- a/src/obj/bhkWorldObject.cpp
+++ b/src/obj/bhkWorldObject.cpp
@@ -59,10 +59,15 @@ void bhkWorldObject::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	//--END CUSTOM CODE--//
 
 	bhkSerializable::Write( out, link_map, info );
-	if ( shape != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	if ( info.version < VER_3_3_0_13 ) {
+		NifStream( (unsigned int)&(*shape), out, info );
+	} else {
+		if ( shape != NULL ) {
+			NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
+		} else {
+			NifStream( 0xFFFFFFFF, out, info );
+		}
+	}
 	NifStream( layer, out, info );
 	NifStream( colFilter, out, info );
 	NifStream( unknownShort, out, info );
-- 
GitLab