From 5d96347ad37a3445672e1c9968a1540ae8cc578d Mon Sep 17 00:00:00 2001 From: Shon Ferguson <shonferg@users.sourceforge.net> Date: Sun, 25 Jun 2006 00:23:30 +0000 Subject: [PATCH] Implemented NiStringPalette and NiControllerSequence. --- obj/NiControllerSequence.cpp | 223 ++++++++++------------------------- obj/NiControllerSequence.h | 15 +-- obj/NiStringPalette.cpp | 39 ++++++ obj/NiStringPalette.h | 5 + 4 files changed, 114 insertions(+), 168 deletions(-) diff --git a/obj/NiControllerSequence.cpp b/obj/NiControllerSequence.cpp index 912dbbcf..cc2e79d3 100644 --- a/obj/NiControllerSequence.cpp +++ b/obj/NiControllerSequence.cpp @@ -14,6 +14,10 @@ All rights reserved. Please see niflib.h for licence. */ #include "NiControllerManager.h" #include "NiStringPalette.h" #include "NiTimeController.h" +#include "NiSingleInterpolatorController.h" +#include "NiObjectNET.h" +#include "NiProperty.h" +#include "NiStringPalette.h" using namespace Niflib; //Definition of TYPE constant @@ -49,188 +53,89 @@ const Type & NiControllerSequence::GetType() const { NiControllerManager * NiControllerSequence::Parent() const { return NULL; } -void NiControllerSequence::SetTextKey( const string new_name, const Ref<NiTextKeyExtraData> & txt_key ) { +void NiControllerSequence::SetTextKey( const Ref<NiTextKeyExtraData> & txt_key ) { //Set new name - textKeysName = new_name; + textKeysName = txt_key->GetName(); textKeys = txt_key; } -void NiControllerSequence::AddController( const string target_name, const Ref<NiTimeController> & obj ) { +void NiControllerSequence::AddController( const Ref<NiTimeController> & obj ) { //Make sure the link isn't null if ( obj == NULL ) { throw runtime_error("Attempted to add a null controller to NiControllerSequence block."); } - throw runtime_error("The AddController function cannot be implemented until prolems in the XML are solved."); - //TODO: ControllerLinks should store controllers, not interpolators. Cannot implement this. - //KfChild kc; + NiObjectNETRef target = obj->GetTarget(); + if ( target == NULL ) { + throw runtime_error("Controller must have a target to be added to a NiControllerSequence."); + } - - //kc.block = new_link; - - ////Check for a string palette - //blk_ref str_pal = GetAttr("String Palette")->asLink(); - //if ( str_pal.is_null() == true ) { - // //No string palette, store name internally - // kc.name = new_name; - //} else { - // //String palette exists - store name and controller type there - - // //Make sure they didn't give us empty strings - // if ( new_name.size() == 0 || controller_type.size() == 0 ) { - // throw runtime_error( "You cannot use empty name or controller type strings when using a string palette."); - // } - - // //Get palette - // string pal = str_pal->GetAttr("Palette")->asString(); - - // //--Search for copies of the text we want to add--// - - // //Search for the name string - // int offset = (int)pal.find( new_name ); - // if ( offset == -1 ) { - // //String not found, append it - // kc.name_offset = (uint)pal.size(); - // pal.append( new_name + '\0' ); - // } else { - // //String found, use existing offset - // kc.name_offset = offset; - // } - - // //Search for the controller type string - // offset = (int)pal.find( controller_type ); - // if ( offset == -1 ) { - // //String not found, append it - // kc.controller_offset = (uint)pal.size(); - // pal.append( controller_type + '\0' ); - // } else { - // //String found, use existing offset - // kc.controller_offset = offset; - // } - - // //Store the palette back to the string pal block - // str_pal->GetAttr("Palette")->Set( pal ); - //} - // - //children.push_back( kc ); - - ////Add new child - //AddChild( kc.block.get_block() ); - // - ////This should be impossible now, but don't want to forget it later - //if ( kc.unk_link.is_null() != true ) { - // AddChild( kc.unk_link.get_block() ); - //} + //Make a new ControllerLink and fill out necessary data + ControllerLink cl; + cl.controller = obj; + cl.targetName = target->GetName(); + cl.nodeName = target->GetName(); + + NiPropertyRef prop = DynamicCast<NiProperty>(target); + if ( prop != NULL ) { + cl.propertyType = prop->GetType().GetTypeName(); + } + + cl.controllerType = obj->GetType().GetTypeName(); + + //Add finished ControllerLink to list + controlledBlocks.push_back( cl ); } -void NiControllerSequence::AddInterpolator( const string target_name, const Ref<NiInterpolator> & obj, string controller_type ) { +void NiControllerSequence::AddInterpolator( const Ref<NiSingleInterpolatorController> & obj, byte priority ) { //Make sure the link isn't null if ( obj == NULL ) { - throw runtime_error("Attempted to add a null interpolator to NiControllerSequence block."); + throw runtime_error("Attempted to add a null controller to NiControllerSequence block."); } - throw runtime_error("The AddInterpolator function cannot be implemented until prolems in the XML are solved."); + NiInterpolatorRef interp = obj->GetInterpolator(); + if ( interp == NULL ) { + throw runtime_error("Controller must have an interpolator attached to be added to a NiControllerSequence with the AddInterpolator function."); + } + + NiObjectNETRef target = obj->GetTarget(); + if ( target == NULL ) { + throw runtime_error("Controller must have a target to be added to a NiControllerSequence."); + } - //TODO: Hold off on this until the XML for this block is fixed up. - //KfChild kc; - - //kc.block = new_link; - - ////Check for a string palette - //blk_ref str_pal = GetAttr("String Palette")->asLink(); - //if ( str_pal.is_null() == true ) { - // //No string palette, store name internally - // kc.name = new_name; - //} else { - // //String palette exists - store name and controller type there - - // //Make sure they didn't give us empty strings - // if ( new_name.size() == 0 || controller_type.size() == 0 ) { - // throw runtime_error( "You cannot use empty name or controller type strings when using a string palette."); - // } - - // //Get palette - // string pal = str_pal->GetAttr("Palette")->asString(); - - // //--Search for copies of the text we want to add--// - - // //Search for the name string - // int offset = (int)pal.find( new_name ); - // if ( offset == -1 ) { - // //String not found, append it - // kc.name_offset = (uint)pal.size(); - // pal.append( new_name + '\0' ); - // } else { - // //String found, use existing offset - // kc.name_offset = offset; - // } - - // //Search for the controller type string - // offset = (int)pal.find( controller_type ); - // if ( offset == -1 ) { - // //String not found, append it - // kc.controller_offset = (uint)pal.size(); - // pal.append( controller_type + '\0' ); - // } else { - // //String found, use existing offset - // kc.controller_offset = offset; - // } - - // //Store the palette back to the string pal block - // str_pal->GetAttr("Palette")->Set( pal ); - //} - // - //children.push_back( kc ); - - ////Add new child - //AddChild( kc.block.get_block() ); - // - ////This should be impossible now, but don't want to forget it later - //if ( kc.unk_link.is_null() != true ) { - // AddChild( kc.unk_link.get_block() ); - //} + //If there are existing ControllerLinks, use the same StringPalette they're using + NiStringPaletteRef str_pal; + if ( controlledBlocks.size() > 0 ) { + str_pal = controlledBlocks[0].stringPalette; + } else { + //No existing ones, so make a new one + str_pal = new NiStringPalette; + } + + //Make a new ControllerLink and fill out necessary data + ControllerLink cl; + + cl.interpolator = interp; + cl.priority_ = priority; + cl.nodeNameOffset = str_pal->AddSubStr( target->GetName() ); + + NiPropertyRef prop = DynamicCast<NiProperty>(target); + if ( prop != NULL ) { + cl.propertyTypeOffset = str_pal->AddSubStr( prop->GetType().GetTypeName() ); + } + + cl.controllerTypeOffset = str_pal->AddSubStr( obj->GetType().GetTypeName() ); + + //Add finished ControllerLink to list + controlledBlocks.push_back( cl ); } void NiControllerSequence::ClearChildren() { throw runtime_error("The AddInterpolator function cannot be implemented until prolems in the XML are solved."); - //TODO: Hold off on this until the XML is sorted out - ////Cycle through all Kf Children, removing them as parents from the blocks they refer to - //for (uint i = 0; i < children.size(); ++i ) { - // if ( children[i].block.is_null() != true ) { - // RemoveChild( children[i].block.get_block() ); - // } - // if ( children[i].unk_link.is_null() != true ) { - // RemoveChild( children[i].unk_link.get_block() ); - // } - //} - - ////Clear list - //children.clear(); - - ////Check for a string palette - //blk_ref str_pal = GetAttr("String Palette")->asLink(); - //if ( str_pal.is_null() == false ) { - // //There's a string palette, so clear it out - // str_pal->GetAttr("Palette")->Set( "" ); - //} + //Clear list + controlledBlocks.clear(); } -string NiControllerSequence::GetSubStr( const string & pal, short offset ) const { - string out; - - // -1 is a null offset - if ( offset == -1 ) { - return out; - } - - for ( uint i = offset; i < pal.size(); ++i ) { - if ( pal[i] == '\0' ) { - break; - } - out.push_back( pal[i] ); - } - return out; -} diff --git a/obj/NiControllerSequence.h b/obj/NiControllerSequence.h index 75fed2cc..026042e0 100644 --- a/obj/NiControllerSequence.h +++ b/obj/NiControllerSequence.h @@ -15,6 +15,7 @@ class NiTextKeyExtraData; class NiControllerManager; class NiStringPalette; class NiTimeController; +class NiSingleInterpolatorController; #include "../gen/obj_defines.h" @@ -47,30 +48,26 @@ public: * \param txt_key A reference to the NiTextKeyExtraData object to use. * \sa NiTextKeyExtraData */ - void SetTextKey( const string new_name, const Ref<NiTextKeyExtraData> & txt_key ); + void SetTextKey( const Ref<NiTextKeyExtraData> & txt_key ); /*! Attatches a controler to this KF file for a KF file of version 10.2.0.0 or below. Versions above this use interpolators. - * \param target_name The name to re-link this controller with when it is merged with a Nif file. * \param obj A reference to the new NiTimeController to attach. * \sa NiControllerSequence::ClearChildren, NiControllersequence::AddInterpolator */ - void AddController( const string target_name, const Ref<NiTimeController> & obj ); + void AddController( const Ref<NiTimeController> & obj ); /*! Attatches an interpolator to this KF file for a KF file of version greater than 10.2.0.0. Versions below this use controllers. - * \param target_name The name to re-link this interpolator with when it is merged with a Nif file. - * \param obj A reference to the new NiInterpolator to attach. - * \param controller_type The original controller type that this interpolator was connected to. + * \param obj A reference to the new controller which has an interpolator to attach. + * \param priority Used only in Oblivion to set the priority of one controller over another when the two are merged. * \sa NiControllerSequence::ClearChildren, NiControllerSequence::AddController */ - void AddInterpolator( const string target_name, const Ref<NiInterpolator> & obj, string controller_type ); + void AddInterpolator( const Ref<NiSingleInterpolatorController> & obj, byte priority = 0 ); /*! Removes all controllers and interpolators from this Kf file root object. * \sa NiControllerSequence::AddController, NiControllersequence::AddInterpolator */ void ClearChildren(); -private: - string GetSubStr( const string & pal, short offset ) const; protected: NiControllerManager * NiControllerSequence::Parent() const; NI_CONTROLLER_SEQUENCE_MEMBERS diff --git a/obj/NiStringPalette.cpp b/obj/NiStringPalette.cpp index e56baf26..25aa2cb7 100644 --- a/obj/NiStringPalette.cpp +++ b/obj/NiStringPalette.cpp @@ -36,3 +36,42 @@ const Type & NiStringPalette::GetType() const { return TYPE; }; +string NiStringPalette::GetPaletteString() const { + return palette.palette; +} + +void NiStringPalette::SetPaletteString( const string & n ) { + palette.palette = n; +} + +string NiStringPalette::GetSubStr( short offset ) const { + string out; + + // -1 is a null offset + if ( offset == -1 ) { + return out; + } + + for ( uint i = offset; i < palette.palette.size(); ++i ) { + if ( palette.palette[i] == '\0' ) { + break; + } + out.push_back( palette.palette[i] ); + } + + return out; +} + +unsigned int NiStringPalette::AddSubStr( const string & n ) { + //Search for the string + uint offset = (uint)palette.palette.find( n ); + + //If string was not found, append it + if ( offset == 0xFFFFFFFF ) { + offset = (uint)palette.palette.size(); + palette.palette.append( n + '\0' ); + } + + //Return the offset where the string was found or appended + return offset; +} \ No newline at end of file diff --git a/obj/NiStringPalette.h b/obj/NiStringPalette.h index 628f0a47..423ebadd 100644 --- a/obj/NiStringPalette.h +++ b/obj/NiStringPalette.h @@ -38,6 +38,11 @@ public: virtual list<NiObjectRef> GetRefs() const; virtual const Type & GetType() const; + string GetPaletteString() const; + void SetPaletteString( const string & n ); + string GetSubStr( short offset ) const; + unsigned int AddSubStr( const string & n ); + protected: NI_STRING_PALETTE_MEMBERS STANDARD_INTERNAL_METHODS -- GitLab