Ejemplo n.º 1
0
std::vector<entity_id_t> EntitySelection::PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, const std::string& templateName, int owner, bool includeOffScreen, bool matchRank)
{
	CmpPtr<ICmpTemplateManager> cmpTemplateManager(simulation, SYSTEM_ENTITY);
	CmpPtr<ICmpRangeManager> cmpRangeManager(simulation, SYSTEM_ENTITY);

	std::vector<entity_id_t> hitEnts;

 	const CSimulation2::InterfaceListUnordered& ents = simulation.GetEntitiesWithInterfaceUnordered(IID_Selectable);
	for (CSimulation2::InterfaceListUnordered::const_iterator it = ents.begin(); it != ents.end(); ++it)
	{
 		entity_id_t ent = it->first;

		if (matchRank)
		{
			// Exact template name matching
			if (cmpTemplateManager->GetCurrentTemplateName(ent) != templateName)
				continue;
		}

		// Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld)
		// In this case, the checking is done to avoid selecting garrisoned units
		if (cmpRangeManager->GetLosVisibility(ent, owner) == ICmpRangeManager::VIS_HIDDEN)
			continue;

 		// Ignore entities not owned by 'owner'
 		CmpPtr<ICmpOwnership> cmpOwnership(simulation.GetSimContext(), ent);
 		if (!cmpOwnership || cmpOwnership->GetOwner() != owner)
 			continue;

		// Ignore off screen entities
 		if (!includeOffScreen)
 		{
 			// Find the current interpolated model position.
			CmpPtr<ICmpVisual> cmpVisual(simulation.GetSimContext(), ent);
			if (!cmpVisual)
				continue;
			CVector3D position = cmpVisual->GetPosition();

			// Reject if it's not on-screen (e.g. it's behind the camera)
			if (!camera.GetFrustum().IsPointVisible(position))
				continue;
 		}

		if (!matchRank)
		{
			// Match by selection group name
			// (This is relatively expensive since it involves script calls, so do it after all other tests)
			CmpPtr<ICmpIdentity> cmpIdentity(simulation.GetSimContext(), ent);
			if (!cmpIdentity || cmpIdentity->GetSelectionGroupName() != templateName)
				continue;
		}

 		hitEnts.push_back(ent);
 	}

 	return hitEnts;
}
Ejemplo n.º 2
0
void CMapWriter::WriteXML(const VfsPath& filename,
						  WaterManager* pWaterMan, SkyManager* pSkyMan,
						  CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema,
						  CPostprocManager* pPostproc,
						  CSimulation2* pSimulation2)
{
	XML_Start();

	{
		XML_Element("Scenario");
		XML_Attribute("version", (int)FILE_VERSION);

		ENSURE(pSimulation2);
		CSimulation2& sim = *pSimulation2;

		if (!sim.GetStartupScript().empty())
		{
			XML_Element("Script");
			XML_CDATA(sim.GetStartupScript().c_str());
		}

		{
			XML_Element("Environment");

			XML_Setting("SkySet", pSkyMan->GetSkySet());
			{
				XML_Element("SunColor");
				XML_Attribute("r", pLightEnv->m_SunColor.X); // yes, it's X/Y/Z...
				XML_Attribute("g", pLightEnv->m_SunColor.Y);
				XML_Attribute("b", pLightEnv->m_SunColor.Z);
			}
			{
				XML_Element("SunElevation");
				XML_Attribute("angle", pLightEnv->m_Elevation);
			}
			{
				XML_Element("SunRotation");
				XML_Attribute("angle", pLightEnv->m_Rotation);
			}
			{
				XML_Element("TerrainAmbientColor");
				XML_Attribute("r", pLightEnv->m_TerrainAmbientColor.X);
				XML_Attribute("g", pLightEnv->m_TerrainAmbientColor.Y);
				XML_Attribute("b", pLightEnv->m_TerrainAmbientColor.Z);
			}
			{
				XML_Element("UnitsAmbientColor");
				XML_Attribute("r", pLightEnv->m_UnitsAmbientColor.X);
				XML_Attribute("g", pLightEnv->m_UnitsAmbientColor.Y);
				XML_Attribute("b", pLightEnv->m_UnitsAmbientColor.Z);
			}
			{
				XML_Element("Fog");
				XML_Setting("FogFactor", pLightEnv->m_FogFactor);
				XML_Setting("FogThickness", pLightEnv->m_FogMax);
				{
					XML_Element("FogColor");
					XML_Attribute("r", pLightEnv->m_FogColor.X);
					XML_Attribute("g", pLightEnv->m_FogColor.Y);
					XML_Attribute("b", pLightEnv->m_FogColor.Z);
				}
			}

			{
				XML_Element("Water");
				{
					XML_Element("WaterBody");
					CmpPtr<ICmpWaterManager> cmpWaterManager(sim, SYSTEM_ENTITY);
					ENSURE(cmpWaterManager);
					XML_Setting("Type", pWaterMan->m_WaterType);
					{
						XML_Element("Color");
						XML_Attribute("r", pWaterMan->m_WaterColor.r);
						XML_Attribute("g", pWaterMan->m_WaterColor.g);
						XML_Attribute("b", pWaterMan->m_WaterColor.b);
					}
					{
						XML_Element("Tint");
						XML_Attribute("r", pWaterMan->m_WaterTint.r);
						XML_Attribute("g", pWaterMan->m_WaterTint.g);
						XML_Attribute("b", pWaterMan->m_WaterTint.b);
					}
					XML_Setting("Height", cmpWaterManager->GetExactWaterLevel(0, 0));
					XML_Setting("Waviness", pWaterMan->m_Waviness);
					XML_Setting("Murkiness", pWaterMan->m_Murkiness);
					XML_Setting("WindAngle", pWaterMan->m_WindAngle);
				}
			}

			{
				XML_Element("Postproc");
				{
					XML_Setting("Brightness", pLightEnv->m_Brightness);
					XML_Setting("Contrast", pLightEnv->m_Contrast);
					XML_Setting("Saturation", pLightEnv->m_Saturation);
					XML_Setting("Bloom", pLightEnv->m_Bloom);
					XML_Setting("PostEffect", pPostproc->GetPostEffect());
				}
			}
		}

		{
			XML_Element("Camera");

			{
				XML_Element("Position");
				CVector3D pos = pCamera->m_Orientation.GetTranslation();
				XML_Attribute("x", pos.X);
				XML_Attribute("y", pos.Y);
				XML_Attribute("z", pos.Z);
			}

			CVector3D in = pCamera->m_Orientation.GetIn();
			// Convert to spherical coordinates
			float rotation = atan2(in.X, in.Z);
			float declination = atan2(sqrt(in.X*in.X + in.Z*in.Z), in.Y) - (float)M_PI/2;

			{
				XML_Element("Rotation");
				XML_Attribute("angle", rotation);
			}
			{
				XML_Element("Declination");
				XML_Attribute("angle", declination);
			}
		}

		{
			std::string settings = sim.GetMapSettingsString();
			if (!settings.empty())
			{
				XML_Element("ScriptSettings");
				XML_CDATA(("\n" + settings + "\n").c_str());
			}
		}

		{
			XML_Element("Entities");

			CmpPtr<ICmpTemplateManager> cmpTemplateManager(sim, SYSTEM_ENTITY);
			ENSURE(cmpTemplateManager);

			// This will probably need to be changed in the future, but for now we'll
			// just save all entities that have a position
			CSimulation2::InterfaceList ents = sim.GetEntitiesWithInterface(IID_Position);
			for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
			{
				entity_id_t ent = it->first;

				// Don't save local entities (placement previews etc)
				if (ENTITY_IS_LOCAL(ent))
					continue;

				XML_Element("Entity");
				XML_Attribute("uid", ent);

				XML_Setting("Template", cmpTemplateManager->GetCurrentTemplateName(ent));

				CmpPtr<ICmpOwnership> cmpOwnership(sim, ent);
				if (cmpOwnership)
					XML_Setting("Player", (int)cmpOwnership->GetOwner());

				CmpPtr<ICmpPosition> cmpPosition(sim, ent);
				if (cmpPosition)
				{
					CFixedVector3D pos;
					if (cmpPosition->IsInWorld())
						pos = cmpPosition->GetPosition();

					CFixedVector3D rot = cmpPosition->GetRotation();
					{
						XML_Element("Position");
						XML_Attribute("x", pos.X);
						XML_Attribute("z", pos.Z);
						// TODO: height offset etc
					}
					{
						XML_Element("Orientation");
						XML_Attribute("y", rot.Y);
						// TODO: X, Z maybe
					}
				}

				CmpPtr<ICmpObstruction> cmpObstruction(sim, ent);
				if (cmpObstruction)
				{
					// TODO: Currently only necessary because Atlas
					// does not set up control groups for its walls.
					cmpObstruction->ResolveFoundationCollisions();

					entity_id_t group = cmpObstruction->GetControlGroup();
					entity_id_t group2 = cmpObstruction->GetControlGroup2();

					// Don't waste space writing the default control groups.
					if (group != ent || group2 != INVALID_ENTITY)
					{
						XML_Element("Obstruction");
						if (group != ent)
							XML_Attribute("group", group);
						if (group2 != INVALID_ENTITY)
							XML_Attribute("group2", group2);
					}
				}

				CmpPtr<ICmpVisual> cmpVisual(sim, ent);
				if (cmpVisual)
				{
					u32 seed = cmpVisual->GetActorSeed();
					if (seed != (u32)ent)
					{
						XML_Element("Actor");
						XML_Attribute("seed", seed);
					}
					// TODO: variation/selection strings
				}
			}
		}

		const std::map<CStrW, CCinemaPath>& paths = pCinema->GetAllPaths();
		std::map<CStrW, CCinemaPath>::const_iterator it = paths.begin();

		{
			XML_Element("Paths");

			for ( ; it != paths.end(); ++it )
			{
				fixed timescale = it->second.GetTimescale();
				const std::vector<SplineData>& nodes = it->second.GetAllNodes();
				const std::vector<SplineData>& target_nodes = it->second.GetTargetSpline().GetAllNodes();
				const CCinemaData* data = it->second.GetData();
				
				XML_Element("Path");
				XML_Attribute("name", data->m_Name);
				XML_Attribute("timescale", timescale);
				XML_Attribute("orientation", data->m_Orientation);
				XML_Attribute("mode", data->m_Mode);
				XML_Attribute("style", data->m_Style);

				fixed last_target = fixed::Zero();
				for (size_t i = 0, j = 0; i < nodes.size(); ++i)
				{
					XML_Element("Node");
					fixed distance = i > 0 ? nodes[i - 1].Distance : fixed::Zero();
					last_target += distance;

					XML_Attribute("deltatime", distance);

					{
						XML_Element("Position");
						XML_Attribute("x", nodes[i].Position.X);
						XML_Attribute("y", nodes[i].Position.Y);
						XML_Attribute("z", nodes[i].Position.Z);
					}

					{
						XML_Element("Rotation");
						XML_Attribute("x", nodes[i].Rotation.X);
						XML_Attribute("y", nodes[i].Rotation.Y);
						XML_Attribute("z", nodes[i].Rotation.Z);
					}

					if (j >= target_nodes.size())
						continue;

					fixed target_distance = j > 0 ? target_nodes[j - 1].Distance : fixed::Zero();

					if (target_distance > last_target)
						continue;

					{
						XML_Element("Target");
						XML_Attribute("x", target_nodes[j].Position.X);
						XML_Attribute("y", target_nodes[j].Position.Y);
						XML_Attribute("z", target_nodes[j].Position.Z);
					}

					last_target = fixed::Zero();
					++j;
				}
			}
		}
	}
	if (!XML_StoreVFS(g_VFS, filename))
		LOGERROR("Failed to write map '%s'", filename.string8());
}
Ejemplo n.º 3
0
std::vector<entity_id_t> EntitySelection::PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, 
	const std::string& templateName, player_id_t owner, bool includeOffScreen, bool matchRank,
	bool allowEditorSelectables, bool allowFoundations)
{
	PROFILE2("PickSimilarEntities");
	CmpPtr<ICmpTemplateManager> cmpTemplateManager(simulation, SYSTEM_ENTITY);
	CmpPtr<ICmpRangeManager> cmpRangeManager(simulation, SYSTEM_ENTITY);

	std::vector<entity_id_t> hitEnts;

 	const CSimulation2::InterfaceListUnordered& ents = simulation.GetEntitiesWithInterfaceUnordered(IID_Selectable);
	for (CSimulation2::InterfaceListUnordered::const_iterator it = ents.begin(); it != ents.end(); ++it)
	{
 		entity_id_t ent = it->first;
		CEntityHandle handle = it->second->GetEntityHandle();

		// Check if this entity is only selectable in Atlas
		if (static_cast<ICmpSelectable*>(it->second)->IsEditorOnly() && !allowEditorSelectables)
			continue;

		if (matchRank)
		{
			// Exact template name matching, optionally also allowing foundations
			std::string curTemplateName = cmpTemplateManager->GetCurrentTemplateName(ent);
			bool matches = (curTemplateName == templateName ||
			                (allowFoundations && curTemplateName.substr(0, 11) == "foundation|" && curTemplateName.substr(11) == templateName));
			if (!matches)
				continue;
		}

		// Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld)
		// In this case, the checking is done to avoid selecting garrisoned units
		if (cmpRangeManager->GetLosVisibility(handle, owner) == ICmpRangeManager::VIS_HIDDEN)
			continue;

		// Ignore entities not owned by 'owner'
		CmpPtr<ICmpOwnership> cmpOwnership(simulation.GetSimContext(), ent);
		if (owner != INVALID_PLAYER && (!cmpOwnership || cmpOwnership->GetOwner() != owner))
			continue;

		// Ignore off screen entities
		if (!includeOffScreen)
		{
 			// Find the current interpolated model position.
			CmpPtr<ICmpVisual> cmpVisual(simulation.GetSimContext(), ent);
			if (!cmpVisual)
				continue;
			CVector3D position = cmpVisual->GetPosition();

			// Reject if it's not on-screen (e.g. it's behind the camera)
			if (!camera.GetFrustum().IsPointVisible(position))
				continue;
		}

		if (!matchRank)
		{
			// Match by selection group name
			// (This is relatively expensive since it involves script calls, so do it after all other tests)
			CmpPtr<ICmpIdentity> cmpIdentity(simulation.GetSimContext(), ent);
			if (!cmpIdentity || cmpIdentity->GetSelectionGroupName() != templateName)
				continue;
		}

 		hitEnts.push_back(ent);
 	}

 	return hitEnts;
}