Ejemplo n.º 1
0
bool CChar::CanSeeLOS( const CObjBaseTemplate *pObj, word wFlags, bool bCombatCheck ) const
{
	ADDTOCALLSTACK("CChar::CanSeeLOS");
	// WARNING: CanSeeLOS is an expensive function (lot of calculations but	most importantly it has to read the UO files, and file I/O is slow).

	if ( !CanSee(pObj) )
		return false;

	pObj = pObj->GetTopLevelObj();
	if ( !pObj )
		return false;

	if ( (m_pPlayer && (g_Cfg.m_iAdvancedLos & ADVANCEDLOS_PLAYER)) || (m_pNPC && (g_Cfg.m_iAdvancedLos & ADVANCEDLOS_NPC)) )
	{
		CPointMap pt = pObj->GetTopPoint();
		const CChar *pChar = dynamic_cast<const CChar*>(pObj);
		if ( pChar )
		{
			short iTotalZ = pt.m_z + pChar->GetHeightMount(true);
			pt.m_z = (char)minimum(iTotalZ, UO_SIZE_Z);
		}
		return CanSeeLOS_New(pt, nullptr, pObj->GetVisualRange(), wFlags, bCombatCheck);
	}
	else
		return CanSeeLOS(pObj->GetTopPoint(), nullptr, pObj->GetVisualRange(), wFlags, bCombatCheck);
}
Ejemplo n.º 2
0
bool ZActor::CanAttackMelee(ZObject* pTarget, ZSkillDesc *pSkillDesc)
{
	if (pSkillDesc == NULL)
	{
		float dist = Magnitude(pTarget->m_Position - m_Position);
		if (dist < m_pNPCInfo->fAttackRange) 
		{
			if (CanSee(pTarget)) return true;
		}
	}
	else
	{
		rvector Pos = GetPosition();
		rvector Dir = GetDirection();
		Dir.z=0; 
		Normalize(Dir);

		float fDist = Magnitude(Pos - pTarget->GetPosition());
		float fColMinRange = pSkillDesc->fEffectAreaMin * 100.0f;
		float fColMaxRange = pSkillDesc->fEffectArea * 100.0f;
		if ((fDist < fColMaxRange + pTarget->GetCollRadius()) && (fDist >= fColMinRange))
		{
			rvector vTargetDir = pTarget->GetPosition() - GetPosition();
			rvector vBodyDir = GetDirection();
			vBodyDir.z = vTargetDir.z = 0.0f;

			float angle = fabs(GetAngleOfVectors(vTargetDir, vBodyDir));
			if (angle <= pSkillDesc->fEffectAngle) return true;
		}
	}

	return false;
}
Ejemplo n.º 3
0
void CASW_Simple_Alien::WhatToDoNext(float delta)
{
	if (m_iState == ASW_SIMPLE_ALIEN_ATTACKING)
	{
		if (!GetEnemy() || !CanSee(GetEnemy()) || GetEnemy()->GetHealth() <= 0)
		{
			LostEnemy();	// clears our enemy and sets us back to idling
		}
		else
		{
			// head towards enemy
			SetMoveTarget(GetChaseDestination(GetEnemy()));

			PerformMovement(delta);				
		}

		SetNextThink( gpGlobals->curtime + 0.1f );
	}
	else if (m_iState == ASW_SIMPLE_ALIEN_IDLING)
	{
		// look for a new enemy?
		FindNewEnemy();
		
		if (GetEnemy())
			SetNextThink( gpGlobals->curtime + 0.1f );
		else
			SetNextThink( gpGlobals->curtime + 0.5f );
	}
	else if (m_iState == ASW_SIMPLE_ALIEN_DEAD)
	{
		// don't need to think again
	}

	// todo: if in moving to dest state, then move towards that dest, etc.
}
Ejemplo n.º 4
0
/** Check warnings on a specific object.
 * We check for ownership or hasprivs before allowing this.
 * \param player the enactor.
 * \param name name of object to check.
 */
