Skip to content
Snippets Groups Projects
Commit 5d96347a authored by Shon Ferguson's avatar Shon Ferguson
Browse files

Implemented NiStringPalette and NiControllerSequence.

parent 7a4780b4
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......@@ -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
......
......@@ -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
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment