From f1e8cd498d905f1688d9a41fdd7739d5c7f56ac5 Mon Sep 17 00:00:00 2001
From: Tazpn <tazpn@users.sourceforge.net>
Date: Sun, 20 Aug 2006 00:34:05 +0000
Subject: [PATCH] 1. Fix issue with exporting with user version specified. 
 Oblivion CS will crash if not set correctly. 2. Fix issues with nif export in
 general around bhk ordering (ported over from gundalfs changes) 3. Civ4
 Shader support for max 4. Numerous bug fixes to max.

---
 niflib.cpp                  | 42 +++++++++++++++++++++++++++----------
 obj/NiAlphaProperty.cpp     |  2 +-
 obj/bhkNiTriStripsShape.cpp |  5 +++++
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/niflib.cpp b/niflib.cpp
index a906b6d3..4bb3a4d5 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -25,6 +25,7 @@ All rights reserved.  Please see niflib.h for licence. */
 #include "obj/NiKeyframeData.h"
 #include "obj/NiStringExtraData.h"
 #include "obj/NiExtraData.h"
+#include "obj/bhkRigidBody.h"
 #include "gen/header.h"
 #include "gen/footer.h"
 
@@ -319,6 +320,7 @@ void WriteNifTree( ostream & out, NiObjectRef const & root, unsigned int version
 	Header header;
 	header.version = version;
 	header.userVersion = user_version;
+   header.userVersion2 = user_version;
 	
 	//Set Type Names
 	header.blockTypes.resize( types.size() );
@@ -374,9 +376,6 @@ void EnumerateObjects( NiObjectRef const & root, map<Type*,uint> & type_map, map
 		return;
 	}
 
-	//Add object to link map
-	link_map[root] = uint(link_map.size());
-
 	//Add this object type to the map if it isn't there already
 	if ( type_map.find( (Type*)&(root->GetType()) ) == type_map.end() ) {
 		//The type has not yet been registered, so register it
@@ -384,14 +383,35 @@ void EnumerateObjects( NiObjectRef const & root, map<Type*,uint> & type_map, map
 		type_map[ (Type*)&(root->GetType()) ] = uint(type_map.size());
 	}
 
-	//Call this function on all links of this object
-	
-	list<NiObjectRef> links = root->GetRefs();
-	for ( list<NiObjectRef>::iterator it = links.begin(); it != links.end(); ++it ) {
-		if ( *it != NULL ) {
-			EnumerateObjects( *it, type_map, link_map );
-		}
-	}
+   // Oblivion has very rigid requirements about block ordering and the bhkRigidBody 
+   //   must be after its children. Hopefully this can be removed and replaced with 
+   //   a more generic mechanism in the future.
+	Type *t = (Type*)&(root->GetType());
+   if (t->IsDerivedType(bhkRigidBody::TypeConst()))
+   {
+      //Call this function on all links of this object
+      list<NiObjectRef> links = root->GetRefs();
+      for ( list<NiObjectRef>::iterator it = links.begin(); it != links.end(); ++it ) {
+         if ( *it != NULL ) {
+            EnumerateObjects( *it, type_map, link_map );
+         }
+      }
+      //Add object to link map
+      link_map[root] = uint(link_map.size());
+   } 
+   else
+   {
+      //Add object to link map
+      link_map[root] = uint(link_map.size());
+
+      //Call this function on all links of this object	
+      list<NiObjectRef> links = root->GetRefs();
+      for ( list<NiObjectRef>::iterator it = links.begin(); it != links.end(); ++it ) {
+         if ( *it != NULL ) {
+            EnumerateObjects( *it, type_map, link_map );
+         }
+      }
+   }
 }
 
 //void BuildUpBindPositions( const NiAVObjectRef & root ) {
diff --git a/obj/NiAlphaProperty.cpp b/obj/NiAlphaProperty.cpp
index b8b3c721..baec44a2 100644
--- a/obj/NiAlphaProperty.cpp
+++ b/obj/NiAlphaProperty.cpp
@@ -55,7 +55,7 @@ void NiAlphaProperty::SetAlphaTestThreshold( byte n ) {
    (( value >> shift ) & mask)
 
 #define NIFLIB_MASK_FLAG(flag, value, shift, mask) \
-   ((flag ^ ~(mask << shift)) | ((value & mask) << shift))
+   ((flag & ~(mask << shift)) | ((value & mask) << shift))
 
 NiAlphaProperty::BlendMode NiAlphaProperty::GetSourceBlendMode() const {
    return (NiAlphaProperty::BlendMode)NIFLIB_GET_FLAG(flags, 1, 0x0f);
diff --git a/obj/bhkNiTriStripsShape.cpp b/obj/bhkNiTriStripsShape.cpp
index 6077a69f..ac3334e0 100644
--- a/obj/bhkNiTriStripsShape.cpp
+++ b/obj/bhkNiTriStripsShape.cpp
@@ -40,6 +40,11 @@ void bhkNiTriStripsShape::SetNumStripsData(int n)
 {
 	numStripsData = n;
 	stripsData.resize(n);
+
+   // This is currently a kludge for compatibility with the max NifExporter as we dont know what this 
+   //   does but its always same number of strips and usually 1 or 4
+   numUnknownInts2 = n;
+   unknownInts2.assign(n, 1);
 }
 
 void bhkNiTriStripsShape::SetStripsData(int i, Ref<NiTriStripsData> &strips)
-- 
GitLab