示例#1
0
scene::INodePtr Doom3EntityCreator::createEntity(const IEntityClassPtr& eclass) {
    scene::INodePtr node = getEntityForEClass(eclass);
    Entity* entity = Node_getEntity(node);
    assert(entity != NULL);

    entity->setKeyValue("classname", eclass->getName());

    // If this is not a worldspawn or unrecognised entity, generate a unique
    // name for it
    const std::string& eclassName = eclass->getName();

    if (!eclassName.empty() &&
            eclassName != "worldspawn" &&
            eclassName != "UNKNOWN_CLASS")
    {
        /* Clean up the name of the entity that is about the created
         * so that nothing bad can happen (for example, the colon character
         * seems to be causing problems in Doom 3 Scripting)
         */
        std::string entityName =
            boost::algorithm::replace_all_copy(eclassName, ":", "_") + "_1";

        entity->setKeyValue("name", entityName);
    }

    return node;
}
示例#2
0
std::string EClassTreeBuilder::getInheritancePathRecursive(const IEntityClassPtr& eclass) {
	std::string returnValue;
	
	try {
		EntityClassAttribute attribute = eclass->getAttribute(INHERIT_KEY);
		
		// Don't use empty or derived "inherit" keys
		if (!attribute.value.empty() && !attribute.inherited) {
			
			// Get the inherited eclass first and resolve the path
			IEntityClassPtr parent = GlobalEntityClassManager().findClass(
				attribute.value
			);
			
			if (parent != NULL) {
				returnValue += getInheritancePathRecursive(parent);
			}
			else {
				globalErrorStream() << "EClassTreeBuilder: Cannot resolve inheritance path for " 
					<< eclass->getName() << std::endl;
			}
			
			returnValue += attribute.value + "/";
		}
	}
	catch (std::runtime_error&) {
		// no inherit key
	}
	
	return returnValue;
}
std::string DifficultySettings::getInheritanceKey(const std::string& className)
{
    if (className.empty()) return "";

    IEntityClassPtr eclass = GlobalEntityClassManager().findClass(className);

    // Get the inheritance chain of this class
    std::list<std::string> inheritanceChain;
    for (const IEntityClass* currentClass = eclass.get();
         currentClass != NULL;
         currentClass = currentClass->getParent())
    {
        inheritanceChain.push_front(currentClass->getName());
    }

    // Build the inheritance key
    std::string inheritanceKey;
    for (std::list<std::string>::const_iterator c = inheritanceChain.begin();
         c != inheritanceChain.end();
         c++)
    {
        inheritanceKey += (inheritanceKey.empty()) ? "" : "_";
        inheritanceKey += *c;
    }

    return inheritanceKey;
}
	void visit(const IEntityClassPtr& eclass)
	{
		if (boost::algorithm::starts_with(eclass->getName(), _prefix))
		{
			// We have a match, store the eclassptr
			_map[eclass->getName()] = eclass;
		}
	}
