示例#1
0
void NPC::TaskBase(void)
{
	if (m_goalWaypointAPI != -1)
	{
		if (m_goalWaypointAPI != m_goalWaypoint)
		{
			DeleteSearchNodes();
			m_goalWaypoint = m_goalWaypointAPI;
		}
	}

	if (DoWaypointNav())
	{
		m_goalWaypoint = -1;

		if (m_goalWaypointAPI != -1 && m_goalWaypointAPI == m_currentWaypointIndex)
			m_goalWaypointAPI = -1;
	}

	if (!GoalIsValid())
	{
		if (m_goalWaypoint == -1)
			m_goalWaypoint = RANDOM_LONG(0, g_numWaypoints - 1);

		FindWaypoint();

		DeleteSearchNodes();
		FindShortestPath(m_currentWaypointIndex, m_goalWaypoint);
	}
}
示例#2
0
void NPC::SetMoveTarget(edict_t *entity)
{
	if (FNullEnt(entity) || !IsAlive(entity))
	{
		m_moveTargetEntity = null;
		m_task &= ~TASK_MOVETOTARGET;
		m_enemyUpdateTime = -1.0f;
		return;
	}

	if (!FNullEnt (m_enemy) || m_moveTargetEntity != entity)
	{
		LoadEntityWaypointPoint(entity);
		LoadEntityWaypointPoint(GetEntity(), entity);
		m_currentWaypointIndex = -1;

		// Pro P.45 - Move Target improve
		FindWaypoint();
	}
	
	SetEnemy(null);

	m_moveTargetEntity = entity;
	m_task |= TASK_MOVETOTARGET;
	m_enemyUpdateTime = gpGlobals->time + 0.3f;
}
示例#3
0
void NPC::HeadTowardWaypoint(void)
{
	FindWaypoint();

	if (m_navNode == null)
		return;

	m_jumpAction = false;

	if (m_navNode->next != null)
	{
		for (int j = 0; j < Const_MaxPathIndex; j++)
		{
			if (g_waypoint->g_wpConnectionIndex[m_navNode->index][j] != m_navNode->next->index)
				continue;

			if (g_waypoint->g_wpConnectionFlags[m_navNode->index][j] & PATHFLAG_JUMP)
			{
				m_jumpAction = true;
				break;
			}
		}
	}

	m_oldNavIndex = m_navNode->index;
	m_navNode = m_navNode->next;
	if (m_navNode != null)
		m_currentWaypointIndex = m_navNode->index;

	SetWaypointOrigin();
	m_navTime = gpGlobals->time + 5.0f;
}
示例#4
0
bool NPC::DoWaypointNav (void)
{
	if (m_currentWaypointIndex < 0 || m_currentWaypointIndex >= g_numWaypoints)
		FindWaypoint();

	float waypointDistance = GetDistance(pev->origin, m_waypointOrigin);
	float desiredDistance = g_waypoint->g_waypointPointRadius[m_currentWaypointIndex];

	if (desiredDistance < 16.0f && waypointDistance < 30.0f)
	{
		Vector nextFrameOrigin = pev->origin + (pev->velocity * m_frameInterval);

		if (GetDistance(nextFrameOrigin, m_waypointOrigin) >= waypointDistance)
			desiredDistance = waypointDistance + 1.0f;
	}
	
	if (waypointDistance < desiredDistance)
	{
		if (m_goalWaypoint == m_currentWaypointIndex)
			return true;
		else if (m_navNode == null)
			return false;

		HeadTowardWaypoint();
		return false;
	}

	if (GetDistance(m_waypointOrigin, pev->origin) <= 2.0f)
		HeadTowardWaypoint();

	return false;
}
static void
SetAirfieldDetails(Waypoints &way_points, const TCHAR *name,
                   const tstring &Details,
                   const std::vector<tstring> &files_external,
                   const std::vector<tstring> &files_embed)
{
  auto wp = FindWaypoint(way_points, name);
  if (wp == nullptr)
    return;

  // TODO: eliminate this const_cast hack
  Waypoint &new_wp = const_cast<Waypoint &>(*wp);
  new_wp.details = Details.c_str();
  new_wp.files_embed.assign(files_embed.begin(), files_embed.end());
#ifdef HAVE_RUN_FILE
  new_wp.files_external.assign(files_external.begin(), files_external.end());
#endif
}
示例#6
0
static void
SetAirfieldDetails(Waypoints &way_points, const TCHAR *name,
                   const tstring &Details,
                   const std::vector<tstring> &files_external,
                   const std::vector<tstring> &files_embed)
{
  const Waypoint *wp = FindWaypoint(way_points, name);
  if (wp == NULL)
    return;

  Waypoint new_wp(*wp);
  new_wp.details = Details.c_str();
  new_wp.files_embed.assign(files_embed.begin(), files_embed.end());
#ifdef ANDROID
  new_wp.files_external.assign(files_external.begin(), files_external.end());
#endif
  way_points.Replace(*wp, new_wp);
  way_points.Optimise();
}
示例#7
0
void NPC::NPCAi(void)
{
	m_frameInterval = gpGlobals->time - m_lastThinkTime;
	m_lastThinkTime = gpGlobals->time;

	m_nextThinkTime = gpGlobals->time + 0.1f;

	g_npcAS = ASC_IDLE;
	m_moveSpeed = 0.0f;
	m_destOrigin = nullvec;
		
	FindWaypoint();

	FindEnemy();
	if (m_task & TASK_ENEMY)
		TaskEnemy();
	else if (m_task & TASK_MOVETOTARGET)
		TaskMoveTarget();
	else
		TaskBase();

	if (m_destOrigin == nullvec && m_currentWaypointIndex != -1)
	{
		m_destOrigin = m_waypointOrigin;
		m_lookAt = m_destOrigin;
		m_moveSpeed = pev->maxspeed;
	}

	if (m_iDamage)
	{
		m_changeActionTime = -1.0f;
		g_npcAS |= ASC_DAMAGE;
		m_iDamage = false;
	}

	FacePosition();
	MoveAction();

	ChangeAnim();
	pev->nextthink = m_nextThinkTime;
}
示例#8
0
bool psPathNetwork::Load(iEngine *engine, iDataConnection *db,psWorld * world)
{
    // First initialize pointers to some importent classes
    this->engine = engine;
    this->db = db;
    this->world = world;
    

    Result rs(db->Select("select wp.*,s.name as sector from sc_waypoints wp, sectors s where wp.loc_sector_id = s.id"));

    if (!rs.IsValid())
    {
        Error2("Could not load waypoints from db: %s",db->GetLastError() );
        return false;
    }
    for (int i=0; i<(int)rs.Count(); i++)
    {
        Waypoint *wp = new Waypoint();

        if (wp->Load(rs[i],engine))
        {
            Result rs2(db->Select("select id,alias,rotation_angle from sc_waypoint_aliases where wp_id=%d",wp->GetID()));
            for (int j=0; j<(int)rs2.Count(); j++)
            {
                wp->AddAlias(rs2[j].GetInt(0),rs2[j][1],rs2[j].GetFloat(2)*PI/180.0);
            }

            waypoints.Push(wp);

            // Push in groups
            if (strcmp(wp->GetGroup(),"")!=0)
            {
                AddWaypointToGroup(wp->GetGroup(),wp);
            }
            
        }
        else
        {
            Error2("Could not load waypoint: %s",db->GetLastError() );            
            delete wp;
            return false;
        }
        
    }

    Result rs1(db->Select("select * from sc_waypoint_links"));

    if (!rs1.IsValid())
    {
        Error2("Could not load waypoint links from db: %s",db->GetLastError() );
        return false;
    }
    for (int i=0; i<(int)rs1.Count(); i++)
    {
        Waypoint * wp1 = FindWaypoint(rs1[i].GetInt("wp1"));
        Waypoint * wp2 = FindWaypoint(rs1[i].GetInt("wp2"));
        if(!wp1 || !wp2)
        {
        	if(!wp1)
        	    Error2("Could not find waypoint wp1 link with id %d",rs1[i].GetInt("wp1") );
        	if(!wp2)
        	    Error2("Could not find waypoint wp2 link with id %d",rs1[i].GetInt("wp2") );
        	return false;
        }
        psString flagStr(rs1[i]["flags"]);

        int pathId = rs1[i].GetInt("id");
        
        csString pathType = rs1[i]["type"];
        
        psPath * path;
        if (strcasecmp(pathType,"linear") == 0)
        {
            path = new psLinearPath(pathId,rs1[i]["name"],flagStr);
        }
        else
        {
            path = new psLinearPath(pathId,rs1[i]["name"],flagStr); // For now
        }

        path->SetStart(wp1);
        if (!path->Load(db,engine))
        {
            Error1("Failed to load path");
            return false;
        }
        path->SetEnd(wp2);
        paths.Push(path);

        float dist = path->GetLength(world,engine);
                                    
        wp1->AddLink(path,wp2,psPath::FORWARD,dist);
        if (!path->oneWay)
        {
            wp2->AddLink(path,wp1,psPath::REVERSE,dist); // bi-directional link is implied
        }
    }
    
    
    return true;
}
示例#9
0
void NPC::FindEnemy(void)
{
	if (m_findEnemyMode == -1)
	{
		SetEnemy(null);
		SetMoveTarget(null);
		return;
	}

	int team = GetTeam(GetEntity());

	if (m_enemyAPI != null && (FNullEnt(m_enemyAPI) || !IsAlive(m_enemyAPI) || GetTeam(m_enemyAPI) == team))
		m_enemyAPI = null;

	if (!FNullEnt(m_enemy))
	{
		if (!IsAlive(m_enemy) || GetTeam(m_enemy) == team)
		{
			SetEnemy(null);

			LoadEntityWaypointPoint(GetEntity());
			m_currentWaypointIndex = -1;
			FindWaypoint();
		}
	}

	if (!FNullEnt(m_moveTargetEntity))
	{
		if (!IsAlive(m_moveTargetEntity) || GetTeam(m_moveTargetEntity) == team)
			SetMoveTarget(null);
	}

	edict_t *targetEntity = null;
	float enemy_distance = 9999.9f;

	if (!FNullEnt(m_enemy))
		targetEntity = m_enemy;
	else if (!FNullEnt(m_moveTargetEntity))
		targetEntity = m_moveTargetEntity;

	if (!FNullEnt(targetEntity))
	{
		if (m_enemyUpdateTime > gpGlobals->time)
			return;

		enemy_distance = GetEntityDistance(targetEntity);
	}

	int i, allEnemy = 0;
	edict_t *entity = null;

	if (FNullEnt(m_enemyAPI))
	{
		for (i = 0; i < checkEnemyNum; i++)
		{
			m_allEnemyId[i] = -1;
			m_allEnemyDistance[i] = 9999.9f;

			m_enemyEntityId[i] = -1;
			m_enemyEntityDistance[i] = 9999.9f;
		}

		for (i = 0; i < gpGlobals->maxClients; i++)
		{
			entity = INDEXENT(i + 1);
			if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team)
				continue;

			m_allEnemyId[allEnemy] = i + 1;
			m_allEnemyDistance[allEnemy] = GetEntityDistance(entity);
			allEnemy++;
		}

		for (i = 0; i < MAX_NPC; i++)
		{
			NPC *npc = g_npcManager->IsSwNPCForNum(i);
			if (npc == null)
				continue;

			entity = npc->GetEntity();
			if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team)
				continue;

			if (entity->v.effects & EF_NODRAW || entity->v.takedamage == DAMAGE_NO)
				continue;

			m_allEnemyId[allEnemy] = npc->GetIndex();
			m_allEnemyDistance[allEnemy] = GetEntityDistance(entity);
			allEnemy++;
		}

		for (i = 0; i < allEnemy; i++)
		{
			for (int y = 0; y < checkEnemyNum; y++)
			{
				if (m_allEnemyDistance[i] >= m_enemyEntityDistance[y])
					continue;

				for (int z = allEnemy - 1; z >= y; z--)
				{
					if (z == allEnemy - 1 || m_enemyEntityId[z] == -1)
						continue;

					m_enemyEntityId[z + 1] = m_enemyEntityId[z];
					m_enemyEntityDistance[z + 1] = m_enemyEntityDistance[z];
				}

				m_enemyEntityId[y] = m_allEnemyId[i];
				m_enemyEntityDistance[y] = m_allEnemyDistance[i];

				break;
			}
		}

		for (i = 0; i < checkEnemyNum; i++)
		{
			if (m_enemyEntityId[i] == -1)
				continue;

			entity = INDEXENT(m_enemyEntityId[i]);
			if (IsEnemyViewable(entity))
			{
				enemy_distance = m_enemyEntityDistance[i];
				targetEntity = entity;

				break;
			}
		}
	}
	else
	{
		targetEntity = m_enemyAPI;
		enemy_distance = GetEntityDistance(m_enemyAPI);
	}

	if (!FNullEnt(m_moveTargetEntity) && m_moveTargetEntity != targetEntity)
	{
		if (m_currentWaypointIndex != g_waypoint->GetEntityWpIndex(targetEntity))
		{
			float distance = GetEntityDistance(m_moveTargetEntity);
			if (distance <= enemy_distance + 400.0f)
			{
				enemy_distance = distance;
				targetEntity = null;
			}
		}
	}

	if (!FNullEnt(targetEntity))
	{
		if (!IsEnemyViewable(targetEntity))
		{
			if (targetEntity == m_enemyAPI)
			{
				SetMoveTarget(targetEntity);
				return;
			}

			targetEntity = null;
		}
	}

	if (!FNullEnt(m_enemy) && FNullEnt (targetEntity))
	{
		SetMoveTarget(m_enemy);
		return;
	}

	if (!FNullEnt(targetEntity))
	{
		if (m_attackDistance <= 300.0f)
		{
			bool moveTarget = true;
			int srcIndex = g_waypoint->GetEntityWpIndex(GetEntity());
			int destIndex = g_waypoint->GetEntityWpIndex(targetEntity);

			enemy_distance = GetDistance(pev->origin, GetEntityOrigin (targetEntity));

			if (srcIndex == destIndex || m_currentWaypointIndex == destIndex)
				moveTarget = false;
			else if (enemy_distance <= m_attackDistance)
				moveTarget = false;
			else if (m_attackDistance <= 120.0f)
			{
				if (targetEntity == m_moveTargetEntity && &m_navNode[0] != null)
				{
					if (m_navNode->index == destIndex)
						moveTarget = false;
				}
				else
				{
					int movePoint = 0;
					while (srcIndex != destIndex && movePoint < 99 && srcIndex >= 0 && destIndex >= 0)
					{
						srcIndex = *(g_waypoint->m_pathMatrix + (srcIndex * g_numWaypoints) + destIndex);
						if (srcIndex < 0)
							continue;

						movePoint++;
					}

					if ((enemy_distance <= 120.0f && movePoint <= 2) ||
						(targetEntity == m_moveTargetEntity && movePoint <= 1))
						moveTarget = false;
				}
			}

			if (!moveTarget)
			{
				SetEnemy(targetEntity);

				return;
			}

			SetMoveTarget(targetEntity);
		}
		else
			SetEnemy(targetEntity);
	}
}