Gracefully deal with entity attributes of the same name. This is needed for
the Input/Output system. We append numerations separated by a '#' character and strip the when saving the map. The editor will intelligently pick a name for us.
This commit is contained in:
parent
adc1c4ea15
commit
826d115cb1
2 changed files with 75 additions and 5 deletions
|
@ -374,6 +374,7 @@ typedef MemberCaller<KeyValue, void(const CopiedString&), &KeyValue::importState
|
||||||
/// - Notifies observers when a pair is inserted or removed.
|
/// - Notifies observers when a pair is inserted or removed.
|
||||||
/// - Provides undo support through the global undo system.
|
/// - Provides undo support through the global undo system.
|
||||||
/// - New keys are appended to the end of the list.
|
/// - New keys are appended to the end of the list.
|
||||||
|
#include "stream/stringstream.h"
|
||||||
class EntityKeyValues : public Entity
|
class EntityKeyValues : public Entity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -441,15 +442,82 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* see if our key already exists in here */
|
||||||
void insert( const char* key, const char* value ){
|
void insert( const char* key, const char* value ){
|
||||||
|
int dupecheck = 0;
|
||||||
|
|
||||||
|
if (!strcmp(key, "classname"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "origin"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "model"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "angles"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "angle"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "alpha"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "rendermode"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "renderamt"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "rendercolor"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "velocity"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "solid"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "movetype"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "avelocity"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "skin"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "effects"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "target"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "targetname"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "killtarget"))
|
||||||
|
dupecheck = 1;
|
||||||
|
else if (!strcmp(key, "shadows"))
|
||||||
|
dupecheck = 1;
|
||||||
|
|
||||||
KeyValues::iterator i = m_keyValues.find( key );
|
KeyValues::iterator i = m_keyValues.find( key );
|
||||||
if ( i != m_keyValues.end() ) {
|
|
||||||
( *i ).second->assign( value );
|
/* does the key already exist */
|
||||||
|
if (i != m_keyValues.end() ) {
|
||||||
|
/* re-assign only when we're a special field, else pick a new name */
|
||||||
|
if (dupecheck) {
|
||||||
|
( *i ).second->assign( value );
|
||||||
|
printf("[ENTLIB]: dupe found, setting %s to %s\n", key, value);
|
||||||
|
} else {
|
||||||
|
bool b = true;
|
||||||
|
unsigned int num = 0;
|
||||||
|
StringOutputStream new_key(64);
|
||||||
|
|
||||||
|
/* loop through and generate an enumerated variant */
|
||||||
|
do {
|
||||||
|
/* keep incrementing num until we find a free slot */
|
||||||
|
num++;
|
||||||
|
new_key.clear();
|
||||||
|
new_key << key << "#" << Unsigned(num);
|
||||||
|
i = m_keyValues.find(new_key.c_str());
|
||||||
|
|
||||||
|
if (i == m_keyValues.end()) {
|
||||||
|
insert(new_key.c_str(), value);
|
||||||
|
b = false;
|
||||||
|
}
|
||||||
|
} while (b != false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_undo.save();
|
m_undo.save();
|
||||||
insert( key, KeyValuePtr( new KeyValue( value, EntityClass_valueForKey( *m_eclass, key ) ) ) );
|
insert( key, KeyValuePtr( new KeyValue( value, EntityClass_valueForKey( *m_eclass, key ) ) ) );
|
||||||
|
printf("[ENTLIB]: inserting key %s = %s\n", key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,11 @@ void Entity_ExportTokens(const Entity &entity, TokenWriter &writer)
|
||||||
|
|
||||||
void visit(const char *key, const char *value)
|
void visit(const char *key, const char *value)
|
||||||
{
|
{
|
||||||
m_writer.writeString(key);
|
/* cut anything after # including the symbol itself */
|
||||||
m_writer.writeString(value);
|
StringTokeniser st(key, "#");
|
||||||
m_writer.nextLine();
|
m_writer.writeString(st.getToken());
|
||||||
|
m_writer.writeString(value);
|
||||||
|
m_writer.nextLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
} visitor(writer);
|
} visitor(writer);
|
||||||
|
|
Loading…
Reference in a new issue