// Required visit function
void EntityClassTreePopulator::visit(const IEntityClassPtr& eclass)
{
	std::string folderPath = eclass->getAttribute(_folderKey).getValue();

    if (!folderPath.empty())
	{
        folderPath = "/" + folderPath;
	}

	// Create the folder to put this EntityClass in, depending on the value
	// of the DISPLAY_FOLDER_KEY.
    addPath(eclass->getModName() + folderPath + "/" + eclass->getName());
}
std::string DifficultySettings::getParentClass(const std::string& className)
{
    // Get the parent eclass
    IEntityClassPtr eclass = GlobalEntityClassManager().findClass(className);

    if (eclass == NULL)
	{
        return ""; // Invalid!
    }

    EntityClassAttribute inheritAttr = eclass->getAttribute("inherit");
    return inheritAttr.getValue();
}
示例#7
0
scene::INodePtr Doom3EntityCreator::getEntityForEClass(const IEntityClassPtr& eclass) {

    // Null entityclass check
    if (!eclass) {
        throw std::runtime_error(
            _("Doom3EntityCreator::getEntityForEClass(): "
              "cannot create entity for NULL entityclass.")
        );
    }

    // Otherwise create the correct entity subclass based on the entity class
    // parameters.
    scene::INodePtr returnValue;

    if (eclass->isLight()) {
        LightNodePtr node(new LightNode(eclass));
        node->construct();

        returnValue = node;
    }
    else if (!eclass->isFixedSize()) {
        // Variable size entity
        Doom3GroupNodePtr node(new Doom3GroupNode(eclass));
        node->construct();

        returnValue = node;
    }
    else if (!eclass->getAttribute("model").value.empty()) {
        // Fixed size, has model path
        EclassModelNodePtr node(new EclassModelNode(eclass));
        node->construct();

        returnValue = node;
    }
    else if (eclass->getName() == "speaker") {
        SpeakerNodePtr node(new SpeakerNode(eclass));
        node->construct();

        returnValue = node;
    }
    else {
        // Fixed size, no model path
        GenericEntityNodePtr node(new GenericEntityNode(eclass));
        node->construct();

        returnValue = node;
    }

    return returnValue;
}
示例#8
0
void EClassTreeBuilder::visit(IEntityClassPtr eclass) {
	std::string fullPath;
	
	// Prefix mod name
	fullPath = eclass->getModName() + "/";
	
	// Prefix inheritance path (recursively)
	fullPath += getInheritancePathRecursive(eclass);
	
	// The entityDef name itself
	fullPath += eclass->getName();
	
	// Let the VFSTreePopulator do the insertion
	_treePopulator.addPath(fullPath);
}
示例#9
0
void Doom3EntityClass::buildInheritanceChain() {
	_inheritanceChain.clear();

	// We start with the name of this class
	_inheritanceChain.push_back(_name);
	
	// Walk up the inheritance chain
	std::string parentClassName = getAttribute("inherit").value;
	while (!parentClassName.empty()) {
		_inheritanceChain.push_front(parentClassName);

		// Get the parent eclass
		IEntityClassPtr parentClass = GlobalEntityClassManager().findClass(parentClassName);

		if (parentClass == NULL) {
			break;
		}

		parentClassName = parentClass->getAttribute("inherit").value;
	}
}
示例#10
0
void EClassManager::resolveInheritance()
{
	// Resolve inheritance on the model classes
    for (Models::iterator i = _models.begin(); i != _models.end(); ++i) {
    	resolveModelInheritance(i->first, i->second);
    }
        
    // Resolve inheritance for the entities. At this stage the classes
    // will have the name of their parent, but not an actual pointer to
    // it
    for (EntityClasses::iterator i = _entityClasses.begin();
         i != _entityClasses.end(); ++i) 
	{
		// Tell the class to resolve its own inheritance using the given
		// map as a source for parent lookup
		i->second->resolveInheritance(_entityClasses);

        // If the entity has a model path ("model" key), lookup the actual
        // model and apply its mesh and skin to this entity.
        if (i->second->getModelPath().size() > 0) {
            Models::iterator j = _models.find(i->second->getModelPath());
            if (j != _models.end()) {
                i->second->setModelPath(j->second->mesh);
                i->second->setSkin(j->second->skin);
            }
        }
    }

	// greebo: Override the eclass colours of two special entityclasses
    Vector3 worlspawnColour = ColourSchemes().getColour("default_brush");
    Vector3 lightColour = ColourSchemes().getColour("light_volumes");
    
    IEntityClassPtr light = findOrInsert("light", true);
	light->setColour(lightColour);
	
	IEntityClassPtr worldspawn = findOrInsert("worldspawn", true);
	worldspawn->setColour(worlspawnColour);

}
void DifficultySettingsManager::loadDifficultyNames() {
    // Locate the worldspawn entity
    Entity* worldspawn = Scene_FindEntityByClass("worldspawn");

    // Try to locate the difficulty menu entity, where the default names are defined
    IEntityClassPtr eclass = GlobalEntityClassManager().findClass(
        game::current::getValue<std::string>(GKEY_DIFFICULTY_ENTITYDEF_MENU)
    );

    // greebo: Setup the default difficulty levels using the found entityDef
    int numLevels = game::current::getValue<int>(GKEY_DIFFICULTY_LEVELS);
    for (int i = 0; i < numLevels; i++) {
        std::string nameKey = "diff" + string::to_string(i) + "default";

        // First, try to find a map-specific name
        if (worldspawn != NULL) {
            std::string name = worldspawn->getKeyValue(nameKey);
            if (!name.empty()) {
                // Found a setting on worldspawn, take it
                _difficultyNames.push_back(name);
                continue; // done for this level
            }
        }

        // If the above failed, try to load the default setting
        if (eclass != NULL) {
            EntityClassAttribute attr = eclass->getAttribute(nameKey);

            if (!attr.getValue().empty()) {
                _difficultyNames.push_back(attr.getValue());
                continue;
            }
        }

        // Fall back to a non-empty default
        _difficultyNames.push_back(string::to_string(i));
    }
}
	void visit(const IEntityClassPtr& eclass)
	{
		if (boost::algorithm::starts_with(eclass->getName(), _prefix))
		{
			// We have a match, create a new structure
			ConversationCommandInfoPtr commandInfo(new ConversationCommandInfo);

			// Fill the values from the found entityDef
			commandInfo->parseFromEntityClass(eclass);

			// Store the structure to the target map
			_map[commandInfo->name] = commandInfo;
		}
	}
