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));
        }
    }
}
Esempio n. 2
0
/**
 * 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);
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
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();
	}
}