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 std::string key; while ((key = tokeniser.nextToken()) != "}") { const std::string value = tokeniser.nextToken(); // Handle some keys specially if (key == "model") { setModelPath(os::standardPath(value)); } else if (key == "editor_color") { setColour(string::convert<Vector3>(value)); } else if (key == "editor_light") { setIsLight(value == "1"); } else if (key == "spawnclass") { setIsLight(value == "idLight"); } else if (boost::algorithm::istarts_with(key, "editor_")) { parseEditorSpawnarg(key, value); } // Try parsing this key/value with the Attachments manager _attachments->parseDefAttachKeys(key, value); // Add the EntityClassAttribute for this key/val if (getAttribute(key).getType().empty()) { // Following key-specific processing, add the keyvalue to the eclass EntityClassAttribute attribute("text", key, value, ""); // Type is empty, attribute does not exist, add it. addAttribute(attribute); } else if (getAttribute(key).getValue().empty()) { // Attribute type is set, but value is empty, set the value. getAttribute(key).setValue(value); } else { // Both type and value are not empty, emit a warning rWarning() << "[eclassmgr] attribute " << key << " already set on entityclass " << _name << std::endl; } } // while true _attachments->validateAttachments(); // Notify the observers _changedSignal.emit(); }
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(); } }
// Resolve inheritance for this class void Doom3EntityClass::resolveInheritance(EntityClasses& classmap) { // If we have already resolved inheritance, do nothing if (_inheritanceResolved) return; // Lookup the parent name and return if it is not set. Also return if the // parent name is the same as our own classname, to avoid infinite // recursion. std::string parName = getAttribute("inherit").getValue(); if (parName.empty() || parName == _name) return; // Find the parent entity class EntityClasses::iterator pIter = classmap.find(parName); if (pIter != classmap.end()) { // Recursively resolve inheritance of parent pIter->second->resolveInheritance(classmap); // Copy attributes from the parent to the child, including editor keys pIter->second->forEachClassAttribute( std::bind(©InheritedAttribute, this, std::placeholders::_1), true ); // Set our parent pointer _parent = pIter->second.get(); } else { rWarning() << "[eclassmgr] Entity class " << _name << " specifies unknown parent class " << parName << std::endl; } // Set the resolved flag _inheritanceResolved = true; if (!getAttribute("model").getValue().empty()) { // We have a model path (probably an inherited one) setModelPath(getAttribute("model").getValue()); } if (getAttribute("editor_light").getValue() == "1" || getAttribute("spawnclass").getValue() == "idLight") { // We have a light setIsLight(true); } if (getAttribute("editor_transparent").getValue() == "1") { _colourTransparent = true; } // (Re)set the colour const EntityClassAttribute& colourAttr = getAttribute("editor_color"); if (!colourAttr.getValue().empty()) { setColour(string::convert<Vector3>(colourAttr.getValue())); } else { // If no colour is set, assign the default entity colour to this class static Vector3 defaultColour = ColourSchemes().getColour("default_entity"); setColour(defaultColour); } }
// Resolve inheritance for this class void Doom3EntityClass::resolveInheritance(EntityClasses& classmap) { // If we have already resolved inheritance, do nothing if (_inheritanceResolved) return; // Lookup the parent name and return if it is not set. Also return if the // parent name is the same as our own classname, to avoid infinite // recursion. std::string parName = getAttribute("inherit").value; if (parName.empty() || parName == _name) return; // Find the parent entity class EntityClasses::iterator pIter = classmap.find(parName); if (pIter != classmap.end()) { // Recursively resolve inheritance of parent pIter->second->resolveInheritance(classmap); // Copy attributes from the parent to the child, including editor keys AttributeCopyingVisitor visitor(*this); pIter->second->forEachClassAttribute(visitor, true); } else { globalWarningStream() << "[eclassmgr] Entity class " << _name << " specifies parent " << parName << " which is not found." << std::endl; } // Set the resolved flag _inheritanceResolved = true; // Construct the inheritance list buildInheritanceChain(); if (getAttribute("model").value != "") { // We have a model path (probably an inherited one) setModelPath(getAttribute("model").value); } if (getAttribute("editor_light").value == "1" || getAttribute("spawnclass").value == "idLight") { // We have a light setIsLight(true); } if (getAttribute("editor_transparent").value == "1") { _colourTransparent = true; } // (Re)set the colour const EntityClassAttribute& colourAttr = getAttribute("editor_color"); if (!colourAttr.value.empty()) { setColour(Vector3(colourAttr.value)); } // Update the colour shader captureColour(); }