void
do_wcheck(dbref player, const char *name)
{
    dbref thing;

    switch (thing = match_result(player, name, NOTYPE, MAT_EVERYTHING)) {
    case NOTHING:
        notify(player, T("I don't see that object."));
        return;
    case AMBIGUOUS:
        notify(player, T("I don't know which one you mean."));
        return;
    default:
        if (!(CanSee(player, thing) || (Owner(player) == Owner(thing)))) {
            notify(player, T("Permission denied."));
            return;
        }
        if (IsGarbage(thing)) {
            notify(player, T("Why would you want to be warned about garbage?"));
            return;
        }
        break;
    }

    check_topology_on(player, thing);
    notify(player, T("@wcheck complete."));
    return;
}
Ejemplo n.º 5
0
void CASW_Sentry_Top::FindEnemy()
{
	bool bFindNewEnemy = true;
	bool bHadEnemy = (m_hEnemy.IsValid() && m_hEnemy.Get());
	// if have an enemy and it is alive
	if (m_hEnemy.IsValid() && m_hEnemy.Get() && m_hEnemy->GetHealth() > 0 )
	{		
		// check for LOS to enemy
		if (CanSee(m_hEnemy))
			bFindNewEnemy = false;
		// reject if enemy is somehow invalid now
		CAI_BaseNPC *pNPC = dynamic_cast<CAI_BaseNPC *>(m_hEnemy.Get());
		if ( pNPC && !IsValidEnemy(pNPC) )
			bFindNewEnemy = true;
	}

	if (bFindNewEnemy)
	{
		if ( g_vecTargetDummies.Count() > 0 )
		{
			m_hEnemy = g_vecTargetDummies[0];
		}
		else
		{
			m_hEnemy = SelectOptimalEnemy();
		}
	}
	// acquired a new enemy
	if (!bHadEnemy && m_hEnemy.IsValid() && m_hEnemy.Get())
	{
		PlayTurnSound();
	}
}
Ejemplo n.º 6
0
CAI_BaseNPC * CASW_Sentry_Top::SelectOptimalEnemy()
{
	// search through all npcs, any that are in LOS and have health
	CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();

	for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )
	{
		if (ppAIs[i]->GetHealth() > 0 && CanSee(ppAIs[i]))
		{
			// don't shoot marines
			if ( !asw_sentry_friendly_target.GetBool() && (ppAIs[i]->Classify() == CLASS_ASW_MARINE || ppAIs[i]->Classify() == CLASS_ASW_COLONIST) )
				continue;

			if ( ppAIs[i]->Classify() == CLASS_SCANNER )
				continue;

			if ( !IsValidEnemy( ppAIs[i] ) )
				continue;

			return ppAIs[i];
			break;

		}
	}
	// todo: should evaluate valid targets and pick the best one?
	//   (didn't do this for ASv1 and it was fine...)

	return NULL;
}
Ejemplo n.º 7
0
void CASW_Simple_Alien::FindNewEnemy()
{
	float dist;
	CBaseEntity *pNearest = UTIL_ASW_NearestMarine(GetAbsOrigin(), dist);
	if (CanSee(pNearest))
	{
		SetEnemy(pNearest);
	}
}
Ejemplo n.º 8
0
	/** Build CUList for showing this join/part/kick */
	void BuildExcept(Membership* memb, CUList& excepts)
	{
		if (IsVisible(memb))
			return;

		const Channel::MemberMap& users = memb->chan->GetUsers();
		for (Channel::MemberMap::const_iterator i = users.begin(); i != users.end(); ++i)
		{
			if (IS_LOCAL(i->first) && !CanSee(i->first, memb))
				excepts.insert(i->first);
		}
	}
Ejemplo n.º 9
0
	/** Build CUList for showing this join/part/kick */
	void BuildExcept(Membership* memb, CUList& excepts)
	{
		if (IsVisible(memb))
			return;

		const UserMembList* users = memb->chan->GetUsers();
		for(UserMembCIter i = users->begin(); i != users->end(); i++)
		{
			if (IS_LOCAL(i->first) && !CanSee(i->first, memb))
				excepts.insert(i->first);
		}
	}