void DifficultySettings::parseFromEntityDef(const IEntityClassPtr& def)
{
    // Construct the prefix for the desired difficulty level
    std::string diffPrefix = "diff_" + string::to_string(_level) + "_";
    std::string prefix = diffPrefix + "change_";

    eclass::AttributeList spawnargs = eclass::getSpawnargsWithPrefix(*def, prefix);

    for (eclass::AttributeList::iterator i = spawnargs.begin();
         i != spawnargs.end(); ++i)
    {
        EntityClassAttribute& attr = *i;

        if (attr.getValue().empty()) {
            continue; // empty spawnarg attribute => invalid
        }

        // Get the index from the string's tail
        std::string indexStr = attr.getName().substr(prefix.length());

        const EntityClassAttribute& classAttr = def->getAttribute(diffPrefix + "class_" + indexStr);
        const EntityClassAttribute& argAttr = def->getAttribute(diffPrefix + "arg_" + indexStr);

        SettingPtr setting = createSetting(classAttr.getValue());
        setting->spawnArg = attr.getValue();
        setting->argument = argAttr.getValue();

        // This has been parsed from the default entityDef
        setting->isDefault = true;

        // Interpret/parse the argument string
        setting->parseAppType();
    }

    clearTreeModel();
    updateTreeModel();
}
示例#14
0
void EClassTree::updatePropertyView(const std::string& eclassName) {
	// Clear the existing list
	gtk_list_store_clear(_propertyStore);
	
	IEntityClassPtr eclass = GlobalEntityClassManager().findClass(eclassName);
	if (eclass == NULL) {
		return;
	}
	
	class ListStorePopulator :
		public EntityClassAttributeVisitor
	{
		GtkListStore* _listStore;
	public:
		ListStorePopulator(GtkListStore* targetStore) :
			_listStore(targetStore)
		{}
		
		virtual void visit(const EntityClassAttribute& attr) {
			// Append the details to the treestore
			GtkTreeIter iter;
			gtk_list_store_append(_listStore, &iter);
			gtk_list_store_set(
				_listStore, &iter,
				PROPERTY_NAME_COLUMN, attr.name.c_str(),
				PROPERTY_VALUE_COLUMN, attr.value.c_str(),
				PROPERTY_TEXT_COLOUR_COLUMN, attr.inherited ? "#666666" : "black",
				PROPERTY_INHERITED_FLAG_COLUMN, attr.inherited ? "1" : "0",
				-1
			);
		}
	};
	
	ListStorePopulator populator(_propertyStore);
	eclass->forEachClassAttribute(populator, true);
}
示例#15
0
// Required visit function
void EntityClassTreePopulator::visit(IEntityClassPtr e) {
    // Recursively create the folder to put this EntityClass in,
    // depending on the value of the DISPLAY_FOLDER_KEY. This may return
    // NULL if the key is unset, in which case we add the entity at
    // the top level.
    GtkTreeIter* parIter = addDisplayFolder(e);
    
    // Add the new class under the parent folder
    GtkTreeIter iter;
    gtk_tree_store_append(_store, &iter, parIter);
    gtk_tree_store_set(_store, &iter, 
                       NAME_COLUMN, e->getName().c_str(), 
                       ICON_COLUMN, GlobalUIManager().getLocalPixbuf(ENTITY_ICON),
                       DIR_FLAG_COLUMN, FALSE,
                       -1);
}
示例#16
0
/**
 * Create an instance of the given entity at the given position, and return
 * the Node containing the new entity.
 *
 * @returns: the scene::INodePtr referring to the new entity.
 */
