コード例 #1
0
void PathInfo::BuildPolyPath(PathNode startPos, PathNode endPos)
{
    // *** getting start/end poly logic ***

    float distToStartPoly, distToEndPoly;
    float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x};
    float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x};

    dtPolyRef startPoly = getPolyByLocation(startPoint, &distToStartPoly);
    dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly);

    // we have a hole in our mesh
    // make shortcut path and mark it as NOPATH ( with flying exception )
    // its up to caller how he will use this info
    if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n");
        BuildShortcut();
        m_type = (m_sourceUnit->GetTypeId() == TYPEID_UNIT && ((Creature*)m_sourceUnit)->CanFly())
                    ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH;
        return;
    }

    // we may need a better number here
    bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f);
    if (farFromPoly)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly);

        bool buildShotrcut = false;
        if (m_sourceUnit->GetTypeId() == TYPEID_UNIT)
        {
            Creature* owner = (Creature*)m_sourceUnit;

            PathNode p = (distToStartPoly > 7.0f) ? startPos : endPos;
            if (m_sourceUnit->GetTerrain()->IsUnderWater(p.x, p.y, p.z))
            {
                DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: underWater case\n");
                if (owner->CanSwim() || owner->IsPet())
                    buildShotrcut = true;
            }
            else
            {
                DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: flying case\n");
                if (owner->CanFly())
                    buildShotrcut = true;
            }
        }

        if (buildShotrcut)
        {
            BuildShortcut();
            m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
            return;
        }
        else
        {
            float closestPoint[VERTEX_SIZE];
            // we may want to use closestPointOnPolyBoundary instead
            if (DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))
            {
                dtVcopy(endPoint, closestPoint);
                setActualEndPosition(PathNode(endPoint[2],endPoint[0],endPoint[1]));
            }

            m_type = PATHFIND_INCOMPLETE;
        }
    }

    // *** poly path generating logic ***

    // start and end are on same polygon
    // just need to move in straight line
    if (startPoly == endPoly)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: (startPoly == endPoly)\n");

        BuildShortcut();

        m_pathPolyRefs[0] = startPoly;
        m_polyLength = 1;

        m_type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL;
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: path type %d\n", m_type);
        return;
    }

    // look for startPoly/endPoly in current path
    // TODO: we can merge it with getPathPolyByPosition() loop
    bool startPolyFound = false;
    bool endPolyFound = false;
    uint32 pathStartIndex, pathEndIndex;

    if (m_polyLength)
    {
        for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex)
        {
            // here to carch few bugs
            MANGOS_ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF);
            
            if (m_pathPolyRefs[pathStartIndex] == startPoly)
            {
                startPolyFound = true;
                break;
            }
        }

        for (pathEndIndex = m_polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex)
            if (m_pathPolyRefs[pathEndIndex] == endPoly)
            {
                endPolyFound = true;
                break;
            }
    }

    if (startPolyFound && endPolyFound)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n");

        // we moved along the path and the target did not move out of our old poly-path
        // our path is a simple subpath case, we have all the data we need
        // just "cut" it out

        m_polyLength = pathEndIndex - pathStartIndex + 1;
        memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, m_polyLength*sizeof(dtPolyRef));
    }
    else if (startPolyFound && !endPolyFound)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n");

        // we are moving on the old path but target moved out
        // so we have atleast part of poly-path ready

        m_polyLength -= pathStartIndex;

        // try to adjust the suffix of the path instead of recalculating entire length
        // at given interval the target cannot get too far from its last location
        // thus we have less poly to cover
        // sub-path of optimal path is optimal

        // take ~80% of the original length
        // TODO : play with the values here
        uint32 prefixPolyLength = uint32(m_polyLength*0.8f + 0.5f);
        memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, prefixPolyLength*sizeof(dtPolyRef));

        dtPolyRef suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1];

        // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
        float suffixEndPoint[VERTEX_SIZE];
        if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
        {
            // suffixStartPoly is invalid somehow, or the navmesh is broken => error state
            sLog.outError("%u's Path Build failed: invalid polyRef in path", m_sourceUnit->GetGUID());

            BuildShortcut();
            m_type = PATHFIND_NOPATH;
            return;
        }

        // generate suffix
        uint32 suffixPolyLength = 0;
        dtStatus dtResult = m_navMeshQuery->findPath(
                                suffixStartPoly,    // start polygon
                                endPoly,            // end polygon
                                suffixEndPoint,     // start position
                                endPoint,           // end position
                                &m_filter,            // polygon search filter
                                m_pathPolyRefs + prefixPolyLength - 1,    // [out] path
                                (int*)&suffixPolyLength,
                                MAX_PATH_LENGTH-prefixPolyLength);   // max number of polygons in output path

        if (!suffixPolyLength || dtResult != DT_SUCCESS)
        {
            // this is probably an error state, but we'll leave it
            // and hopefully recover on the next Update
            // we still need to copy our preffix
            sLog.outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUID());
        }

        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++  m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength);

        // new path = prefix + suffix - overlap
        m_polyLength = prefixPolyLength + suffixPolyLength - 1;
    }
    else
    {
        DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n");

        // either we have no path at all -> first run
        // or something went really wrong -> we aren't moving along the path to the target
        // just generate new path

        // free and invalidate old path data
        clear();

        dtStatus dtResult = m_navMeshQuery->findPath(
                startPoly,          // start polygon
                endPoly,            // end polygon
                startPoint,         // start position
                endPoint,           // end position
                &m_filter,           // polygon search filter
                m_pathPolyRefs,     // [out] path
                (int*)&m_polyLength,
                MAX_PATH_LENGTH);   // max number of polygons in output path

        if (!m_polyLength || dtResult != DT_SUCCESS)
        {
            // only happens if we passed bad data to findPath(), or navmesh is messed up
            sLog.outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUID());
            BuildShortcut();
            m_type = PATHFIND_NOPATH;
            return;
        }
    }

    // by now we know what type of path we can get
    if (m_pathPolyRefs[m_polyLength - 1] == endPoly && !(m_type & PATHFIND_INCOMPLETE))
        m_type = PATHFIND_NORMAL;
    else
        m_type = PATHFIND_INCOMPLETE;

    // generate the point-path out of our up-to-date poly-path
    BuildPointPath(startPoint, endPoint);
}
コード例 #2
0
ファイル: vehicle.cpp プロジェクト: spippolatore/freesynd
void VehicleInstance::setDestinationV(Mission *m, int x, int y, int z, int ox,
                                       int oy, int new_speed)
{
    std::set < PathNode > open, closed;
    std::map < PathNode, PathNode > parent;

    m->adjXYZ(x, y, z);
    z = tile_z_;

    dest_path_.clear();
    setSpeed(0);

    if (map_ == -1 || health_ <= 0 || !(walkable(x, y, z)))
        return;

    if (!walkable(tile_x_, tile_y_, tile_z_)) {
        float dBest = 100000, dCur;
        int xBest,yBest;
        // we got somewhere we shouldn't, we need to find somewhere that is walkable
        for (int j = 0; j < 5; j++)
            for (int i = 0; i < 5; i++)
                if (walkable(tile_x_ + i, tile_y_ + j, tile_z_)) {
                    dCur = sqrt((float)(i*i + j*j));
                    if(dCur < dBest) {
                        xBest = tile_x_ + i;
                        yBest = tile_y_ + j;
                        dBest = dCur;
                    }
                }
        for (int j = 0; j < 5; j++)
            for (int i = 0; i > -5; --i)
                if (walkable(tile_x_ + i, tile_y_ + j, tile_z_)) {
                    dCur = sqrt((float)(i*i + j*j));
                    if(dCur < dBest) {
                        xBest = tile_x_ + i;
                        yBest = tile_y_ + j;
                        dBest = dCur;
                    }
                }
        for (int j = 0; j > -5; --j)
            for (int i = 0; i > -5; --i)
                if (walkable(tile_x_ + i, tile_y_ + j, tile_z_)) {
                    dCur = sqrt((float)(i*i + j*j));
                    if(dCur < dBest) {
                        xBest = tile_x_ + i;
                        yBest = tile_y_ + j;
                    }
                }
        for (int j = 0; j > -5; --j)
            for (int i = 0; i < 5; i++)
                if (walkable(tile_x_ + i, tile_y_ + j, tile_z_)) {
                    dCur = sqrt((float)(i*i + j*j));
                    if(dCur < dBest) {
                        xBest = tile_x_ + i;
                        yBest = tile_y_ + j;
                        dBest = dCur;
                    }
                }
        if(dBest == 100000)
            return;
        else {
            tile_x_ = xBest;
            tile_y_ = yBest;
        }
    }

    PathNode closest;
    float closest_dist = 100000;

    open.insert(PathNode(tile_x_, tile_y_, tile_z_, off_x_, off_y_));
    int watchDog = 1000;
    while (!open.empty()) {
        watchDog--;
        float dist = 100000;
        PathNode p;
        std::set < PathNode >::iterator pit;
        for (std::set < PathNode >::iterator it = open.begin();
             it != open.end(); it++) {
            float d =
                sqrt((float) (x - it->tileX()) * (x - it->tileX()) +
                     (y - it->tileY()) * (y - it->tileY()));
            if (d < dist) {
                dist = d;
                p = *it;
                pit = it;       // it cannot be const_iterator because of this assign
            }
        }
        if (dist < closest_dist) {
            closest = p;
            closest_dist = dist;
        }
        //printf("found best dist %f in %i nodes\n", dist, open.size());
        open.erase(pit);
        closed.insert(p);

        if ((p.tileX() == x && p.tileY() == y && p.tileZ() == z)
            || watchDog < 0) {
            if (watchDog < 0) {
                p = closest;
                dest_path_.
                    push_front(PathNode
                               (p.tileX(), p.tileY(), p.tileZ(), ox, oy));
            } else
                dest_path_.push_front(PathNode(x, y, z, ox, oy));
            while (parent.find(p) != parent.end()) {
                p = parent[p];
                if (p.tileX() == tile_x_ && p.tileY() == tile_y_
                    && p.tileZ() == tile_z_)
                    break;
                dest_path_.push_front(p);
            }
            break;
        }

        std::list < PathNode > neighbours;
        uint32 goodDir = tileDir(p.tileX(), p.tileY(), p.tileZ());

        if (p.tileX() > 0) {
            if (dirWalkable(&p,p.tileX() - 1, p.tileY(), p.tileZ())
                && ((goodDir & 0xFF000000) == 0x06000000 || goodDir == 0xFFFFFFFF))
                neighbours.
                    push_back(PathNode(p.tileX() - 1, p.tileY(), p.tileZ()));
        }

        if (p.tileX() < g_App.maps().map(map())->maxX()) {
            if (dirWalkable(&p,p.tileX() + 1, p.tileY(), p.tileZ())
                && ((goodDir & 0x0000FF00) == 0x00000200 || goodDir == 0xFFFFFFFF))
                neighbours.
                    push_back(PathNode(p.tileX() + 1, p.tileY(), p.tileZ()));
        }

        if (p.tileY() > 0)
            if (dirWalkable(&p,p.tileX(), p.tileY() - 1, p.tileZ())
                && ((goodDir & 0x00FF0000) == 0x00040000 || goodDir == 0xFFFFFFFF))
                neighbours.
                    push_back(PathNode(p.tileX(), p.tileY() - 1, p.tileZ()));

        if (p.tileY() < g_App.maps().map(map())->maxY())
            if (dirWalkable(&p,p.tileX(), p.tileY() + 1, p.tileZ())
                && ((goodDir & 0x000000FF) == 0x0 || goodDir == 0xFFFFFFFF))
                neighbours.
                    push_back(PathNode(p.tileX(), p.tileY() + 1, p.tileZ()));

        for (std::list < PathNode >::iterator it = neighbours.begin();
             it != neighbours.end(); it++)
            if (dirWalkable(&p,it->tileX(), it->tileY(), it->tileZ())
                && open.find(*it) == open.end()
                && closed.find(*it) == closed.end()) {
                parent[*it] = p;
                open.insert(*it);
            }
    }

    if(!dest_path_.empty()) {
        // Adjusting offsets for correct positioning
        speed_ = new_speed;
        for(std::list < PathNode >::iterator it = dest_path_.begin();
            it != dest_path_.end(); it++) {

            // TODO : requires testing for correct offsets per
            // every direction, because in some part of game
            // vehicle position on start of game can create incorrect
            // visual representation
            // maybe offsets depend on type or tileZ?
            switch(tileDir(it->tileX(), it->tileY(), it->tileZ())) {
                case 0xFFFFFF00:
                case 0xFFFF0200:
                    it->setOffX(200);
                    it->setOffY(32);
                    break;
                case 0xFF04FFFF:
                    it->setOffX(32);
                    it->setOffY(200);
                    break;
                case 0xFFFF02FF:
                case 0xFF0402FF:
                    it->setOffX(32);
                    it->setOffY(32);
                    break;
                case 0x06FFFFFF:
                case 0x0604FFFF:
                    it->setOffX(32);
                    it->setOffY(200);
                    break;
                case 0x06FFFF00:
                    it->setOffX(200);
                    it->setOffY(200);
                    break;
                default:
                    printf("hmm tileDir %X\n", (unsigned int)tileDir(it->tileX(), it->tileY(), it->tileZ()));
                    break;
            }

        }
    }
}
コード例 #3
0
ファイル: PathFinder.cpp プロジェクト: morno/blizzlikecore
void PathInfo::BuildPointPath(const float *startPoint, const float *endPoint)
{
    float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE];
    uint32 pointCount = 0;
    dtStatus dtResult = DT_FAILURE;
    if (m_useStraightPath)
    {
        dtResult = m_navMeshQuery->findStraightPath(
                startPoint,         // start position
                endPoint,           // end position
                m_pathPolyRefs,     // current path
                m_polyLength,       // lenth of current path
                pathPoints,         // [out] path corner points
                NULL,               // [out] flags
                NULL,               // [out] shortened path
                (int*)&pointCount,
                m_pointPathLimit);   // maximum number of points/polygons to use
    }
    else
    {
        dtResult = findSmoothPath(
                startPoint,         // start position
                endPoint,           // end position
                m_pathPolyRefs,     // current path
                m_polyLength,       // length of current path
                pathPoints,         // [out] path corner points
                (int*)&pointCount,
                m_pointPathLimit);    // maximum number of points
    }

    if (pointCount < 2 || dtResult != DT_SUCCESS)
    {
        // only happens if pass bad data to findStraightPath or navmesh is broken
        // single point paths can be generated here
        // TODO : check the exact cases
        //DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ PathInfo::BuildPointPath FAILED! path sized %d returned\n", pointCount);
        BuildShortcut();
        m_type = PATHFIND_NOPATH;
        return;
    }

    m_pathPoints.resize(pointCount);
    for (uint32 i = 0; i < pointCount; ++i)
        m_pathPoints.set(i, PathNode(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]));

    // first point is always our current location - we need the next one
    setNextPosition(m_pathPoints[1]);
    setActualEndPosition(m_pathPoints[pointCount-1]);

    // force the given destination, if needed
    if (m_forceDestination &&
        (!(m_type & PATHFIND_NORMAL) || !inRange(getEndPosition(), getActualEndPosition(), 1.0f, 1.0f)))
    {
        // we may want to keep partial subpath
        if (dist3DSqr(getActualEndPosition(), getEndPosition()) < 
            0.3f * dist3DSqr(getStartPosition(), getEndPosition()))
        {
            setActualEndPosition(getEndPosition());
            m_pathPoints.set(m_pathPoints.size()-1, getEndPosition());
        }
        else
        {
            setActualEndPosition(getEndPosition());
            BuildShortcut();
        }

        m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
    }

    //DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ PathInfo::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength);
}
コード例 #4
0
ファイル: j1Pathfinding.cpp プロジェクト: N4bi/Dev
// ----------------------------------------------------------------------------------
// Actual A* algorithm: return number of steps in the creation of the path or -1 ----
// ----------------------------------------------------------------------------------
int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination)
{
	if (IsWalkable(origin) && IsWalkable(destination))
	{
		// TODO 2: Create three lists: open, close ,adjacent

		PathList open;
		PathList closed;
		PathList adjacent;

		// Add the origin tile to open
		open.list.add(PathNode(0, 0, origin, NULL));

		// Iterate while we have tile in the open list
		do
		{
			// TODO 3: Move the lowest score cell from open list to the closed list
			p2List_item<PathNode>* lowest_score = open.GetNodeLowestScore();
			p2List_item<PathNode>* node = closed.list.add(lowest_score->data);
			// delete de lowest score from the open list
			open.list.del(lowest_score);

			// TODO 4: If we just added the destination, we are done!

			if (node->data.pos == destination)
			{
				//clean the path we used before
				last_path.Clear();

				// Backtrack to create the final path
				const PathNode* path_node = &node->data;

				while (path_node)
				{
					// Use the Pathnode::parent and Flip() the path when you are finish
					last_path.PushBack(path_node->pos);
					path_node = path_node->parent;
				}

				last_path.Flip();
				return last_path.Count();
			}
			// TODO 5: Fill a list of all adjancent nodes

			node->data.FindWalkableAdjacents(adjacent);

			p2List_item<PathNode>* adjacent_items = adjacent.list.start;

			// TODO 6: Iterate adjancent nodes:

			for (; adjacent_items; adjacent_items = adjacent_items->next)
			{
				// ignore nodes in the closed list

				if (closed.Find(adjacent_items->data.pos) != NULL)
				{
					continue;
				}

				p2List_item<PathNode>* adjacent_open = open.Find(adjacent_items->data.pos);

				// If it is NOT found, calculate its F and add it to the open list
				if (adjacent_open == NULL)
				{
					adjacent_items->data.CalculateF(destination);
					open.list.add(adjacent_items->data);
				}
				else
					// If it is already in the open list, check if it is a better path (compare G)
				{
					if (adjacent_open->data.g > adjacent_items->data.g)
					{

						// If it is a better path, Update the parent
						adjacent_open->data.parent = adjacent_items->data.parent;
						adjacent_open->data.CalculateF(destination);
					}
				}
			}


		} while (open.list.count()>0);

	}

	return -1;
}
コード例 #5
0
bool NGMainWnd::onnet_authsuccess(const NETAUTHEX &auth) {
	EnableMenuItem(this->hmenu, 1, MF_BYPOSITION | MF_ENABLED);
	EnableMenuItem(this->hmenu, 2, MF_BYPOSITION | MF_ENABLED);
	DrawMenuBar(this->hwnd);

	if (this->client->hasaccess(NGWINAMPUSER_ACCESS_READ)) {
		if (this->client->hasaccess(NGWINAMPUSER_ACCESS_WRITE)) {
			this->toolbox_select(TOOLBOX_ADMIN);
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_PL_ADD)) {
			} else {
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_PL_SET)) {
			} else {
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_PL_DEL)) {
			} else {
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_PL_CTRL)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_SHUFFLE), TRUE);
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_REPEAT), TRUE);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_REPEAT, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_SHUFFLE, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_CLEAR, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_REMOVE_DEAD, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_SORTBYNAME, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_SORTBYPATH, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_RANDOMIZE, MF_BYCOMMAND | MF_ENABLED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_REFRESH, MF_BYCOMMAND | MF_ENABLED);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_SHUFFLE), FALSE);
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_REPEAT), FALSE);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_REPEAT, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_SHUFFLE, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_CLEAR, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_REMOVE_DEAD, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_SORTBYNAME, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_SORTBYPATH, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_RANDOMIZE, MF_BYCOMMAND | MF_GRAYED);
				EnableMenuItem(GetSubMenu(this->hmenu, 2), IDM_REFRESH, MF_BYCOMMAND | MF_GRAYED);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_BACK)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_BACK), TRUE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_BACK, MF_BYCOMMAND | MF_ENABLED);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_BACK), FALSE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_BACK, MF_BYCOMMAND | MF_GRAYED);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_PLAY)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PLAY), TRUE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_PLAY, MF_BYCOMMAND | MF_ENABLED);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PLAY), FALSE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_PLAY, MF_BYCOMMAND | MF_GRAYED);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_PAUSE)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PAUSE), TRUE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_PAUSE, MF_BYCOMMAND | MF_ENABLED);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PAUSE), FALSE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_PAUSE, MF_BYCOMMAND | MF_GRAYED);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_STOP)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_STOP), TRUE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_STOP, MF_BYCOMMAND | MF_ENABLED);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_STOP), FALSE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_STOP, MF_BYCOMMAND | MF_GRAYED);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_NEXT)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_NEXT), TRUE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_NEXT, MF_BYCOMMAND | MF_ENABLED);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_NEXT), FALSE);
				EnableMenuItem(GetSubMenu(this->hmenu, 1), IDM_NEXT, MF_BYCOMMAND | MF_GRAYED);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_VOLUME)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_VOLUME), TRUE);
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_VOLUME_VALUE), TRUE);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_VOLUME), FALSE);
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_VOLUME_VALUE), FALSE);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_PAN)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PAN), TRUE);
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PAN_VALUE), TRUE);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PAN), FALSE);
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_PAN_VALUE), FALSE);
			}
			if (this->client->hasaccess(NGWINAMPUSER_ACCESS_SN_POS)) {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_SONG_PROGRESS), TRUE);
			} else {
				EnableWindow(GetDlgItem(this->htoolboxwnd[this->curtoolbox], IDC_SONG_PROGRESS), FALSE);
			}
		} else {
			this->toolbox_select(TOOLBOX_USER);
		}
		if (this->client->hasaccess(NGWINAMPUSER_ACCESS_ADMIN)) {
		} else {
		}

		// setup playlist
		if (!this->client->request_pl_getnames()) {
			return false;
		}
		if (!this->client->request_pl_getfiles()) {
			return false;
		}

		// setup initial values
		if (!this->client->request_snapshot(NGWINAMP_SNAPSHOT_REFRESH)) {
			return false;
		}

		// setup share tree
		TVINSERTSTRUCT tvi;

		memset(&tvi, 0, sizeof(TVINSERTSTRUCT));
		tvi.hParent = TVI_ROOT;
		tvi.hInsertAfter = TVI_ROOT;
		tvi.itemex.mask = TVIF_CHILDREN | TVIF_IMAGE | TVIF_TEXT;
		tvi.itemex.cChildren = 1;
		tvi.itemex.pszText = NGWINAMP_BROWSER_ROOT;
		tvi.itemex.iImage = ICON_MAIN;
		this->browsenodes.push_back(PathNode(NULL, TreeView_InsertItem(this->hbrowsewnd, &tvi), "/", 0));
		if (!this->client->request_bw_getdirectories("/")) {
			return false;
		}
		if (!this->client->request_bw_getfiles("/")) {
			return false;
		}
	}
	return true;
}
コード例 #6
0
// ----------------------------------------------------------------------------------
// Actual A* algorithm: return number of steps in the creation of the path or -1 ----
// ----------------------------------------------------------------------------------
int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination)
{
	int ret = -1;
	int iterations = 0;

	if(IsWalkable(origin) && IsWalkable(destination))
	{
		PathList open;
		PathList closed;
		PathList adjacent;

		// Start pushing the origin in the open list
		open.list.add(PathNode(0, 0, origin, NULL));

		// Iterate while we have open destinations to visit
		do
		{
			// Move the lowest score cell from open list to the closed list
			p2List_item<PathNode>* lowest = open.GetNodeLowestScore();
			p2List_item<PathNode>* node = closed.list.add(lowest->data);
			open.list.del(lowest);

			// If destination was added, we are done!
			if(node->data.pos == destination)
			{
				last_path.Clear();
				// Backtrack to create the final path
				const PathNode* path_node = &node->data;

				while(path_node)
				{
					last_path.PushBack(path_node->pos);
					path_node = path_node->parent;
				}

				last_path.Flip();
				ret = last_path.Count();
				LOG("Created path of %d steps in %d iterations", ret, iterations);
				break;
			}

			// Fill a list with all adjacent nodes
			adjacent.list.clear();
			node->data.FindWalkableAdjacents(adjacent);

			p2List_item<PathNode>* item = adjacent.list.start;
			for(; item; item = item->next)
			{
				if(closed.Find(item->data.pos) != NULL)
					continue;

				p2List_item<PathNode>* adjacent_in_open = open.Find(item->data.pos);
				if(adjacent_in_open == NULL)
				{
					item->data.CalculateF(destination);
					open.list.add(item->data);
				}
				else
				{
					if(adjacent_in_open->data.g > item->data.g + 1)
					{
						adjacent_in_open->data.parent = item->data.parent;
						adjacent_in_open->data.CalculateF(destination);
					}
				}
			}

			++iterations;
		} while(open.list.count() > 0);
	}
	return ret;
}