Ejemplo n.º 10
0
void CChar::NPC_PetConfirmCommand(bool bSuccess, CChar *pMaster)
{
	ADDTOCALLSTACK("CChar::NPC_PetConfirmCommand");
	// I take a command from my master

	if ( !m_pNPC || !g_Cfg.m_sSpeechPet.IsEmpty() || !CanSee(pMaster) )
		return;

	if ( NPC_CanSpeak() )
		Speak(bSuccess ? g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_SUCCESS) : g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_FAILURE));
	else
		SoundChar(bSuccess ? CRESND_IDLE : CRESND_NOTICE);
}
Ejemplo n.º 11
0
    //
    // Set visible cells in +- quadrant
    //
    void CompareGradPosNeg()
    {
      for (z = 0, z2 = 0; z2 < r2; z2 += 2 * z + 1, ++z)
      {
        for (x = 1, x2 = 1; x2 + z2 < r2; x2 += 2 * x + 1, ++x)
        {
          dx = z;
          dz = -x;

          if (maxGradMap[z][x]<=gradMapU[z][x])
          {
            CanSee(cellX + dx, cellZ + dz, dx, dz, mapLo, maskLo, teamBits, Map::LV_LO);
          }
        }
      }
    }
Ejemplo n.º 12
0
void CSynAoiDimObj::PostMsgToViewee(const void* pContext)
{
	CSynAoiDimObj* pObject;
	ViewObjSet_t::const_iterator iter = m_setObjInMyViewRect.begin();
	ViewObjSet_t::const_iterator iter_end = m_setObjInMyViewRect.end();
	while (iter != iter_end)
	{
		pObject = (*iter);
		if (CanSee(pObject))
		{
			pObject->OnMsgFromViewer(pContext);
		}
		++iter;
	}

	OnMsgToVieweeHandled(pContext);
}
Ejemplo n.º 13
0
void CSynAoiDimObj::PostMsgToSyncer(const void *pContext)
{
	CSynAoiDimObj* pObject;
	ViewObjSet_t::const_iterator iter = m_setObjInMyViewRect.begin();
	ViewObjSet_t::const_iterator iter_end = m_setObjInMyViewRect.end();
	while (iter != iter_end)
	{
		pObject = (*iter);
		if (CanSee(pObject))
		{
			CFPos OtPos = pObject->GetPosition();
			if(m_pDimScene->IsInSyncAoi(OtPos - m_Pos))
				pObject->OnMsgFromSyncee(pContext);
		}
		++iter;
	}

	OnMsgToSyncerHandled(pContext);
}
Ejemplo n.º 14
0
/*
Can we see s2 from s1 ?
*/
bool SquareLine::CanSee(Square s1, Square s2, Board *w)
{    
	s_cur=s1;
	s_goal=s2;
	p_lastipoint=vector2d::Invalid;
	board=w;
	sg.p0=board->GetCenterInPx(s1);
	sg.p1=board->GetCenterInPx(s2);

#if defined(_showdebugger_)
//	Debugger::GetInstance().Output("from (%d,%d) to (%d,%d)\n",s_cur.x,s_cur.y,s_goal.x,s_goal.y);
#endif //defined(_showdebugger_)

	bool t = CanSee();

#if defined(_showdebugger_)
//	Debugger::GetInstance().Output("\n");
#endif //defined(_showdebugger_)

	return t;
}
Ejemplo n.º 15
0
void CChar::NPC_OnPetCommand( bool fSuccess, CChar * pMaster )
{
	ADDTOCALLSTACK("CChar::NPC_OnPetCommand");
	if ( m_pPlayer )	// players don't respond
		return;

	if (  !g_Cfg.m_sSpeechPet.IsEmpty() )
		return;

	if ( !CanSee( pMaster ) )
		return;

	// i take a command from my master.
	if ( NPC_CanSpeak())
	{
		Speak( fSuccess? g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_SUCCESS ) : g_Cfg.GetDefaultMsg( DEFMSG_NPC_PET_FAILURE ) );
	}
	else
	{
		SoundChar( fSuccess? CRESND_RAND1 : CRESND_RAND2 );
	}
}
Ejemplo n.º 16
0
visibility_t NPC_CheckVisibility ( gentity_t *ent, int flags )
{
	// flags should never be 0
	if ( !flags )
	{
		return VIS_NOT;
	}

	// check PVS
	if ( flags & CHECK_PVS )
	{
		if ( !gi.inPVS ( ent->currentOrigin, NPC->currentOrigin ) )
		{
			return VIS_NOT;
		}
	}
	if ( !(flags & (CHECK_360|CHECK_FOV|CHECK_SHOOT)) )
	{
		return VIS_PVS;
	}

	// check within visrange
	if (flags & CHECK_VISRANGE)
	{
		if( !InVisrange ( ent ) )
		{
			return VIS_PVS;
		}
	}

	// check 360 degree visibility
	//Meaning has to be a direct line of site
	if ( flags & CHECK_360 )
	{
		if ( !CanSee ( ent ) )
		{
			return VIS_PVS;
		}
	}
	if ( !(flags & (CHECK_FOV|CHECK_SHOOT)) )
	{
		return VIS_360;
	}

	// check FOV
	if ( flags & CHECK_FOV )
	{
		if ( !InFOV ( ent, NPC, NPCInfo->stats.hfov, NPCInfo->stats.vfov) )
		{
			return VIS_360;
		}
	}

	if ( !(flags & CHECK_SHOOT) )
	{
		return VIS_FOV;
	}

	// check shootability
	if ( flags & CHECK_SHOOT )
	{
		if ( !CanShoot ( ent, NPC ) )
		{
			return VIS_FOV;
		}
	}

	return VIS_SHOOT;
}
Ejemplo n.º 17
0
void Coloring(Model& integ)
{

	//CalculateDistance(integ);
	CalculateDistance_AllVoxel(integ);

	cout << "CalculateNormal: " << endl;
	//
	CalculateNormal(integ);

	//
	vector<cv::Mat> UpSilhouette(ImageNum);
	ReadSilhouette(ImageNum, directory[1], model, pose[0], UpSilhouette);
	vector<cv::Mat> DownSilhouette(ImageNum);
	ReadSilhouette(ImageNum, directory[1], model, pose[1], DownSilhouette);
	vector<cv::Mat> UpImage(ImageNum);
	ReadColorImage(ImageNum, directory[0], model, pose[0], UpImage);
	vector<cv::Mat> DownImage(ImageNum);
	ReadColorImage(ImageNum, directory[0], model, pose[1], DownImage);

	cv::Point temp;
	int R, G, B;
	int step = UpImage[0].step;
	int width = UpSilhouette[0].cols;
	int height = UpSilhouette[0].rows;

	CColor tempColor(0.0, 0.0, 0.0);
	Color_hue tempColorH;
	vector<Color_hue> VoxColor;

	CVector3d Point_Image;
	short templum;
	//short thre(50);
	short thre(123);

	Color_hue tempBackColor;
	tempBackColor.r = integ.BackColor.r;
	tempBackColor.g = integ.BackColor.g;
	tempBackColor.b = integ.BackColor.b;
	tempBackColor.CalcHue();

	integ.SurfColors.reserve(integ.SurfNum);		//

	int ring1[][2] = { {0, 0},		{-1, -1},		{-1, 0},
					   {-1, 1},		{0, -1},		{0, 1},
					   {1, -1},		{1, 0},		    {1, 1}
	};

	//                                                                                   
	//                                     
	//                                                                                   
	integ.Voxel_colors = new CColor **[integ.num[0]];
	for (int i(0); i < integ.num[0]; i++) {
		integ.Voxel_colors[i] = new CColor *[integ.num[1]];
		for (int k(0); k < integ.num[1]; k++)
			integ.Voxel_colors[i][k] = new CColor[integ.num[2]];
	}

	cout << "\nCheck visable voxels which can be seen\n" << endl;

	for (int x = 1; x < integ.num[0] - 1; x++) {
		for (int y = 1; y < integ.num[1] - 1; y++) {
			for (int z = 1; z < integ.num[2] - 1; z++) {
				//
				if (integ.Voxels[x][y][z].surf) {
					//
					VoxColor.clear();
					for (int i = 0; i < ImageNum; i++)
					{
						CanSee(integ, x, y, z, CameraPosUp[i], "UP");					//true(UP)
						//UP
						if (integ.Flags[x][y][z].upCan)
						{
							integ.Voxels[x][y][z].line.push_back(CameraPosUp[i] - integ.Voxels[x][y][z].center);
							temp = integ.Voxels[x][y][z].CalcImageCoordofCenter(ART[i]);
							//�
							//
							for (int n = 0; n < 9; n++) {
								templum = (short)(UpSilhouette[i].data[width * (temp.y + ring1[n][1]) + temp.x + ring1[n][0]]);
								if (templum < thre)	
									continue;
								//opencv
								tempColorH.Clear();
								B = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3];
								G = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 1];
								R = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 2];
								tempColorH.b = B / 255.0;
								tempColorH.g = G / 255.0;
								tempColorH.r = R / 255.0;
								tempColorH.CalcHue();
								tempColorH.CalcLuminance();
								//if( fabs(tempBackColor.GetHue() - tempColorH.GetHue()) < HueGap_Thres )				//�w�i�F�̐F���ɋ߂��F�͎g�p���Ȃ�
								//	continue;
								//								//�V�}�E�}��p
								//if(tempColorH.luminance>0.5){
								//	tempColorH.Set(1.0,1.0,1.0);
								//}
								//else{
								//	tempColorH.Set(0.0,0.0,0.0);
								//}
								VoxColor.push_back(tempColorH);
							}
						}
						CanSee(integ, x, y, z, CameraPosDown[i], "DOWN");		//false(DOWN)
						//DOWN
						if (integ.Flags[x][y][z].downCan)
						{
							integ.Voxels[x][y][z].line.push_back(CameraPosDown[i] - integ.Voxels[x][y][z].center);
							temp = integ.Voxels[x][y][z].CalcImageCoordofCenter(ARTRTinv[i]);
							//�
							//
							for (int n = 0; n < 9; n++) {
								templum = (short)(DownSilhouette[i].data[width * (temp.y + ring1[n][1]) + temp.x + ring1[n][0]]);
								if (templum < thre)	//
									continue;
								//opencv�
								tempColorH.Clear();
								B = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3];
								G = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 1];
								R = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 2];
								tempColorH.b = B / 255.0;
								tempColorH.g = G / 255.0;
								tempColorH.r = R / 255.0;
								tempColorH.CalcHue();
								tempColorH.CalcLuminance();
								//if( fabs(tempBackColor.GetHue() - tempColorH.GetHue()) < HueGap_Thres )				
								//	continue;
								//								
								//if(tempColorH.luminance>0.5){
								//	tempColorH.Set(1.0,1.0,1.0);
								//}
								//else{
								//	tempColorH.Set(0.0,0.0,0.0);
								//}
								VoxColor.push_back(tempColorH);
							}
						}
					}

					if (!VoxColor.empty()) {
						tempColor = GetVoxelColor_hue_mode(VoxColor);
						//tempColor = GetVoxelColor_lumi_mode(VoxColor);			
						//cout<<tempColor.r <<" "<<tempColor.g<<" "<<tempColor.b<<endl;
						integ.Voxel_colors[x][y][z] = tempColor;
						integ.SurfColors.push_back(tempColor);
					}

					else {
						integ.Voxel_colors[x][y][z] = tempColor;
						integ.SurfColors.push_back(tempColor);   //0.0.0.0.0.0
					}
				}
			}
		}
	}

	//
	UpSilhouette.clear();
	UpSilhouette.shrink_to_fit();
	DownSilhouette.clear();
	DownSilhouette.shrink_to_fit();
	UpImage.clear();
	UpImage.shrink_to_fit();
	DownImage.clear();
	DownImage.shrink_to_fit();
}
Ejemplo n.º 18
0
    //
    // New and improved sweep
    //
    void Sweep(UnitObj *u)
    {
      ASSERT(sysInit);
      ASSERT(u);
      //ASSERT(u->GetTeam());
      ASSERT(u->OnMap());

      START(sweepTime);

      r = u->GetSeeingRange();
      unit = u;
      cellX = u->cellX;
      cellZ = u->cellZ;

      ASSERT(r < MAXR)

      // Get sight map and mask
      maskLo = u->sightMap->GetBitMask(Map::LV_LO);
      mapLo = u->sightMap->GetByteMap(Map::LV_LO);

      // Reset max radius seen
      u->sightMap->lastR = S16_MIN;

      // Set teams that this sweep will provide LOS for
      Team *myTeam = u->GetTeam();
      teamBits = 0;

      if (myTeam)
      {
        for (U32 team = 0; team < Game::MAX_TEAMS; ++team)
        {
          Team *other = Team::Id2Team(team);

          if (other)
          {
            if
            (
              // Other team is an ally
              Team::TestUnitRelation(u, other, Relation::ALLY)

              ||

              // Other team is giving us line of sight
              myTeam->GivingSightTo(other->GetId())
            )
            {
              ASSERT(teamRemap[team] < teamCount)
              Game::TeamSet(teamBits, teamRemap[team]);
            }
          }
        }
      }

      // Dirty cells that line of sight has changed in
      DirtyCells(cellX - r, cellZ - r, cellX + r, cellZ + r, teamBits);

      // Set up viewing radius
      if (r > 0)
      {
        r2 = r * r;
        r2Inv = 1.0f / F32(r2);

        // Get eye position
        eyePos = EyePosition(u);

        // In the code below the row and column of cells with the
        // same y and x value of the unit are processed twice but
        // their viewing information is only updated once. Stuff
        // the slight inneficiency (2*r extra comparisons). This
        // way we require 1/4 the memory and the code is more
        // elegant.

        // scan ++ quadrant
        quadrantX = POS;
        quadrantZ = POS;

        FillGradMap();
        FillMaxGradMapPosZ();
        CompareGradPosPos();

        // Scan -+ quadrant
        quadrantX = NEG;

        FillGradMapRotated();
        FillMaxGradMapPosZ();
        CompareGradNegPos();

        // Scan -- quadrant
        quadrantZ = NEG;

        FillGradMap();
        FillMaxGradMapNegZ();
        CompareGradNegNeg();

        // Scan +- quadrant
        quadrantX = POS;

        FillGradMapRotated();
        FillMaxGradMapNegZ();
        CompareGradPosNeg();
      }

      // Can always see cell that unit is occupying
      CanSee(cellX, cellZ, 0, 0, mapLo, maskLo, teamBits, Map::LV_LO);

      // Update scan info in unit's sight map
      u->sightMap->lastTeam = teamBits;
      u->sightMap->lastR = S16(r);
      u->sightMap->lastX = cellX;
      u->sightMap->lastZ = cellZ;
      u->sightMap->lastAlt = eyePos;

      STOP(sweepTime);
    }