scene::INodePtr createEntityFromSelection(const std::string& name, const Vector3& origin)
{
    // Obtain the structure containing the selection counts
    const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();

    IEntityClassPtr entityClass = GlobalEntityClassManager().findOrInsert(name, true);

    // TODO: to be replaced by inheritance-based class detection
    bool isModel = (info.totalCount == 0 && name == "func_static");

    // Some entities are based on the size of the currently-selected primitive(s)
    bool primitivesSelected = info.brushCount > 0 || info.patchCount > 0;

    if (!(entityClass->isFixedSize() || isModel) && !primitivesSelected) {
        throw EntityCreationException(
            (boost::format(_("Unable to create entity %s, no brushes selected.")) % name).str()
        );
    }

    // Get the selection workzone bounds
    AABB workzone = GlobalSelectionSystem().getWorkZone().bounds;

    // Create the new node for the entity
    IEntityNodePtr node(GlobalEntityCreator().createEntity(entityClass));

    GlobalSceneGraph().root()->addChildNode(node);

    // The layer list we're moving the newly created node/subgraph into
    scene::LayerList targetLayers;

    if (entityClass->isFixedSize() || (isModel && !primitivesSelected))
    {
        selection::algorithm::deleteSelection();

        ITransformablePtr transform = Node_getTransformable(node);

        if (transform != 0) {
            transform->setType(TRANSFORM_PRIMITIVE);
            transform->setTranslation(origin);
            transform->freezeTransform();
        }

        GlobalSelectionSystem().setSelectedAll(false);

        // Move the item to the active layer
        targetLayers.insert(GlobalLayerSystem().getActiveLayer());

        Node_setSelected(node, true);
    }
    else // brush-based entity
    {
        // Add selected brushes as children of non-fixed entity
        node->getEntity().setKeyValue("model",
                                      node->getEntity().getKeyValue("name"));

        // Take the selection center as new origin
        Vector3 newOrigin = selection::algorithm::getCurrentSelectionCenter();
        node->getEntity().setKeyValue("origin", string::to_string(newOrigin));

        // If there is an "editor_material" class attribute, apply this shader
        // to all of the selected primitives before parenting them
        std::string material = node->getEntity().getEntityClass()->getAttribute("editor_material").getValue();

        if (!material.empty()) {
            selection::algorithm::applyShaderToSelection(material);
        }

        // If we had primitives to reparent, the new entity should inherit the layer info from them
        if (primitivesSelected)
        {
            scene::INodePtr primitive = GlobalSelectionSystem().ultimateSelected();
            targetLayers = primitive->getLayers();
        }
        else
        {
            // Otherwise move the item to the active layer
            targetLayers.insert(GlobalLayerSystem().getActiveLayer());
        }

        // Parent the selected primitives to the new node
        selection::algorithm::ParentPrimitivesToEntityWalker walker(node);
        GlobalSelectionSystem().foreachSelected(walker);
        walker.reparent();

        // De-select the children and select the newly created parent entity
        GlobalSelectionSystem().setSelectedAll(false);
        Node_setSelected(node, true);
    }

    // Assign the layers - including all child nodes (#2864)
    scene::AssignNodeToLayersWalker layerWalker(targetLayers);
    Node_traverseSubgraph(node, layerWalker);

    // Set the light radius and origin

    if (entityClass->isLight() && primitivesSelected)
    {
        AABB bounds(Doom3Light_getBounds(workzone));
        node->getEntity().setKeyValue("origin",
                                      string::to_string(bounds.getOrigin()));
        node->getEntity().setKeyValue("light_radius",
                                      string::to_string(bounds.getExtents()));
    }

    // Flag the map as unsaved after creating the entity
    GlobalMap().setModified(true);

    // Check for auto-setting key values. TODO: use forEachClassAttribute
    // directly here.
    eclass::AttributeList list = eclass::getSpawnargsWithPrefix(
        *entityClass, "editor_setKeyValue"
    );

    if (!list.empty())
    {
        for (eclass::AttributeList::const_iterator i = list.begin(); i != list.end(); ++i)
        {
            // Cut off the "editor_setKeyValueN " string from the key to get the spawnarg name
            std::string key = i->getName().substr(i->getName().find_first_of(' ') + 1);
            node->getEntity().setKeyValue(key, i->getValue());
        }
    }

    // Return the new node
    return node;
}