void Doom3EntityClass::parseEditorSpawnarg(const std::string& key, const std::string& value) { // "editor_yyy" represents an attribute that may be set on this // entity. Construct a value-less EntityClassAttribute to add to // the class, so that it will show in the entity inspector. // Locate the space in "editor_bool myVariable", starting after "editor_" std::size_t spacePos = key.find(' ', 7); // Only proceed if we have a space (some keys like "editor_displayFolder" // don't have spaces) if (spacePos != std::string::npos) { // The part beyond the space is the name of the attribute std::string attName = key.substr(spacePos + 1); // Get the type by trimming the string left and right std::string type = key.substr(7, key.length() - attName.length() - 8); if (!attName.empty() && type != "setKeyValue") // Ignore editor_setKeyValue { // Transform the type into a better format if (type == "var" || type == "string") { type = "text"; } // Construct an attribute with empty value, but with valid // description addAttribute(EntityClassAttribute(type, attName, "", value)); } } }
/** * Add a new EntityClassAttribute to entity class based on given definition * @param e entity class to add attribute to * @param keydef definition parsed from entities.ufo with information about type, * default values and mandatory state. * @note opposed to old parsing code this adds attributes for all definitions, * not only for the ones that get special treatment in gui. */ void EntityClassScannerUFO::parseAttribute (EntityClass *e, const entityKeyDef_t* keydef) { const bool mandatory = (keydef->flags & ED_MANDATORY); /* we use attribute key as its type, only for some types this is really used */ std::string attributeName = keydef->name; std::string value = ""; std::string desc = ""; if (keydef->defaultVal) value = keydef->defaultVal; if (keydef->desc) desc = keydef->desc; int typeFlag = keydef->flags & ED_KEY_TYPE; std::string type = attributeName; if (attributeName == "noise") type = "sound"; else if (attributeName == "_color" || attributeName == "color") type = "colour"; else if (attributeName == "target") type = "entity"; else if (typeFlag & ED_TYPE_FLOAT) { if (keydef->vLen == 3) type = "vector3"; else if (keydef->vLen == 1) type = "float"; } else if (typeFlag & ED_TYPE_INT) { // integer } else if (typeFlag == 0 || (typeFlag & ED_TYPE_STRING)) { // string } EntityClassAttribute attribute = EntityClassAttribute(type, attributeName, mandatory, value, desc); EntityClass_insertAttribute(*e, attributeName, attribute); }
/** * Creates a new entityclass for given parsed definition * @param entityDef parsed definition information to use * @return a new entity class or 0 if something was wrong with definition */ EntityClass *EntityClassScannerUFO::initFromDefinition (const entityDef_t* definition) { g_debug("Creating entity class for entity definition '%s'\n", definition->classname); EntityClass* e = Eclass_Alloc(); e->free = &Eclass_Free; e->m_name = definition->classname; for (int idx = 0; idx < definition->numKeyDefs; idx++) { const entityKeyDef_t* keydef = &definition->keyDefs[idx]; const std::string keyName = keydef->name; if (keyName == "color") { //not using _color as this is a valid attribute flag // grab the color, reformat as texture name const int r = sscanf(keydef->desc, "%f %f %f", &e->color[0], &e->color[1], &e->color[2]); if (r != 3) { g_message("Invalid color token given\n"); return 0; } } else if (keyName == "size") { e->fixedsize = true; const int r = sscanf(keydef->desc, "%f %f %f %f %f %f", &e->mins[0], &e->mins[1], &e->mins[2], &e->maxs[0], &e->maxs[1], &e->maxs[2]); if (r != 6) { g_message("Invalid size token given\n"); return 0; } } else if (keyName == "description") { e->m_comments = keydef->desc; } else if (keyName == "spawnflags") { if (keydef->flags & ED_ABSTRACT) { /* there are two keydefs, abstract holds the valid levelflags, the other one default value and type */ const char* flags = keydef->desc; parseFlags(e, &flags); } else { parseAttribute(e, keydef); } } else if (keyName == "classname") { /* ignore, read from head */ continue; } else if (keyName == "model") { /** @todo what does that modelpath stuff do? it does not read anything from keydef */ e->m_modelpath = os::standardPath(e->m_modelpath); const bool mandatory = (keydef->flags & ED_MANDATORY); EntityClass_insertAttribute(*e, "model", EntityClassAttribute("model", "model", mandatory)); } else { /* all other keys are valid attribute keys */ parseAttribute(e, keydef); } } #if 0 /** * @todo direction and angle are 2 types used for different display * (see entityinspector DirectionAttribute and AngleAttribute) * the problem is that different entities have "angle" property, but different defines what values are valid * which is actually not reflected by this code. Perhaps we should introduce different types for these representations. */ EntityClassAttribute *angle = e->getAttribute("angle"); if (angle) { if (e->fixedsize) { angle->name = _("Yaw Angle"); } else { angle->name = _("Direction"); } } #endif eclass_capture_state(e); return e; }
void Doom3EntityClass::parseFromTokens(parser::DefTokeniser& tokeniser) { // Clear this structure first, we might be "refreshing" ourselves from tokens clear(); // Required open brace (the name has already been parsed by the EClassManager) tokeniser.assertNextToken("{"); // Loop over all of the keys in this entitydef while (true) { const std::string key = tokeniser.nextToken(); if (key == "}") { break; // end of def } const std::string value = tokeniser.nextToken(); // Otherwise, switch on the key name if (key == "model") { setModelPath(os::standardPath(value)); } else if (key == "editor_color") { setColour(value); } else if (key == "editor_light") { if (value == "1") { setIsLight(true); } } else if (key == "spawnclass") { if (value == "idLight") { setIsLight(true); } } else if (boost::algorithm::istarts_with(key, "editor_")) { // "editor_yyy" represents an attribute that may be set on this // entity. Construct a value-less EntityClassAttribute to add to // the class, so that it will show in the entity inspector. // Locate the space in "editor_bool myVariable", starting after "editor_" std::size_t spacePos = key.find(' ', 7); // Only proceed if we have a space (some keys like "editor_displayFolder" don't have spaces) if (spacePos != std::string::npos) { // The part beyond the space is the name of the attribute std::string attName = key.substr(spacePos + 1); // Get the type by trimming the string left and right std::string type = key.substr(7, key.length() - attName.length() - 8); // Ignore editor_setKeyValue if (!attName.empty() && type != "setKeyValue") { // Transform the type into a better format if (type == "var" || type == "string") { type = "text"; } addAttribute(EntityClassAttribute(type, attName, "", value)); } } } // Following key-specific processing, add the keyvalue to the eclass EntityClassAttribute attribute("text", key, value, ""); if (getAttribute(key).type.empty()) { // Type is empty, attribute does not exist, add it. addAttribute(attribute); } else if (getAttribute(key).value.empty() ) { // Attribute type is set, but value is empty, set the value. getAttribute(key).value = value; } else { // Both type and value are not empty, emit a warning globalWarningStream() << "[eclassmgr] attribute " << key << " already set on entityclass " << _name << std::endl; } } // while true // Notify the observers for (Observers::const_iterator i = _observers.begin(); i != _observers.end(); ++i) { (*i)->OnEClassReload(); } }