MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{   
    ui->setupUi(this);

    // Define the scene
    scene = new Map(this);
    ui->graphicView->setScene(scene);
    ui->graphicView->setRenderHint(QPainter::Antialiasing);

    // Add tanks to this scene
    tank = new Tank();
    scene->addItem(tank);

    // Set animation
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()),
            scene, SLOT(advance()));
    timer->start(100);

    // Many connections...
    connect(scene, SIGNAL(toTarget(QPointF)),
            this, SLOT(moveTanks(QPointF)));
}
Beispiel #2
0
Camera::Camera( const QVector3D & pos, const QVector3D & target, float fov,\
                float zNear, float zFar, int width, int height )
: pos_( pos )
, dir_( DEFAULT_DIR_VEC )
, up_( DEFAULT_UP_VEC )
, side_( DEFAULT_SIDE_VEC )
, transform_()
, fov_( fov )
, zNear_( zNear )
, zFar_( zFar )
, width_( width )
, height_( height )
, aspect_( 0.0f )
{
    computeAspect();   

    toTarget( target );

    computeMatrix();
}
void loop() {
    api.getMyZRState(myState);
    time = api.getTime();
    picNum = game.getMemoryFilled();   
    DEBUG(("%d picture(s) have been taken\n", picNum));
    DEBUG(("STATE = %d\n",state));
    DEBUG(("ARRAY = %d,%d,%d\n",goodPOI[0],goodPOI[1],goodPOI[2]));
    DEBUG(("TARGET = %f,%f,%f\n",target[0],target[1],target[2]));
    if(takePic > -1){ //takePic is used to make sure you take an accurate picture.
        takePic--;
    }
    if(time%60 == 0){
        for(int i = 0; i < 3; i++){
            goodPOI[i] = 1;
        }
        state = ST_GET_POI;
    }
    if((time > solarFlareBegin - 25)&&(time < solarFlareBegin)){
        if((state < ST_SHADOW)||(state > ST_SHADOW + 9)){
            state = ST_SHADOW; //if not in shadow state go there.
        }
    }
    else if(time == solarFlareBegin + 3){
        state = ST_GET_POI + 1;
    }
    else if (game.getNextFlare() != -1) {
	    solarFlareBegin = api.getTime() + game.getNextFlare();
	    DEBUG(("Next solar flare will occur at %ds.\n", solarFlareBegin));
	}
    switch(state){
        case ST_GET_POI: //POI selection
            closestPOI(goodPOI,POI,23);
            getPOILoc(POIproj, POIID, 23);
            takePic = 23; //25 probably needs to be changed. only good for the first cycle.
            DEBUG(("POI Coors = %f,%f,%f\n",POI[0],POI[1],POI[2]));
            state = ST_OUTER;
            break;
            
        case ST_GET_POI + 1: //if coming from shadow zone
            closestPOI(goodPOI,POI,30);
            getPOILoc(POIproj, POIID, 30);
            takePic = 30; //25 probably needs to be changed. only good for the first cycle.
            DEBUG(("POI Coors = %f,%f,%f\n",POI[0],POI[1],POI[2]));
            state = ST_OUTER;
            break;
            
        case ST_OUTER: //outer picture
            wp = false;
            //find closest place to take picture
            memcpy(target, POIproj, 3*sizeof(float)); //copy the projected POI location to target
            for(int i = 0; i < 3; i++){
                target[i] *= 0.465/mathVecMagnitude(POI,3); //dilate target to outer zone
            }
            mathVecSubtract(facing,origin,target,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            if(pathToTarget(myState,target,waypoint)){
                setWaypoint(waypoint,originalVecBetween);
                state = ST_OUTER + 1;
                for (int i = 0; i < 3; i++) tempTarget[i] = target[i];
            }
            else{
                state = ST_OUTER + 2;
            }
            break;
        
        case ST_OUTER + 1: //something is in the way so go to waypoint
            wp = true;
            mathVecSubtract(facing,POIproj,target,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            if(goToWaypoint(target,waypoint,tempTarget,originalVecBetween)){
                goToWaypoint(target,waypoint,tempTarget,originalVecBetween);
            }
            else{
                state = ST_OUTER + 2;
            }
            break;
            
        case ST_OUTER + 2://go to target
            mathVecSubtract(facing,origin,myState,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            toTarget();
            if(takePic == 0){
                game.takePic(POIID);
            }
            if(game.getMemoryFilled() > checkNum){
                checkNum++;
                getPOILoc(POIproj, POIID, 5);
                state = ST_INNER;
            }
            break;

      
        case ST_INNER: //inner picture
            wp = false;
            memcpy(target, POIproj, 3*sizeof(float));
            for(int i = 0; i < 3; i++){
                target[i] *= 0.34/mathVecMagnitude(POI,3);
            }
            mathVecSubtract(facing,POIproj,target,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            haulAssTowardTarget(target,8);
            state = ST_INNER + 1;
            break;
        
        case ST_INNER + 1: //after outer picture is taken, rush to inner zone. 
            mathVecSubtract(facing,POIproj,myState,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            if(distance(myState,target)<0.02){
                haulAssTowardTarget(target,10);
            }
            else{
                haulAssTowardTarget(target,2);
            }
            if(game.alignLine(POIID)){
                game.takePic(POIID);
            }
            if(game.getMemoryFilled() > checkNum){
                checkNum++;
                state = ST_UPLOAD;
            }
            break;
            
            
        case ST_SHADOW: //shadow zone
            wp = false;
            target[0] = 0.39; //arbitrary point in the shadow zone 
            target[1] = 0.00;
            target[2] = 0.00;
            if(pathToTarget(myState,target,waypoint)){
                setWaypoint(waypoint,originalVecBetween);
                goToWaypoint(target,waypoint,tempTarget,originalVecBetween);
                state = 31;
            }
            else{
                state = 32;
            }
            break;
            
        case ST_SHADOW + 1:
            wp = true;
            if(goToWaypoint(target,waypoint,tempTarget,originalVecBetween)){
                goToWaypoint(target,waypoint,tempTarget,originalVecBetween);
            }
            else{
                toTarget();
                state = 32;
            }
            break;
            
        case ST_SHADOW + 2:
            mathVecSubtract(facing,earth,myState,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            toTarget();
            game.uploadPic();
            break;
           
        case ST_UPLOAD: //upload, needs to be fixed
            for(int i = 0; i < 3; i++){
                uploadPos[i] = myState[i] / mathVecMagnitude(myState, 3) * 0.65;
            }
            mathVecSubtract(facing,earth,uploadPos,3); 
            mathVecNormalize(facing,3);
            api.setAttitudeTarget(facing);
            haulAssTowardTarget(uploadPos,1.8);
            state = ST_UPLOAD + 1;
            break;
            
        case ST_UPLOAD + 1: 
            //get to the closest place, keep trying to upload
            api.setAttitudeTarget(facing);
            if(distance(myState,origin)>0.54){
                api.setPositionTarget(myState);
                game.uploadPic();
            }
            else{
                if(distance(myState,origin)>0.51){
                    api.setPositionTarget(uploadPos);
                }
                else{
                    haulAssTowardTarget(uploadPos,1.8);
                }
            }
            if(picNum == 0){
                DEBUG(("LOOKING FOR POI"));
                state = ST_GET_POI;
            }
            break;
    }
}
Beispiel #4
0
void Bot::RegisterVisibleEnemies()
{
    if(G_ISGHOSTING(self) || GS_MatchState() == MATCH_STATE_COUNTDOWN || GS_ShootingDisabled())
        return;

    CheckIsInThinkFrame(__FUNCTION__);

    // Compute look dir before loop
    vec3_t lookDir;
    AngleVectors(self->s.angles, lookDir, nullptr, nullptr);

    float fov = 110.0f + 69.0f * Skill();
    float dotFactor = cosf((float)DEG2RAD(fov / 2));

    struct EntAndDistance
    {
        int entNum;
        float distance;

        EntAndDistance(int entNum_, float distance_): entNum(entNum_), distance(distance_) {}
        bool operator<(const EntAndDistance &that) const { return distance < that.distance; }
    };

    // Do not call inPVS() and G_Visible() for potential targets inside a loop for all clients.
    // In worst case when all bots may see each other we get N^2 traces and PVS tests
    // First, select all candidate targets along with distance to a bot.
    // Then choose not more than BotBrain::maxTrackedEnemies nearest enemies for calling OnEnemyViewed()
    // It may cause data loss (far enemies may have higher logical priority),
    // but in a common good case (when there are few visible enemies) it preserves data,
    // and in the worst case mentioned above it does not act weird from player POV and prevents server hang up.
    // Note: non-client entities also may be candidate targets.
    StaticVector<EntAndDistance, MAX_EDICTS> candidateTargets;

    for (int i = 1; i < game.numentities; ++i)
    {
        edict_t *ent = game.edicts + i;
        if (botBrain.MayNotBeFeasibleEnemy(ent))
            continue;

        // Reject targets quickly by fov
        Vec3 toTarget(ent->s.origin);
        toTarget -= self->s.origin;
        float squareDistance = toTarget.SquaredLength();
        if (squareDistance < 1)
            continue;
        float invDistance = Q_RSqrt(squareDistance);
        toTarget *= invDistance;
        if (toTarget.Dot(lookDir) < dotFactor)
            continue;

        // It seams to be more instruction cache-friendly to just add an entity to a plain array
        // and sort it once after the loop instead of pushing an entity in a heap on each iteration
        candidateTargets.emplace_back(EntAndDistance(ENTNUM(ent), 1.0f / invDistance));
    }

    std::sort(candidateTargets.begin(), candidateTargets.end());

    // Select inPVS/visible targets first to aid instruction cache, do not call callbacks in loop
    StaticVector<edict_t *, MAX_CLIENTS> targetsInPVS;
    StaticVector<edict_t *, MAX_CLIENTS> visibleTargets;

    static_assert(AiBaseEnemyPool::MAX_TRACKED_ENEMIES <= MAX_CLIENTS, "targetsInPVS capacity may be exceeded");

    for (int i = 0, end = std::min(candidateTargets.size(), botBrain.MaxTrackedEnemies()); i < end; ++i)
    {
        edict_t *ent = game.edicts + candidateTargets[i].entNum;
        if (trap_inPVS(self->s.origin, ent->s.origin))
            targetsInPVS.push_back(ent);
    }

    for (auto ent: targetsInPVS)
        if (G_Visible(self, ent))
            visibleTargets.push_back(ent);

    // Call bot brain callbacks on visible targets
    for (auto ent: visibleTargets)
        botBrain.OnEnemyViewed(ent);

    botBrain.AfterAllEnemiesViewed();

    CheckAlertSpots(visibleTargets);
}
//-----------------------------------------------------------------------------
// Purpose: Give the buster a slight attraction to striders.
//			Ported back from the magnade.
//-----------------------------------------------------------------------------
void CWeaponStriderBuster::BusterFlyThink()
{
	if (IsAttachedToStrider())
		return; // early out. Think no more.

	// If we're nosediving, forget about magnetism.
	if ( m_bNoseDiving )
	{
		if ( VPhysicsGetObject() )
			VPhysicsGetObject()->ApplyForceCenter( Vector( 0, 0, striderbuster_dive_force.GetFloat() ) );
		SetNextThink(gpGlobals->curtime + 0.01f);
		return;
	}

	// seek?	
	const float magradius = 38.0 * sk_striderbuster_magnet_multiplier.GetFloat(); // radius of strider hull times multiplier
	if (magradius > 0 &&
		GetMoveType() == MOVETYPE_VPHYSICS &&
		VPhysicsGetObject()
		)
	{
		// find the nearest enemy.
		CBaseEntity *pList[16];
		Vector origin = GetAbsOrigin();

		// do a find in box ( a little faster than sphere )
		int count;
		{
			Vector mins,maxs;
			mins = origin; 
			mins -= magradius;
			
			maxs = origin; 
			maxs += magradius;

			count = UTIL_EntitiesInBox(pList, 16, mins, maxs, FL_NPC); 
		}

		float magradiusSq = Square( magradius );	
		float nearestDistSq = magradiusSq + 1;
		int bestFit = -1;
		Vector toTarget(0.0f, 0.0f, 0.0f); // will be garbage unless something good is found
		CNPC_Strider *pBestStrider  = NULL;

		for ( int ii = 0 ; ii < count ; ++ii )
		{
			CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pList[ii]);
			if ( pStrider && !pStrider->CarriedByDropship() ) // ShouldStickToEntity() doesn't work because the strider NPC isn't what we glue to
			{
				// get distance squared
				VectorSubtract( pStrider->GetAdjustedOrigin(), GetAbsOrigin(), toTarget );

				//NDebugOverlay::Line( GetAbsOrigin(), GetAbsOrigin() + toTarget, 128, 0, 128, false, 0.1 );

				float dSq = toTarget.LengthSqr();
				if (dSq < nearestDistSq)
				{
					bestFit = ii; nearestDistSq = dSq;
					pBestStrider = pStrider;
				}
			}
		}

		if (bestFit >= 0) // we found something and should attract towards it. (hysterisis later?)
		{
			if ( striderbuster_debugseek.GetBool() )
			{
				NDebugOverlay::Circle( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, 255, true, .1 );
				NDebugOverlay::Cross3D( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, true, .1 );
			}

			// force magnitude. 
			float magnitude = GetMass() * striderbuster_magnetic_force_strider.GetFloat();
			int falloff = striderbuster_falloff_power.GetInt();
			switch (falloff) 
			{
			case 1:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / nearestDistSq) ); // dividing through by distance squared normalizes toTarget and gives a linear falloff
				break;
			case 2:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * sqrtf(nearestDistSq))) ); // dividing through by distance cubed normalizes toTarget and gives a quadratic falloff
				break;
			case 3:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * nearestDistSq)) ); // dividing through by distance fourth normalizes toTarget and gives a cubic falloff
				break;
			case 4:
				{
					Vector toTarget;
					pBestStrider->GetAttachment( "buster_target", toTarget );

					if ( striderbuster_debugseek.GetBool() )
					{
						NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 );
						NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 );
					}

					toTarget -= GetAbsOrigin();
					toTarget.NormalizeInPlace();
					VPhysicsGetObject()->ApplyForceCenter( toTarget * magnitude );

				}
				break;
			default: // arbitrary powers
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude * powf(nearestDistSq,(falloff+1.0f)/2)) );  // square root for distance instead of squared, add one to normalize toTarget 
				break;
			}
		}

		SetNextThink(gpGlobals->curtime + 0.01f);
	}
}