From 8a7ead363bd7f4a13d0fa9c3b7f2a9c362e6c55a Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Tue, 26 Sep 2006 19:54:51 +0000
Subject: [PATCH] Updated from XML.  Improves support for FFvt3R, but there are
 still problems that down show up in NifSkope.

---
 include/gen/obj_defines.h               | 26 ++++---
 include/obj/NiPSysEmitterSpeedCtlr.h    |  2 +
 include/obj/NiPSysGravityStrengthCtlr.h |  2 +
 src/gen/obj_impl.cpp                    | 97 +++++++++++++++++++------
 src/obj/NiPSysEmitterSpeedCtlr.cpp      |  2 +
 src/obj/NiPSysGravityStrengthCtlr.cpp   |  1 +
 6 files changed, 97 insertions(+), 33 deletions(-)

diff --git a/include/gen/obj_defines.h b/include/gen/obj_defines.h
index 610eb652..fbb50cc7 100644
--- a/include/gen/obj_defines.h
+++ b/include/gen/obj_defines.h
@@ -480,13 +480,13 @@ uint unknownInt2; \
 
 #define NI_COLLISION_DATA_MEMBERS \
 NiNode * targetNode; \
-uint unknown2; \
-byte unknown3; \
+uint unknownInt1; \
+uint unknownInt2; \
+byte unknownByte; \
 uint collisionType; \
-uint unknown5; \
-Vector3 unknown7; \
-array<8,float> unknown6; \
-array<15,float> unknown8; \
+Vector3 unknownVector; \
+array<8,float> unknownFloat1; \
+array<15,float> unknownFloat2; \
 
 #define NI_COLOR_DATA_MEMBERS \
 KeyGroup<Color4 > data; \
@@ -924,6 +924,7 @@ vector<Key<byte > > visibilityKeys_; \
 #define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_MEMBERS \
 
 #define NI_P_SYS_EMITTER_SPEED_CTLR_MEMBERS \
+Ref<NiFloatData > unknownLink; \
 
 #define NI_P_SYS_GRAVITY_MODIFIER_MEMBERS \
 NiNode * gravityObject; \
@@ -935,6 +936,7 @@ float turbulence; \
 float turbulenceScale; \
 
 #define NI_P_SYS_GRAVITY_STRENGTH_CTLR_MEMBERS \
+Ref<NiFloatData > unknownLink; \
 
 #define NI_P_SYS_GROW_FADE_MODIFIER_MEMBERS \
 float growTime; \
@@ -954,6 +956,7 @@ mutable uint numMeshes; \
 vector<Ref<NiNode > > meshes; \
 
 #define NI_P_SYS_MODIFIER_ACTIVE_CTLR_MEMBERS \
+uint unknownInt; \
 
 #define NI_P_SYS_PLANAR_COLLIDER_MEMBERS \
 float bounce; \
@@ -1931,7 +1934,7 @@ CompareMode function; \
 
 #define NI_COLLISION_DATA_PARENT NiObject
 
-#define NI_COLLISION_DATA_CONSTRUCT  : targetNode(NULL), unknown2((uint)0), unknown3((byte)0), collisionType((uint)0), unknown5((uint)0)
+#define NI_COLLISION_DATA_CONSTRUCT  : targetNode(NULL), unknownInt1((uint)0), unknownInt2((uint)0), unknownByte((byte)0), collisionType((uint)0)
 
 #define NI_COLOR_DATA_INCLUDE "AKeyedData.h"
 
@@ -2374,7 +2377,8 @@ CompareMode function; \
 
 #define NI_P_SYS_EMITTER_SPEED_CTLR_PARENT APSysCtlr
 
-#define NI_P_SYS_EMITTER_SPEED_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_SPEED_CTLR_CONSTRUCT  : unknownLink(NULL)
+
 #define NI_P_SYS_GRAVITY_MODIFIER_INCLUDE "NiPSysModifier.h"
 
 #define NI_P_SYS_GRAVITY_MODIFIER_PARENT NiPSysModifier
@@ -2385,7 +2389,8 @@ CompareMode function; \
 
 #define NI_P_SYS_GRAVITY_STRENGTH_CTLR_PARENT APSysCtlr
 
-#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_CONSTRUCT 
+#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_CONSTRUCT  : unknownLink(NULL)
+
 #define NI_P_SYS_GROW_FADE_MODIFIER_INCLUDE "NiPSysModifier.h"
 
 #define NI_P_SYS_GROW_FADE_MODIFIER_PARENT NiPSysModifier
