Ejemplo n.º 1
0
void CCmpPathfinder::Init(const CParamNode& UNUSED(paramNode))
{
	m_MapSize = 0;
	m_Grid = NULL;
	m_TerrainOnlyGrid = NULL;

	m_ObstructionsDirty.Clean();
	m_PreserveUpdateInformations = false;

	m_NextAsyncTicket = 1;

	m_DebugOverlay = false;
	m_AtlasOverlay = NULL;

	m_SameTurnMovesCount = 0;

	// Register Relax NG validator
	CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng");

	// Since this is used as a system component (not loaded from an entity template),
	// we can't use the real paramNode (it won't get handled properly when deserializing),
	// so load the data from a special XML file.
	CParamNode externalParamNode;
	CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml", "pathfinder");

    // Previously all move commands during a turn were
    // queued up and processed asynchronously at the start
    // of the next turn.  Now we are processing queued up 
    // events several times duing the turn.  This improves
    // responsiveness and units move more smoothly especially.
    // when in formation.  There is still a call at the 
    // beginning of a turn to process all outstanding moves - 
    // this will handle any moves above the MaxSameTurnMoves 
    // threshold.  
    //
    // TODO - The moves processed at the beginning of the 
    // turn do not count against the maximum moves per turn 
    // currently.  The thinking is that this will eventually 
    // happen in another thread.  Either way this probably 
    // will require some adjustment and rethinking.
	const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder");
	m_MaxSameTurnMoves = (u16)pathingSettings.GetChild("MaxSameTurnMoves").ToInt();


	const CParamNode::ChildrenMap& passClasses = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses").GetChildren();
	for (CParamNode::ChildrenMap::const_iterator it = passClasses.begin(); it != passClasses.end(); ++it)
	{
		std::string name = it->first;
		ENSURE((int)m_PassClasses.size() <= PASS_CLASS_BITS);
		pass_class_t mask = PASS_CLASS_MASK_FROM_INDEX(m_PassClasses.size());
		m_PassClasses.push_back(PathfinderPassability(mask, it->second));
		m_PassClassMasks[name] = mask;
	}
}
Ejemplo n.º 2
0
void CCmpPathfinder::Init(const CParamNode& UNUSED(paramNode))
{
	m_MapSize = 0;
	m_Grid = NULL;
	m_ObstructionGrid = NULL;
	m_TerrainDirty = true;
	m_NextAsyncTicket = 1;

	m_DebugOverlay = NULL;
	m_DebugGrid = NULL;
	m_DebugPath = NULL;

	m_SameTurnMovesCount = 0;

	// Since this is used as a system component (not loaded from an entity template),
	// we can't use the real paramNode (it won't get handled properly when deserializing),
	// so load the data from a special XML file.
	CParamNode externalParamNode;
	CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml");

    // Previously all move commands during a turn were
    // queued up and processed asynchronously at the start
    // of the next turn.  Now we are processing queued up 
    // events several times duing the turn.  This improves
    // responsiveness and units move more smoothly especially.
    // when in formation.  There is still a call at the 
    // beginning of a turn to process all outstanding moves - 
    // this will handle any moves above the MaxSameTurnMoves 
    // threshold.  
    //
    // TODO - The moves processed at the beginning of the 
    // turn do not count against the maximum moves per turn 
    // currently.  The thinking is that this will eventually 
    // happen in another thread.  Either way this probably 
    // will require some adjustment and rethinking.
	const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder");
	m_MaxSameTurnMoves = (u16)pathingSettings.GetChild("MaxSameTurnMoves").ToInt();


	const CParamNode::ChildrenMap& passClasses = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses").GetChildren();
	for (CParamNode::ChildrenMap::const_iterator it = passClasses.begin(); it != passClasses.end(); ++it)
	{
		std::string name = it->first;
		ENSURE((int)m_PassClasses.size() <= PASS_CLASS_BITS);
		pass_class_t mask = (pass_class_t)(1u << (m_PassClasses.size() + 2));
		m_PassClasses.push_back(PathfinderPassability(mask, it->second));
		m_PassClassMasks[name] = mask;
	}


	const CParamNode::ChildrenMap& moveClasses = externalParamNode.GetChild("Pathfinder").GetChild("MovementClasses").GetChildren();

	// First find the set of unit classes used by any terrain classes,
	// and assign unique tags to terrain classes
	std::set<std::string> unitClassNames;
	unitClassNames.insert("default"); // must always have costs for default

	{
		size_t i = 0;
		for (CParamNode::ChildrenMap::const_iterator it = moveClasses.begin(); it != moveClasses.end(); ++it)
		{
			std::string terrainClassName = it->first;
			m_TerrainCostClassTags[terrainClassName] = (cost_class_t)i;
			++i;

			const CParamNode::ChildrenMap& unitClasses = it->second.GetChild("UnitClasses").GetChildren();
			for (CParamNode::ChildrenMap::const_iterator uit = unitClasses.begin(); uit != unitClasses.end(); ++uit)
				unitClassNames.insert(uit->first);
		}
	}

	// For each terrain class, set the costs for every unit class,
	// and assign unique tags to unit classes
	{
		size_t i = 0;
		for (std::set<std::string>::const_iterator nit = unitClassNames.begin(); nit != unitClassNames.end(); ++nit)
		{
			m_UnitCostClassTags[*nit] = (cost_class_t)i;
			++i;

			std::vector<u32> costs;
			std::vector<fixed> speeds;

			for (CParamNode::ChildrenMap::const_iterator it = moveClasses.begin(); it != moveClasses.end(); ++it)
			{
				// Default to the general costs for this terrain class
				fixed cost = it->second.GetChild("@Cost").ToFixed();
				fixed speed = it->second.GetChild("@Speed").ToFixed();
				// Check for specific cost overrides for this unit class
				const CParamNode& unitClass = it->second.GetChild("UnitClasses").GetChild(nit->c_str());
				if (unitClass.IsOk())
				{
					cost = unitClass.GetChild("@Cost").ToFixed();
					speed = unitClass.GetChild("@Speed").ToFixed();
				}
				costs.push_back((cost * DEFAULT_MOVE_COST).ToInt_RoundToZero());
				speeds.push_back(speed);
			}

			m_MoveCosts.push_back(costs);
			m_MoveSpeeds.push_back(speeds);
		}
	}
}