|
@@ -652,6 +652,31 @@ S32 PersistenceManager::getPropertyIndex(ParsedObject* parsedObject, const char*
|
|
return propertyIndex;
|
|
return propertyIndex;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+S32 PersistenceManager::getSpecialPropertyAtOffset(ParsedObject* parsedObject, const char* fieldName, U32 offsetPos)
|
|
|
|
+{
|
|
|
|
+ S32 propertyIndex = -1;
|
|
|
|
+
|
|
|
|
+ if (!parsedObject)
|
|
|
|
+ return propertyIndex;
|
|
|
|
+
|
|
|
|
+ U32 hitCount = -1;
|
|
|
|
+ for (U32 i = 0; i < parsedObject->properties.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ if (dStricmp(fieldName, parsedObject->properties[i].name) == 0)
|
|
|
|
+ {
|
|
|
|
+ hitCount++;
|
|
|
|
+
|
|
|
|
+ if (hitCount == offsetPos)
|
|
|
|
+ {
|
|
|
|
+ propertyIndex = i;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return propertyIndex;
|
|
|
|
+}
|
|
|
|
+
|
|
char* PersistenceManager::getObjectIndent(ParsedObject* object)
|
|
char* PersistenceManager::getObjectIndent(ParsedObject* object)
|
|
{
|
|
{
|
|
char* indent = Con::getReturnBuffer(2048);
|
|
char* indent = Con::getReturnBuffer(2048);
|
|
@@ -1361,166 +1386,335 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
|
|
if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors))
|
|
if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors))
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- for(U32 j = 0; S32(j) < f->elementCount; j++)
|
|
|
|
|
|
+ if (f->flag.test(AbstractClassRep::FIELD_SpecialtyArrayField))
|
|
{
|
|
{
|
|
- const char* value = getFieldValue(object, f->pFieldname, j);
|
|
|
|
|
|
+ U32 fieldArraySize = object->getSpecialFieldSize(f->pFieldname);
|
|
|
|
|
|
- // Make sure we got a value
|
|
|
|
- if (!value)
|
|
|
|
- continue;
|
|
|
|
|
|
+ for(U32 j = 0; j < fieldArraySize; j++)
|
|
|
|
+ {
|
|
|
|
+ const char* value = object->getSpecialFieldOut(f->pFieldname, j);
|
|
|
|
|
|
- // Let's see if this field is already in the file
|
|
|
|
- S32 propertyIndex = getPropertyIndex(parsedObject, f->pFieldname, j);
|
|
|
|
|
|
+ // Make sure we got a value
|
|
|
|
+ if (!value)
|
|
|
|
+ continue;
|
|
|
|
|
|
- if (propertyIndex > -1)
|
|
|
|
- {
|
|
|
|
- ParsedProperty& prop = parsedObject->properties[propertyIndex];
|
|
|
|
|
|
+ // Let's see if this field is already in the file
|
|
|
|
+ S32 propertyIndex = getSpecialPropertyAtOffset(parsedObject, f->pFieldname, j);
|
|
|
|
|
|
- // If this field is on the remove list then remove it and continue
|
|
|
|
- if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value))
|
|
|
|
|
|
+ if (propertyIndex > -1)
|
|
{
|
|
{
|
|
- removeField( parsedObject->properties[ propertyIndex ] );
|
|
|
|
- dFree( value );
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
|
|
+ ParsedProperty& prop = parsedObject->properties[propertyIndex];
|
|
|
|
|
|
- // Run the parsed value through the console system conditioners so
|
|
|
|
- // that it will better match the data we got back from the object.
|
|
|
|
- const char* evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag);
|
|
|
|
-
|
|
|
|
- // If our data doesn't match then we get to update it.
|
|
|
|
- //
|
|
|
|
- // As for copy-sources, we just assume here that if a property setting
|
|
|
|
- // is there in the file, the user does not want it inherited from the copy-source
|
|
|
|
- // even in the case the actual values are identical.
|
|
|
|
-
|
|
|
|
- if( dStricmp(value, evalue) != 0 )
|
|
|
|
|
|
+ // If this field is on the remove list then remove it and continue
|
|
|
|
+ if (findRemoveField(object, f->pFieldname, j))
|
|
|
|
+ {
|
|
|
|
+ removeField(parsedObject->properties[propertyIndex]);
|
|
|
|
+ dFree(value);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Run the parsed value through the console system conditioners so
|
|
|
|
+ // that it will better match the data we got back from the object.
|
|
|
|
+ const char* evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag);
|
|
|
|
+
|
|
|
|
+ // If our data doesn't match then we get to update it.
|
|
|
|
+ //
|
|
|
|
+ // As for copy-sources, we just assume here that if a property setting
|
|
|
|
+ // is there in the file, the user does not want it inherited from the copy-source
|
|
|
|
+ // even in the case the actual values are identical.
|
|
|
|
+
|
|
|
|
+ if (dStricmp(value, evalue) != 0)
|
|
|
|
+ {
|
|
|
|
+ if (value[0] == '\0' &&
|
|
|
|
+ dStricmp(getFieldValue(defaultObject, f->pFieldname, j), value) == 0 &&
|
|
|
|
+ (!object->getCopySource() || dStricmp(getFieldValue(object->getCopySource(), f->pFieldname, j), value) == 0))
|
|
|
|
+ {
|
|
|
|
+ removeField(prop);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // TODO: This should be wrapped in a helper method... probably.
|
|
|
|
+ // Detect and collapse relative path information
|
|
|
|
+ if (f->type == TypeFilename ||
|
|
|
|
+ f->type == TypeStringFilename ||
|
|
|
|
+ f->type == TypeImageFilename ||
|
|
|
|
+ f->type == TypePrefabFilename ||
|
|
|
|
+ f->type == TypeShapeFilename ||
|
|
|
|
+ f->type == TypeSoundFilename)
|
|
|
|
+ {
|
|
|
|
+ char fnBuf[1024];
|
|
|
|
+ Con::collapseScriptFilename(fnBuf, 1024, value);
|
|
|
|
+
|
|
|
|
+ updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true);
|
|
|
|
+ }
|
|
|
|
+ else if (f->type == TypeCommand || f->type == TypeString || f->type == TypeRealString)
|
|
|
|
+ {
|
|
|
|
+ char cmdBuf[1024];
|
|
|
|
+ expandEscape(cmdBuf, value);
|
|
|
|
+
|
|
|
|
+ updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, cmdBuf, true);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value, true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- if( value[ 0 ] == '\0' &&
|
|
|
|
- dStricmp( getFieldValue( defaultObject, f->pFieldname, j ), value ) == 0 &&
|
|
|
|
- ( !object->getCopySource() || dStricmp( getFieldValue( object->getCopySource(), f->pFieldname, j ), value ) == 0 ) )
|
|
|
|
|
|
+ // No need to process a removed field that doesn't exist in the file
|
|
|
|
+ if (findRemoveField(object, f->pFieldname, j))
|
|
|
|
+ {
|
|
|
|
+ dFree(value);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bool mustUpdate = false;
|
|
|
|
+
|
|
|
|
+ // If we didn't find the property in the ParsedObject
|
|
|
|
+ // then we need to compare against the default value
|
|
|
|
+ // for this property and save it out if it is different
|
|
|
|
+
|
|
|
|
+ const char* defaultValue = defaultObject->getSpecialFieldOut(f->pFieldname, j);
|
|
|
|
+ if (!defaultValue || dStricmp(value, defaultValue) != 0)
|
|
{
|
|
{
|
|
- removeField( prop );
|
|
|
|
|
|
+ // Value differs. Check whether it also differs from the
|
|
|
|
+ // value in the copy source if there is one.
|
|
|
|
+
|
|
|
|
+ if (object->getCopySource())
|
|
|
|
+ {
|
|
|
|
+ const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
|
|
|
|
+ if (!copySourceValue || dStricmp(copySourceValue, value) != 0)
|
|
|
|
+ mustUpdate = true;
|
|
|
|
+
|
|
|
|
+ if (copySourceValue)
|
|
|
|
+ dFree(copySourceValue);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ mustUpdate = true;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
|
|
+ {
|
|
|
|
+ // Value does not differ. If it differs from the copy source's value,
|
|
|
|
+ // though, we still want to write it out as otherwise we'll see the
|
|
|
|
+ // copy source's value override us.
|
|
|
|
+
|
|
|
|
+ if (object->getCopySource())
|
|
|
|
+ {
|
|
|
|
+ const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
|
|
|
|
+ if (copySourceValue && dStricmp(copySourceValue, value) != 0)
|
|
|
|
+ mustUpdate = true;
|
|
|
|
+
|
|
|
|
+ if (copySourceValue)
|
|
|
|
+ dFree(copySourceValue);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // The default value for most string type fields is
|
|
|
|
+ // NULL so we can't just continue here or we'd never ever
|
|
|
|
+ // write them out...
|
|
|
|
+ //
|
|
|
|
+ //if (!defaultValue)
|
|
|
|
+ // continue;
|
|
|
|
+
|
|
|
|
+ // If the object's value is different from the default
|
|
|
|
+ // value then add it to the ParsedObject's newLines
|
|
|
|
+ if (mustUpdate)
|
|
{
|
|
{
|
|
// TODO: This should be wrapped in a helper method... probably.
|
|
// TODO: This should be wrapped in a helper method... probably.
|
|
// Detect and collapse relative path information
|
|
// Detect and collapse relative path information
|
|
- if (f->type == TypeFilename ||
|
|
|
|
- f->type == TypeStringFilename ||
|
|
|
|
- f->type == TypeImageFilename ||
|
|
|
|
- f->type == TypePrefabFilename ||
|
|
|
|
- f->type == TypeShapeFilename ||
|
|
|
|
- f->type == TypeSoundFilename )
|
|
|
|
|
|
+ if (f->type == TypeFilename ||
|
|
|
|
+ f->type == TypeStringFilename ||
|
|
|
|
+ f->type == TypeImageFilename ||
|
|
|
|
+ f->type == TypePrefabFilename ||
|
|
|
|
+ f->type == TypeShapeFilename ||
|
|
|
|
+ f->type == TypeSoundFilename)
|
|
{
|
|
{
|
|
char fnBuf[1024];
|
|
char fnBuf[1024];
|
|
Con::collapseScriptFilename(fnBuf, 1024, value);
|
|
Con::collapseScriptFilename(fnBuf, 1024, value);
|
|
|
|
|
|
- updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true);
|
|
|
|
|
|
+ newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j));
|
|
}
|
|
}
|
|
- else if (f->type == TypeCommand || f->type == TypeString || f->type == TypeRealString)
|
|
|
|
|
|
+ else if (f->type == TypeCommand)
|
|
{
|
|
{
|
|
char cmdBuf[1024];
|
|
char cmdBuf[1024];
|
|
expandEscape(cmdBuf, value);
|
|
expandEscape(cmdBuf, value);
|
|
|
|
|
|
- updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, cmdBuf, true);
|
|
|
|
|
|
+ newLines.push_back(createNewProperty(f->pFieldname, cmdBuf, f->elementCount > 1, j));
|
|
}
|
|
}
|
|
else
|
|
else
|
|
- updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value, true);
|
|
|
|
|
|
+ newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (defaultValue)
|
|
|
|
+ dFree(defaultValue);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ //dFree(value);
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ for (U32 j = 0; S32(j) < f->elementCount; j++)
|
|
{
|
|
{
|
|
- // No need to process a removed field that doesn't exist in the file
|
|
|
|
- if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value))
|
|
|
|
- {
|
|
|
|
- dFree( value );
|
|
|
|
|
|
+ const char* value = getFieldValue(object, f->pFieldname, j);
|
|
|
|
+
|
|
|
|
+ // Make sure we got a value
|
|
|
|
+ if (!value)
|
|
continue;
|
|
continue;
|
|
- }
|
|
|
|
-
|
|
|
|
- bool mustUpdate = false;
|
|
|
|
|
|
|
|
- // If we didn't find the property in the ParsedObject
|
|
|
|
- // then we need to compare against the default value
|
|
|
|
- // for this property and save it out if it is different
|
|
|
|
|
|
+ // Let's see if this field is already in the file
|
|
|
|
+ S32 propertyIndex = getPropertyIndex(parsedObject, f->pFieldname, j);
|
|
|
|
|
|
- const char* defaultValue = getFieldValue(defaultObject, f->pFieldname, j);
|
|
|
|
- if( !defaultValue || dStricmp( value, defaultValue ) != 0 )
|
|
|
|
|
|
+ if (propertyIndex > -1)
|
|
{
|
|
{
|
|
- // Value differs. Check whether it also differs from the
|
|
|
|
- // value in the copy source if there is one.
|
|
|
|
-
|
|
|
|
- if( object->getCopySource() )
|
|
|
|
|
|
+ ParsedProperty& prop = parsedObject->properties[propertyIndex];
|
|
|
|
+
|
|
|
|
+ // If this field is on the remove list then remove it and continue
|
|
|
|
+ if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value))
|
|
{
|
|
{
|
|
- const char* copySourceValue = getFieldValue( object->getCopySource(), f->pFieldname, j );
|
|
|
|
- if( !copySourceValue || dStricmp( copySourceValue, value ) != 0 )
|
|
|
|
- mustUpdate = true;
|
|
|
|
-
|
|
|
|
- if( copySourceValue )
|
|
|
|
- dFree( copySourceValue );
|
|
|
|
|
|
+ removeField(parsedObject->properties[propertyIndex]);
|
|
|
|
+ dFree(value);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Run the parsed value through the console system conditioners so
|
|
|
|
+ // that it will better match the data we got back from the object.
|
|
|
|
+ const char* evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag);
|
|
|
|
+
|
|
|
|
+ // If our data doesn't match then we get to update it.
|
|
|
|
+ //
|
|
|
|
+ // As for copy-sources, we just assume here that if a property setting
|
|
|
|
+ // is there in the file, the user does not want it inherited from the copy-source
|
|
|
|
+ // even in the case the actual values are identical.
|
|
|
|
+
|
|
|
|
+ if (dStricmp(value, evalue) != 0)
|
|
|
|
+ {
|
|
|
|
+ if (value[0] == '\0' &&
|
|
|
|
+ dStricmp(getFieldValue(defaultObject, f->pFieldname, j), value) == 0 &&
|
|
|
|
+ (!object->getCopySource() || dStricmp(getFieldValue(object->getCopySource(), f->pFieldname, j), value) == 0))
|
|
|
|
+ {
|
|
|
|
+ removeField(prop);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // TODO: This should be wrapped in a helper method... probably.
|
|
|
|
+ // Detect and collapse relative path information
|
|
|
|
+ if (f->type == TypeFilename ||
|
|
|
|
+ f->type == TypeStringFilename ||
|
|
|
|
+ f->type == TypeImageFilename ||
|
|
|
|
+ f->type == TypePrefabFilename ||
|
|
|
|
+ f->type == TypeShapeFilename ||
|
|
|
|
+ f->type == TypeSoundFilename)
|
|
|
|
+ {
|
|
|
|
+ char fnBuf[1024];
|
|
|
|
+ Con::collapseScriptFilename(fnBuf, 1024, value);
|
|
|
|
+
|
|
|
|
+ updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true);
|
|
|
|
+ }
|
|
|
|
+ else if (f->type == TypeCommand || f->type == TypeString || f->type == TypeRealString)
|
|
|
|
+ {
|
|
|
|
+ char cmdBuf[1024];
|
|
|
|
+ expandEscape(cmdBuf, value);
|
|
|
|
+
|
|
|
|
+ updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, cmdBuf, true);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value, true);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- else
|
|
|
|
- mustUpdate = true;
|
|
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- // Value does not differ. If it differs from the copy source's value,
|
|
|
|
- // though, we still want to write it out as otherwise we'll see the
|
|
|
|
- // copy source's value override us.
|
|
|
|
-
|
|
|
|
- if( object->getCopySource() )
|
|
|
|
|
|
+ // No need to process a removed field that doesn't exist in the file
|
|
|
|
+ if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value))
|
|
{
|
|
{
|
|
- const char* copySourceValue = getFieldValue( object->getCopySource(), f->pFieldname, j );
|
|
|
|
- if( copySourceValue && dStricmp( copySourceValue, value ) != 0 )
|
|
|
|
- mustUpdate = true;
|
|
|
|
-
|
|
|
|
- if( copySourceValue )
|
|
|
|
- dFree( copySourceValue );
|
|
|
|
|
|
+ dFree(value);
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- // The default value for most string type fields is
|
|
|
|
- // NULL so we can't just continue here or we'd never ever
|
|
|
|
- // write them out...
|
|
|
|
- //
|
|
|
|
- //if (!defaultValue)
|
|
|
|
- // continue;
|
|
|
|
|
|
+ bool mustUpdate = false;
|
|
|
|
|
|
- // If the object's value is different from the default
|
|
|
|
- // value then add it to the ParsedObject's newLines
|
|
|
|
- if ( mustUpdate )
|
|
|
|
- {
|
|
|
|
- // TODO: This should be wrapped in a helper method... probably.
|
|
|
|
- // Detect and collapse relative path information
|
|
|
|
- if (f->type == TypeFilename ||
|
|
|
|
- f->type == TypeStringFilename ||
|
|
|
|
- f->type == TypeImageFilename ||
|
|
|
|
- f->type == TypePrefabFilename ||
|
|
|
|
- f->type == TypeShapeFilename ||
|
|
|
|
- f->type == TypeSoundFilename )
|
|
|
|
|
|
+ // If we didn't find the property in the ParsedObject
|
|
|
|
+ // then we need to compare against the default value
|
|
|
|
+ // for this property and save it out if it is different
|
|
|
|
+
|
|
|
|
+ const char* defaultValue = getFieldValue(defaultObject, f->pFieldname, j);
|
|
|
|
+ if (!defaultValue || dStricmp(value, defaultValue) != 0)
|
|
{
|
|
{
|
|
- char fnBuf[1024];
|
|
|
|
- Con::collapseScriptFilename(fnBuf, 1024, value);
|
|
|
|
|
|
+ // Value differs. Check whether it also differs from the
|
|
|
|
+ // value in the copy source if there is one.
|
|
|
|
+
|
|
|
|
+ if (object->getCopySource())
|
|
|
|
+ {
|
|
|
|
+ const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
|
|
|
|
+ if (!copySourceValue || dStricmp(copySourceValue, value) != 0)
|
|
|
|
+ mustUpdate = true;
|
|
|
|
|
|
- newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j));
|
|
|
|
|
|
+ if (copySourceValue)
|
|
|
|
+ dFree(copySourceValue);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ mustUpdate = true;
|
|
}
|
|
}
|
|
- else if (f->type == TypeCommand)
|
|
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- char cmdBuf[1024];
|
|
|
|
- expandEscape(cmdBuf, value);
|
|
|
|
|
|
+ // Value does not differ. If it differs from the copy source's value,
|
|
|
|
+ // though, we still want to write it out as otherwise we'll see the
|
|
|
|
+ // copy source's value override us.
|
|
|
|
|
|
- newLines.push_back(createNewProperty(f->pFieldname, cmdBuf, f->elementCount > 1, j));
|
|
|
|
|
|
+ if (object->getCopySource())
|
|
|
|
+ {
|
|
|
|
+ const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
|
|
|
|
+ if (copySourceValue && dStricmp(copySourceValue, value) != 0)
|
|
|
|
+ mustUpdate = true;
|
|
|
|
+
|
|
|
|
+ if (copySourceValue)
|
|
|
|
+ dFree(copySourceValue);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- else
|
|
|
|
- newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j));
|
|
|
|
|
|
+
|
|
|
|
+ // The default value for most string type fields is
|
|
|
|
+ // NULL so we can't just continue here or we'd never ever
|
|
|
|
+ // write them out...
|
|
|
|
+ //
|
|
|
|
+ //if (!defaultValue)
|
|
|
|
+ // continue;
|
|
|
|
+
|
|
|
|
+ // If the object's value is different from the default
|
|
|
|
+ // value then add it to the ParsedObject's newLines
|
|
|
|
+ if (mustUpdate)
|
|
|
|
+ {
|
|
|
|
+ // TODO: This should be wrapped in a helper method... probably.
|
|
|
|
+ // Detect and collapse relative path information
|
|
|
|
+ if (f->type == TypeFilename ||
|
|
|
|
+ f->type == TypeStringFilename ||
|
|
|
|
+ f->type == TypeImageFilename ||
|
|
|
|
+ f->type == TypePrefabFilename ||
|
|
|
|
+ f->type == TypeShapeFilename ||
|
|
|
|
+ f->type == TypeSoundFilename)
|
|
|
|
+ {
|
|
|
|
+ char fnBuf[1024];
|
|
|
|
+ Con::collapseScriptFilename(fnBuf, 1024, value);
|
|
|
|
+
|
|
|
|
+ newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j));
|
|
|
|
+ }
|
|
|
|
+ else if (f->type == TypeCommand)
|
|
|
|
+ {
|
|
|
|
+ char cmdBuf[1024];
|
|
|
|
+ expandEscape(cmdBuf, value);
|
|
|
|
+
|
|
|
|
+ newLines.push_back(createNewProperty(f->pFieldname, cmdBuf, f->elementCount > 1, j));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (defaultValue)
|
|
|
|
+ dFree(defaultValue);
|
|
}
|
|
}
|
|
|
|
|
|
- if (defaultValue)
|
|
|
|
- dFree( defaultValue );
|
|
|
|
|
|
+ dFree(value);
|
|
}
|
|
}
|
|
-
|
|
|
|
- dFree( value );
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|