@@ -2408,7 +2413,8 @@ CompareMode function; \
 
 #define NI_P_SYS_MODIFIER_ACTIVE_CTLR_PARENT APSysCtlr
 
-#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_CONSTRUCT 
+#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_CONSTRUCT  : unknownInt((uint)0)
+
 #define NI_P_SYS_PLANAR_COLLIDER_INCLUDE "NiObject.h"
 
 #define NI_P_SYS_PLANAR_COLLIDER_PARENT NiObject
diff --git a/include/obj/NiPSysEmitterSpeedCtlr.h b/include/obj/NiPSysEmitterSpeedCtlr.h
index f333c891..a05f92c3 100644
--- a/include/obj/NiPSysEmitterSpeedCtlr.h
+++ b/include/obj/NiPSysEmitterSpeedCtlr.h
@@ -7,6 +7,8 @@ All rights reserved.  Please see niflib.h for licence. */
 #include "APSysCtlr.h"
 namespace Niflib {
 
+// Forward define of referenced blocks
+class NiFloatData;
 
 #include "../gen/obj_defines.h"
 
diff --git a/include/obj/NiPSysGravityStrengthCtlr.h b/include/obj/NiPSysGravityStrengthCtlr.h
index ba4a7283..fa7f5973 100644
--- a/include/obj/NiPSysGravityStrengthCtlr.h
+++ b/include/obj/NiPSysGravityStrengthCtlr.h
@@ -7,6 +7,8 @@ All rights reserved.  Please see niflib.h for licence. */
 #include "APSysCtlr.h"
 namespace Niflib {
 
+// Forward define of referenced blocks
+class NiFloatData;
 
 #include "../gen/obj_defines.h"
 
diff --git a/src/gen/obj_impl.cpp b/src/gen/obj_impl.cpp
index febf4390..6c97682e 100644
--- a/src/gen/obj_impl.cpp
+++ b/src/gen/obj_impl.cpp
@@ -1256,7 +1256,9 @@ void NiPSysEmitter::InternalRead( istream& in, list<uint> & link_stack, unsigned
 	NifStream( planarAngleVariation, in, version );
 	NifStream( initialColor, in, version );
 	NifStream( initialRadius, in, version );
-	NifStream( radiusVariation, in, version );
+	if ( version >= 0x14000004 ) {
+		NifStream( radiusVariation, in, version );
+	};
 	NifStream( lifeSpan, in, version );
 	NifStream( lifeSpanVariation, in, version );
 }
@@ -1271,7 +1273,9 @@ void NiPSysEmitter::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map,
 	NifStream( planarAngleVariation, out, version );
 	NifStream( initialColor, out, version );
 	NifStream( initialRadius, out, version );
-	NifStream( radiusVariation, out, version );
+	if ( version >= 0x14000004 ) {
+		NifStream( radiusVariation, out, version );
+	};
 	NifStream( lifeSpan, out, version );
 	NifStream( lifeSpanVariation, out, version );
 }
@@ -1306,7 +1310,7 @@ std::list<NiObjectRef> NiPSysEmitter::InternalGetRefs() const {
 void NiPSysVolumeEmitter::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	uint block_num;
 	NiPSysEmitter::Read( in, link_stack, version, user_version );
-	if ( version >= 0x14000004 ) {
+	if ( version >= 0x0A010000 ) {
 		NifStream( block_num, in, version );
 		link_stack.push_back( block_num );
 	};
@@ -1314,7 +1318,7 @@ void NiPSysVolumeEmitter::InternalRead( istream& in, list<uint> & link_stack, un
 
 void NiPSysVolumeEmitter::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
 	NiPSysEmitter::Write( out, link_map, version, user_version );
-	if ( version >= 0x14000004 ) {
+	if ( version >= 0x0A010000 ) {
 		if ( emitterObject != NULL )
 			NifStream( link_map[StaticCast<NiObject>(emitterObject)], out, version );
 		else
@@ -1331,7 +1335,7 @@ std::string NiPSysVolumeEmitter::InternalAsString( bool verbose ) const {
 
 void NiPSysVolumeEmitter::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	NiPSysEmitter::FixLinks( objects, link_stack, version, user_version );
-	if ( version >= 0x14000004 ) {
+	if ( version >= 0x0A010000 ) {
 		emitterObject = FixLink<NiNode>( objects, link_stack, version );
 	};
 }
@@ -4528,21 +4532,24 @@ void NiCollisionData::InternalRead( istream& in, list<uint> & link_stack, unsign
 	NiObject::Read( in, link_stack, version, user_version );
 	NifStream( block_num, in, version );
 	link_stack.push_back( block_num );
-	NifStream( unknown2, in, version );
-	NifStream( unknown3, in, version );
+	NifStream( unknownInt1, in, version );
+	if ( ( version >= 0x0A010000 ) && ( version <= 0x0A010000 ) ) {
+		NifStream( unknownInt2, in, version );
+	};
+	NifStream( unknownByte, in, version );
 	NifStream( collisionType, in, version );
 	if ( (collisionType == 0) ) {
-		NifStream( unknown5, in, version );
-		NifStream( unknown7, in, version );
+		NifStream( unknownInt2, in, version );
+		NifStream( unknownVector, in, version );
 	};
 	if ( (collisionType == 2) ) {
 		for (uint i2 = 0; i2 < 8; i2++) {
-			NifStream( unknown6[i2], in, version );
+			NifStream( unknownFloat1[i2], in, version );
 		};
 	};
 	if ( (collisionType == 1) ) {
 		for (uint i2 = 0; i2 < 15; i2++) {
-			NifStream( unknown8[i2], in, version );
+			NifStream( unknownFloat2[i2], in, version );
 		};
 	};
 }
@@ -4553,21 +4560,24 @@ void NiCollisionData::InternalWrite( ostream& out, map<NiObjectRef,uint> link_ma
 		NifStream( link_map[StaticCast<NiObject>(targetNode)], out, version );
 	else
 		NifStream( 0xffffffff, out, version );
-	NifStream( unknown2, out, version );
-	NifStream( unknown3, out, version );
+	NifStream( unknownInt1, out, version );
+	if ( ( version >= 0x0A010000 ) && ( version <= 0x0A010000 ) ) {
+		NifStream( unknownInt2, out, version );
+	};
+	NifStream( unknownByte, out, version );
 	NifStream( collisionType, out, version );
 	if ( (collisionType == 0) ) {
-		NifStream( unknown5, out, version );
-		NifStream( unknown7, out, version );
+		NifStream( unknownInt2, out, version );
+		NifStream( unknownVector, out, version );
 	};
 	if ( (collisionType == 2) ) {
 		for (uint i2 = 0; i2 < 8; i2++) {
-			NifStream( unknown6[i2], out, version );
+			NifStream( unknownFloat1[i2], out, version );
 		};
 	};
 	if ( (collisionType == 1) ) {
 		for (uint i2 = 0; i2 < 15; i2++) {
-			NifStream( unknown8[i2], out, version );
+			NifStream( unknownFloat2[i2], out, version );
 		};
 	};
 }
@@ -4576,12 +4586,12 @@ std::string NiCollisionData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	out << NiObject::asString();
 	out << "  Target Node:  " << targetNode << endl;
-	out << "  Unknown2:  " << unknown2 << endl;
-	out << "  Unknown3:  " << unknown3 << endl;
+	out << "  Unknown Int 1:  " << unknownInt1 << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Unknown Byte:  " << unknownByte << endl;
 	out << "  Collision Type:  " << collisionType << endl;
 	if ( (collisionType == 0) ) {
-		out << "    Unknown5:  " << unknown5 << endl;
-		out << "    Unknown7:  " << unknown7 << endl;
+		out << "    Unknown Vector:  " << unknownVector << endl;
 	};
 	if ( (collisionType == 2) ) {
 		for (uint i2 = 0; i2 < 8; i2++) {
@@ -4589,7 +4599,7 @@ std::string NiCollisionData::InternalAsString( bool verbose ) const {
 				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 				break;
 			};
-			out << "      Unknown6[" << i2 << "]:  " << unknown6[i2] << endl;
+			out << "      Unknown Float 1[" << i2 << "]:  " << unknownFloat1[i2] << endl;
 		};
 	};
 	if ( (collisionType == 1) ) {
@@ -4598,7 +4608,7 @@ std::string NiCollisionData::InternalAsString( bool verbose ) const {
 				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 				break;
 			};
-			out << "      Unknown8[" << i2 << "]:  " << unknown8[i2] << endl;
+			out << "      Unknown Float 2[" << i2 << "]:  " << unknownFloat2[i2] << endl;
 		};
 	};
 	return out.str();
@@ -8910,26 +8920,43 @@ std::list<NiObjectRef> NiPSysEmitterLifeSpanCtlr::InternalGetRefs() const {
 }
 
 void NiPSysEmitterSpeedCtlr::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	uint block_num;
 	APSysCtlr::Read( in, link_stack, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		NifStream( block_num, in, version );
+		link_stack.push_back( block_num );
+	};
 }
 
 void NiPSysEmitterSpeedCtlr::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
 	APSysCtlr::Write( out, link_map, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		if ( unknownLink != NULL )
+			NifStream( link_map[StaticCast<NiObject>(unknownLink)], out, version );
+		else
+			NifStream( 0xffffffff, out, version );
+	};
 }
 
 std::string NiPSysEmitterSpeedCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	out << APSysCtlr::asString();
+	out << "  Unknown Link:  " << unknownLink << endl;
 	return out.str();
 }
 
 void NiPSysEmitterSpeedCtlr::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	APSysCtlr::FixLinks( objects, link_stack, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		unknownLink = FixLink<NiFloatData>( objects, link_stack, version );
+	};
 }
 
 std::list<NiObjectRef> NiPSysEmitterSpeedCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = APSysCtlr::GetRefs();
+	if ( unknownLink != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink));
 	return refs;
 }
 
@@ -8985,26 +9012,43 @@ std::list<NiObjectRef> NiPSysGravityModifier::InternalGetRefs() const {
 }
 
 void NiPSysGravityStrengthCtlr::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
+	uint block_num;
 	APSysCtlr::Read( in, link_stack, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		NifStream( block_num, in, version );
+		link_stack.push_back( block_num );
+	};
 }
 
 void NiPSysGravityStrengthCtlr::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
 	APSysCtlr::Write( out, link_map, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		if ( unknownLink != NULL )
+			NifStream( link_map[StaticCast<NiObject>(unknownLink)], out, version );
+		else
+			NifStream( 0xffffffff, out, version );
+	};
 }
 
 std::string NiPSysGravityStrengthCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	out << APSysCtlr::asString();
+	out << "  Unknown Link:  " << unknownLink << endl;
 	return out.str();
 }
 
 void NiPSysGravityStrengthCtlr::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	APSysCtlr::FixLinks( objects, link_stack, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		unknownLink = FixLink<NiFloatData>( objects, link_stack, version );
+	};
 }
 
 std::list<NiObjectRef> NiPSysGravityStrengthCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = APSysCtlr::GetRefs();
+	if ( unknownLink != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink));
 	return refs;
 }
 
@@ -9165,15 +9209,22 @@ std::list<NiObjectRef> NiPSysMeshUpdateModifier::InternalGetRefs() const {
 
 void NiPSysModifierActiveCtlr::InternalRead( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	APSysCtlr::Read( in, link_stack, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		NifStream( unknownInt, in, version );
+	};
 }
 
 void NiPSysModifierActiveCtlr::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
 	APSysCtlr::Write( out, link_map, version, user_version );
+	if ( version <= 0x0A010000 ) {
+		NifStream( unknownInt, out, version );
+	};
 }
 
 std::string NiPSysModifierActiveCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	out << APSysCtlr::asString();
+	out << "  Unknown Int:  " << unknownInt << endl;
 	return out.str();
 }
 
diff --git a/src/obj/NiPSysEmitterSpeedCtlr.cpp b/src/obj/NiPSysEmitterSpeedCtlr.cpp
index 482d9066..79741a50 100644
--- a/src/obj/NiPSysEmitterSpeedCtlr.cpp
+++ b/src/obj/NiPSysEmitterSpeedCtlr.cpp
@@ -2,6 +2,8 @@
 All rights reserved.  Please see niflib.h for licence. */
 
 #include "../../include/obj/NiPSysEmitterSpeedCtlr.h"
+#include "../../include/obj/NiFloatData.h"
+
 using namespace Niflib;
 
 //Definition of TYPE constant
diff --git a/src/obj/NiPSysGravityStrengthCtlr.cpp b/src/obj/NiPSysGravityStrengthCtlr.cpp
index 355eb154..ca2f1d40 100644
--- a/src/obj/NiPSysGravityStrengthCtlr.cpp
+++ b/src/obj/NiPSysGravityStrengthCtlr.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for licence. */
 
 #include "../../include/obj/NiPSysGravityStrengthCtlr.h"
+#include "../../include/obj/NiFloatData.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-- 
GitLab