Ejemplo n.º 19
0
CAI_BaseNPC *CASW_Sentry_Top_Cannon::SelectOptimalEnemy()
{
	// prioritize unfrozen aliens who are going to leave the cone soon.
	// prioritize aliens less the more frozen they get.
	CUtlVectorFixedGrowable< CAI_BaseNPC *,16 > candidates;
	CUtlVectorFixedGrowable< float, 16 > candidatescores;

	// search through all npcs, any that are in LOS and have health
	CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
	for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )
	{
		if (ppAIs[i]->GetHealth() > 0 && CanSee(ppAIs[i]))
		{
			// don't shoot marines
			if ( !asw_sentry_friendly_target.GetBool() && ppAIs[i]->Classify() == CLASS_ASW_MARINE )
				continue;

			if ( ppAIs[i]->Classify() == CLASS_SCANNER )
				continue;

			if ( !IsValidEnemy( ppAIs[i] ) )
				continue;

			candidates.AddToTail( ppAIs[i] );
		}
	}

	// bail out if we don't have anyone
	if ( candidates.Count() < 1 )
		return NULL;

	else if ( candidates.Count() == 1 ) // just one candidate is an obvious result
		return candidates[0];

	// score each of the candidates
	candidatescores.EnsureCount( candidates.Count() );
	for ( int i = candidates.Count() - 1; i >= 0 ; --i )
	{
		CAI_BaseNPC * RESTRICT pCandidate = candidates[i];

		// is the candidate moving into or out of the cone?
		Vector vCandVel = GetEnemyVelocity(pCandidate);
		Vector vMeToTarget = pCandidate->GetAbsOrigin() - GetFiringPosition();
		Vector vBaseForward = UTIL_YawToVector( m_fDeployYaw );

		// crush everything to 2d for simplicity
		vMeToTarget.z = 0.0f;
		vCandVel.z = 0.0f;
		vBaseForward.z = 0.0f;

		Vector velCross = vBaseForward.Cross(vCandVel); // this encodes also some info on perpendicularity
		Vector vAimCross = vBaseForward.Cross(vMeToTarget);
		bool bTargetHeadedOutOfCone = !vCandVel.IsZero() && velCross.z * vAimCross.z >= 0; // true if same sign
		float flConeLeavingUrgency;

		if ( bTargetHeadedOutOfCone )
		{
			flConeLeavingUrgency = fabs( velCross.z / vCandVel.Length2D() ); 
			// just the sin; varies 0..1 where 1 means moving perpendicular to my aim
		}
		else
		{
			flConeLeavingUrgency = 0; // not at threat of leaving just yet
		}

		// the angle between my current yaw and what's needed to hit the target
		float flSwivelNeeded = fabs( UTIL_AngleDiff(  // i wish we weren't storing euler angles
			UTIL_VecToYaw( vMeToTarget ), m_fDeployYaw ) );
		flSwivelNeeded /= ASW_SENTRY_ANGLE; // normalize to 0..2

		float fBigness = 0.0f;

		int nClassify = pCandidate->Classify();
		switch( nClassify )
		{
		case CLASS_ASW_SHIELDBUG:
		case CLASS_ASW_MORTAR_BUG:
			fBigness = 4.0f;
			break;

		case CLASS_ASW_HARVESTER:
		case CLASS_ASW_RANGER:
			fBigness = 2.0f;
			break;
		}

		candidatescores[i] = Vector( 3.0f, -1.5f, 4.0f ).Dot( Vector( flConeLeavingUrgency, flSwivelNeeded, fBigness ) );
	}
	// find the highest scoring candidate
	int best = 0;
	for ( int i = 1 ; i < candidatescores.Count() ; ++i )
	{
		if ( candidatescores[i] > candidatescores[best] )
			best = i;
	}

	// NDebugOverlay::EntityBounds(candidates[best], 255, 255, 0, 255, 0.2f );

	return candidates[best];
}
Ejemplo n.º 20
0
bool SquareLine::CanSee()
{
#if defined(_showdebugger_)
//	Debugger::GetInstance().Output("(%d,%d)  ",s_cur.x,s_cur.y);
#endif //defined(_showdebugger_)

	if(s_cur == s_goal)
		return true;
	if(!NotOutOfBoard(s_cur))//IsAValidRefuge can call CanSee with a square out of board. 
		return true;		//if no obstacle can hide the refuge from the borders of the map, the refuge is exposed.
	else if(board->GetContentAt(s_cur) == e_obstacle)
		return false;

	vector2d l_cornerspos[4]; //corners of a square
	board->GetSquareCornersInLogPx(s_cur,l_cornerspos);
	Segment sg2;
	int i,intersection_value ;
	vector2d ipoint;

	//foreach segment in the square, see intersection;
	for(i=0; i<4; i++)
	{
		if(i+1 == 4)
			sg2=Segment(l_cornerspos[i],l_cornerspos[0]);
		else
			sg2=Segment(l_cornerspos[i],l_cornerspos[i+1]);
		
		intersection_value = lines_intersect(sg,sg2, ipoint);

		ipoint.setint();

		if(intersection_value == 1 && ! (ipoint== p_lastipoint) )
		{
			if( ipoint == l_cornerspos[i] || ipoint == l_cornerspos[i+1])
			{
				vector2d g = sg.p1-ipoint;

				if(g.x>0)
				{
					if(g.y>0)
					{
						s_cur=s_cur+vector2d(1,1);
					}
					else if(g.y<0)
					{
						s_cur=s_cur+vector2d(1,-1);
					}
					else
						assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center.
				}
				else if(g.x<0)
				{
					if(g.y>0)
					{
						s_cur=s_cur+vector2d(-1,1);
					}
					else if(g.y<0)
					{
						s_cur=s_cur+vector2d(-1,-1);
					}
					else
						assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center.
				}
				else
					assert(0); //this means that the line coincides with the y-axis. and this is not possible since the destination point is a square center.
			}
			else if(i==0)
			{
				s_cur=s_cur+vector2d(0,-1);
			}
			else if(i==1)
			{
				s_cur=s_cur+vector2d(1,0);
			}
			else if(i==2)
			{
				s_cur=s_cur+vector2d(0,1);
			}
			else
			{
				s_cur=s_cur+vector2d(-1,0);
			}

			p_lastipoint=ipoint;

			break;
		}
	}

	return CanSee();
}