View Single Post
Re: Autowaypointing...
Old
  (#5)
Cheeseh
[rcbot]
 
Cheeseh's Avatar
 
Status: Offline
Posts: 361
Join Date: Dec 2003
Location: China
Default Re: Autowaypointing... - 09-09-2008

I put a rather complex auto waypoint generation into my RCBot that uses humans to generate waypoints automatically for use with HPB Bot type waypoints.

What I usually do is keep track of 5 last positions a player has been in (seperated by a little time) and whenever the current point is not visible fromn the last placed waypoint, a new waypoint is placed on the nearest visible point. This is for corner waypointing. There is also the distance taken into consideration, i.e. whether a waypoint already exists at the location wher you want to make a new waypoint, you don't want to make new waypoints in the sample place all the time.

There are also other special cases such as ladders (which I tried to autowaypoint) and also jumping. for example, when jumping a JUMP waypoint is placed if none are around and then a new waypoint is generated when the player hits the ground, and a path is automatically formed from the jump waypoint to the ground waypoint.

I have all the code here if any one can understand it!

Code:
	if ( IsAutoWaypointOn() )
	{
		if ( !m_bSetUpAutoWaypoint || !EntityIsAlive(m_pPlayer) )
		{
			int i;
			int start = 0;

			if ( EntityIsAlive(m_pPlayer) )
				start = 1; // grab one location


			m_fLastAutoWaypointCheckTime = gpGlobals->time + gBotGlobals.m_fAutoWaypointCheckTime;

			if ( EntityIsAlive(m_pPlayer) )
				m_vLastAutoWaypointCheckPos[0].SetVector(m_pPlayer->v.origin);

			for ( i = start; i < MAX_STORED_AUTOWAYPOINT; i++ )
			{
				m_vLastAutoWaypointCheckPos[i].UnSetPoint();
			}

			m_vLastAutoWaypointPlacePos = m_pPlayer->v.origin;
			m_bSetUpAutoWaypoint = TRUE;
			m_fCanPlaceJump = 0;
			m_iLastButtons = 0;

			m_iLastJumpWaypointIndex = -1;
			m_iLastLadderWaypointIndex = -1;
			m_iLastMoveType = 0;
			m_fCanPlaceLadder = 0;
			m_iJoinLadderWaypointIndex = -1;
		}
		else
		{
			entvars_t *pev = &m_pPlayer->v;
			Vector vPlayerOrigin = pev->origin;

			// ****************************************************
			// Jump waypoint
			//
			// wait until checkJump is not -1 (meaning that bot is in the air)
			// set checkJump to time+0.5 after landing 
			// 
			// ****************************************************

			if ( (pev->waterlevel < 3) && (m_fCanPlaceJump < gpGlobals->time) )
			{	
				BOOL bStunt = gBotGlobals.IsMod(MOD_TS)&&(m_iLastButtons & IN_ALT1);
				Vector v_floor;

				if ( (m_fCanPlaceJump != -1) && (bStunt||(m_iLastButtons & IN_JUMP)) && !(pev->flags & FL_ONGROUND) )
				{
					int iNearestWpt = WaypointLocations.NearestWaypoint(vPlayerOrigin, 80.0, -1, TRUE, FALSE, FALSE, NULL);

					m_iLastJumpWaypointIndex = -1;
					
					if ( iNearestWpt == -1 )
					{
						if ( bStunt )
						{
							m_iLastJumpWaypointIndex = WaypointAddOrigin(vPlayerOrigin,W_FL_STUNT,m_pPlayer,m_bWaypointOn,m_bWaypointOn);

							if ( (m_iLastJumpWaypointIndex != -1) && UTIL_CanStand(waypoints[m_iLastJumpWaypointIndex].origin,&v_floor) )
							{
								waypoints[m_iLastJumpWaypointIndex].flags &= ~W_FL_CROUCH;
								waypoints[m_iLastJumpWaypointIndex].origin = v_floor+Vector(0,0,36);
							}
						}
						else
							m_iLastJumpWaypointIndex = WaypointAddOrigin(vPlayerOrigin,W_FL_JUMP,m_pPlayer,m_bWaypointOn,m_bWaypointOn);
					}
					else
						m_iLastJumpWaypointIndex = iNearestWpt; // can still update a current waypoint for land position
					
					m_vLastAutoWaypointPlacePos = vPlayerOrigin;

					m_fCanPlaceJump = -1;

					if ( bStunt )
						m_iJumpType = JUMP_TYPE_STUNT;
					else
						m_iJumpType = JUMP_TYPE_JUMP;
				}
				// ****************************************************
				// Join jump waypoint to the landed waypoint
				// ****************************************************
				else if ( (m_fCanPlaceJump == -1) && (pev->flags & FL_ONGROUND) )
				{
					if ( m_iLastJumpWaypointIndex != -1 )
					{
						int iNearestWpt = WaypointLocations.NearestWaypoint(vPlayerOrigin, 80.0, -1, TRUE, FALSE, FALSE, NULL);
						
						if ( iNearestWpt == -1 )
						{
							int iNewWpt = WaypointAddOrigin(vPlayerOrigin,0,m_pPlayer,m_bWaypointOn,m_bWaypointOn);

							if ( iNewWpt != -1 )
							{
								if ( BotNavigate_FindPathFromTo(m_iLastJumpWaypointIndex,iNewWpt,-1) == NULL )
								{
									WaypointAddPath(m_iLastJumpWaypointIndex,iNewWpt);																	
								}

								if ( m_iJumpType == JUMP_TYPE_STUNT )							
									waypoints[m_iLastJumpWaypointIndex].flags |= W_FL_STUNT;																
								else
									waypoints[m_iLastJumpWaypointIndex].flags |= W_FL_JUMP;
								
								if ( UTIL_CanStand(waypoints[iNewWpt].origin,&v_floor) )
								{
									waypoints[iNewWpt].flags &= ~W_FL_CROUCH;
									waypoints[iNewWpt].origin = v_floor+Vector(0,0,36);
								}
							}
						}
						else if ( iNearestWpt != m_iLastJumpWaypointIndex )
						{
							if ( BotNavigate_FindPathFromTo(m_iLastJumpWaypointIndex,iNearestWpt,-1) == NULL )
							{
								WaypointAddPath(m_iLastJumpWaypointIndex,iNearestWpt);
								
								if ( m_iJumpType == JUMP_TYPE_STUNT )
									waypoints[m_iLastJumpWaypointIndex].flags |= W_FL_STUNT;								
								else
									waypoints[m_iLastJumpWaypointIndex].flags |= W_FL_JUMP;								
							}
						}
					}

					m_iLastJumpWaypointIndex = -1;

					// wait a sec after player lands before checking jump again
					m_fCanPlaceJump = gpGlobals->time + 0.5;
				}				
			}

			BOOL bCheckDistance = (pev->movetype != MOVETYPE_FLY) && (m_fCanPlaceLadder == 0); // always check distance unless ladder climbing

			// ****************************************************
			// Ladder waypoint
			// make the frist waypoint (e.g. bottom waypoint)
			// ****************************************************
			if ( (pev->movetype == MOVETYPE_FLY) && !(m_iLastMoveType == MOVETYPE_FLY) )
			{
				// went ON to a ladder

				int iNearestWpt = WaypointLocations.NearestWaypoint(vPlayerOrigin, 80.0, -1, TRUE, FALSE, FALSE, NULL);

				m_iLastLadderWaypointIndex = -1;
					
				if ( iNearestWpt == -1 )
					m_iLastLadderWaypointIndex = WaypointAddOrigin(vPlayerOrigin,W_FL_LADDER,m_pPlayer,m_bWaypointOn,m_bWaypointOn);
				else
				{
					m_iLastLadderWaypointIndex = iNearestWpt; // can still update a current waypoint for land position

					waypoints[m_iLastLadderWaypointIndex].flags |= W_FL_LADDER; // update flags
				}
					
				m_vLastAutoWaypointPlacePos = vPlayerOrigin;

				bCheckDistance = FALSE;

				m_fCanPlaceLadder = 0;

				// need to unset every check point when going on ladder first time
				for ( int i = 0; i < MAX_STORED_AUTOWAYPOINT; i ++ )
				{
						m_vLastAutoWaypointCheckPos[i].UnSetPoint();					
				}
			}
			else if ( !(pev->movetype == MOVETYPE_FLY) && (m_iLastMoveType == MOVETYPE_FLY) )
			{
				// went OFF a ladder
				m_fCanPlaceLadder = gpGlobals->time + 0.2;
			}
			
			// ****************************************************
			// If we have walked off a ladder for a small amount of time
			// Make the top/bottom ladder waypoint
			// ****************************************************
			if ( m_fCanPlaceLadder && (m_fCanPlaceLadder < gpGlobals->time ) )
			{
				if ( m_iLastLadderWaypointIndex != -1 )
					// place a ladder waypoint before jumping off
				{
					int iNearestWpt = WaypointLocations.NearestWaypoint(vPlayerOrigin, 80.0, -1, TRUE, FALSE, FALSE, NULL);
					
					if ( iNearestWpt == -1 )
					{
						int iNewWpt = WaypointAddOrigin(vPlayerOrigin,W_FL_LADDER,m_pPlayer,m_bWaypointOn,m_bWaypointOn);
						
						if ( iNewWpt != -1 )
						{
							m_iJoinLadderWaypointIndex = iNewWpt;

							if ( BotNavigate_FindPathFromTo(m_iLastLadderWaypointIndex,iNewWpt,-1) == NULL )
								WaypointAddPath(m_iLastLadderWaypointIndex,iNewWpt);
						}
					}
					else if ( iNearestWpt != m_iLastLadderWaypointIndex )
					{
						m_iJoinLadderWaypointIndex = iNearestWpt;

						if ( BotNavigate_FindPathFromTo(m_iLastLadderWaypointIndex,iNearestWpt,-1) == NULL )
							WaypointAddPath(m_iLastLadderWaypointIndex,iNearestWpt);
					}				
				}
				
				m_iLastLadderWaypointIndex = -1;
				
				bCheckDistance = FALSE;

				m_fCanPlaceLadder = 0;
			}
			
			// ****************************************************
			// Join top ladder waypoint to a ground waypoint
			// ****************************************************
			if ( (m_iJoinLadderWaypointIndex != -1) && (pev->flags & FL_ONGROUND) && (pev->movetype == MOVETYPE_WALK) )
			{
				int iNearestWpt = WaypointLocations.NearestWaypoint(vPlayerOrigin, 40.0, m_iJoinLadderWaypointIndex, TRUE, FALSE, FALSE, NULL);
				
				if ( iNearestWpt == -1 )
				{
					int iNewWpt = WaypointAddOrigin(vPlayerOrigin,0,m_pPlayer,m_bWaypointOn,m_bWaypointOn);
					
					if ( iNewWpt != -1 )
					{
						if ( BotNavigate_FindPathFromTo(m_iJoinLadderWaypointIndex,iNewWpt,-1) == NULL )
							WaypointAddPath(m_iJoinLadderWaypointIndex,iNewWpt);
					}
				}
				else if ( iNearestWpt != m_iJoinLadderWaypointIndex )
				{
					if ( BotNavigate_FindPathFromTo(m_iJoinLadderWaypointIndex,iNearestWpt,-1) == NULL )
						WaypointAddPath(m_iJoinLadderWaypointIndex,iNearestWpt);
				}

				m_iJoinLadderWaypointIndex = -1;
			}

			m_iLastButtons = pev->button;
			m_iLastMoveType = pev->movetype;

			if ( m_fLastAutoWaypointCheckTime < gpGlobals->time )
			{
				// ****************************************
				// Corner - Check
				// ****************************************
				//
				// place a "Check - point" at player origin
				//

				CAutoWaypointCheck *vCurVector;				
				Vector vCheckOrigin;

				Vector vPlacePosition;
				int iFlags = 0;
				BOOL bPlace = FALSE;
				
				int i;
				int n;

				TraceResult tr;

				int numset = 0;
				int last = 0;

				for ( n = 0; n < MAX_STORED_AUTOWAYPOINT; n ++ )
				{
					if ( m_vLastAutoWaypointCheckPos[n].IsVectorSet() )
					{
						numset++;
					}
				}

				if ( numset == MAX_STORED_AUTOWAYPOINT )
				{
					// move check points down
					for ( n = 0; n < (MAX_STORED_AUTOWAYPOINT-1); n ++ )
					{
						m_vLastAutoWaypointCheckPos[n] = m_vLastAutoWaypointCheckPos[n+1];						
					}
					
					last = MAX_STORED_AUTOWAYPOINT-1;
				}
				else
				{					
					last = numset;
				}

				iFlags = 0;

				// sort out flags for this waypoint depending on player
				if ((pev->flags & FL_DUCKING) == FL_DUCKING)
				{
					iFlags |= W_FL_CROUCH;  // crouching waypoint
				}
				
				if (pev->movetype == MOVETYPE_FLY)
					iFlags |= W_FL_LADDER;  // waypoint on a ladder

				m_vLastAutoWaypointCheckPos[last].SetPoint(vPlayerOrigin,iFlags);
				
				if ( (m_iLastJumpWaypointIndex==-1) && bCheckDistance && ((vPlayerOrigin - m_vLastAutoWaypointPlacePos).Length() > 200) )
				{
					int iNearestWpt = WaypointLocations.NearestWaypoint(vPlayerOrigin, 150.0, -1, TRUE, FALSE, FALSE, NULL);
					
					if ( iNearestWpt == -1 )
						WaypointAddOrigin(vPlayerOrigin,0,m_pPlayer,m_bWaypointOn,m_bWaypointOn);
					
					// set regardless
					m_vLastAutoWaypointPlacePos = vPlayerOrigin;
				}

				// search for occluded check points from player
				for ( i = 0; i < MAX_STORED_AUTOWAYPOINT; i++ )
				{
					vCurVector = &m_vLastAutoWaypointCheckPos[i];

					if ( !vCurVector->IsVectorSet() )
						continue;

					vCheckOrigin = vCurVector->GetVector();

					UTIL_TraceLine(vPlayerOrigin,vCheckOrigin,ignore_monsters,ignore_glass,m_pPlayer,&tr);

					if ( m_bDebugAutoWaypoint )
					{
						WaypointDrawBeam(m_pPlayer,vCheckOrigin+Vector(0,0,16),vCheckOrigin-Vector(0,0,16),20,1,255,1,1,150,10);
						WaypointDrawBeam(m_pPlayer,vPlayerOrigin,vCheckOrigin,20,1,1,255,1,150,10);
					}
					
					if ( tr.flFraction < 1.0 )
					{
						if ( tr.pHit )
						{
							// on a lift/train moving "fast"
							if ( tr.pHit->v.velocity.Length() > 20.0 )
								continue;
						}
						// find next which is visible
						for ( n = i+1; n < MAX_STORED_AUTOWAYPOINT; n++ )
						{
							vCurVector = &m_vLastAutoWaypointCheckPos[n];
							
							if ( !vCurVector->IsVectorSet() )
								continue;
							
							vCheckOrigin = vCurVector->GetVector();
							
							UTIL_TraceLine(vPlayerOrigin,vCheckOrigin,ignore_monsters,ignore_glass,m_pPlayer,&tr);

							if ( m_bDebugAutoWaypoint )
								WaypointDrawBeam(m_pPlayer,vPlayerOrigin,vCheckOrigin,20,1,1,1,255,150,10);
							
							if ( tr.flFraction >= 1.0 )
							{
								int iNearestWpt = WaypointLocations.NearestWaypoint(vCheckOrigin, 100.0, -1, TRUE, FALSE, FALSE, NULL);
								
								if ( iNearestWpt == -1 )
								{
									bPlace = TRUE;		
									vPlacePosition = vCheckOrigin;
									iFlags = vCurVector->getFlags();
									
									break;
								}
								else
									continue;
							}
						}
						
					}
				}

				if ( bPlace )
				{
					int inewwpt = WaypointAddOrigin(vPlacePosition,iFlags,m_pPlayer,m_bWaypointOn,m_bWaypointOn,FALSE);
					Vector v_floor;

					m_vLastAutoWaypointPlacePos = vPlacePosition;

					if ( (m_iLastJumpWaypointIndex != -1) && UTIL_CanStand(waypoints[inewwpt].origin,&v_floor) )
					{
						waypoints[inewwpt].flags &= ~W_FL_CROUCH;
						//waypoints[inewwpt].origin = v_floor+Vector(0,0,36);
					}
					//clear from i

					int pos = n;
					int n = 0;

					for ( n = 0; pos < MAX_STORED_AUTOWAYPOINT; n ++ )
					{
						m_vLastAutoWaypointCheckPos[n] = m_vLastAutoWaypointCheckPos[pos];

						pos++;
					}

					for ( n = n; n < MAX_STORED_AUTOWAYPOINT; n ++ )
					{
						m_vLastAutoWaypointCheckPos[n].UnSetPoint();					
					}
				}

				m_fLastAutoWaypointCheckTime = gpGlobals->time + gBotGlobals.m_fAutoWaypointCheckTime;
			}
		}
bear in mind this autowaypointing is for natural-selection in particular

Last edited by Cheeseh; 10-09-2008 at 19:13..
  
Reply With Quote