void UIColorPicker::Update() {
		if (!this->HasFocus() || (!this->pm_bIsBragging && !this->pm_bIsBraggingAlpha)) return;

		Vector2 mp = this->UIMan->LastMousePosition - this->GetAbsoluteLocation();

		float mdist = mp.Distance(this->pm_vCenter);
		if (mdist >= this->W / 2 - BorderSize && mdist <= this->W / 2) {
			this->pm_fHue = (float)((int)(-atan2(mp.X - (float)this->W / 2, (float)this->H / 2 - mp.Y) * (float)(180.0 / M_PI) + 180) % 360);
		} else {
			if (mp.X >= this->BorderSize * 3 + +this->Padding && mp.Y >= this->BorderSize * 3 + this->Padding && mp.X <= this->W - this->BorderSize * 3 - this->Padding  && mp.Y <= this->H - this->BorderSize * 3 - this->Padding) {
				Vector2 tmp = mp;
				tmp -= (float)this->BorderSize * 3 + this->Padding;

				this->pm_vsat.X = Utilities::Clamp(tmp.X / (float)(this->W - this->BorderSize * 6 - this->Padding * 2), 0.0f, 1.0f);
				this->pm_vsat.Y = Utilities::Clamp(1 - (tmp.Y / (float)(this->H - this->BorderSize * 6 - this->Padding * 2)), 0.0f, 1.0f);
			}
		}

		Color oldval = this->Value;
		this->Value = HSVtoRGB(this->pm_fHue, this->pm_vsat.X, this->pm_vsat.Y);

		if (this->Value != oldval) {
			if (this->OnValueChanged != nullptr) this->OnValueChanged();
			this->MarkForFullRedraw();
		}
	}
TID EntityController::GetClosestEnemyEntityInSight()
{
    if (!IsControllingEntity() ||
        !EntityExists())
        return false;

    EntityList enemies;

    int closestDist = INT_MAX;
    TID closestId = INVALID_TID;
    Vector2 selfPos = Entity()->Position();
    Vector2 otherPos = Vector2::Inf();
    int los = Entity()->Type()->P(TP_LineOfSight);

    // For now, just select the closest entity in sight
    for (auto& entityR : g_Game->Enemy()->Entities())
    {
        if (!Entity()->CanAttack(entityR.first))
            continue;

        otherPos = entityR.second->Position();
        int dist = selfPos.Distance(otherPos);

        if (dist < los && dist < closestDist)
        {
            closestId = entityR.first;
            closestDist = dist;
        }
    }

    return closestId;
}
Exemple #3
0
bool Eagle::DoesRobotHaveBall(RobotState robotState, Vector2 ballPos) 
{
	Vector2 robotPos = robotState.Position();

    float angleThresh;
	float distanceThresh;

    if (robotState.HasBall())
    {
        angleThresh = M_PI_2;
        distanceThresh = 70.0f;
    }
    else
    {
        angleThresh = M_PI_4;
        distanceThresh = 45.0f;
    }
	
	float angleToBall = fmod(robotPos.GetAngleTo(&ballPos), (2*M_PI));
	float robotOrientation = fmod(robotState.Orientation(), (2*M_PI));

	float distanceToBall = robotPos.Distance(&ballPos);
	
    float orientationDiff = fmod(fabs(robotOrientation - angleToBall), (2*M_PI));
    bool withinOrientationThresh = (orientationDiff < angleThresh) || (2*M_PI - orientationDiff < angleThresh);
    bool withinProximityThresh = distanceToBall < distanceThresh;
	
	if(withinOrientationThresh && withinProximityThresh)
	{
		return true;
	} 
	
	return false;
}
Exemple #4
0
//----------------------------------------------------------------------------------------------
MapArea StarCraftMap::GetSpecialBuildingPosition(EntityClassType p_buildingType) const
{
    if (!m_isOnline)
        DEBUG_THROW(InvalidOperationException(XcptHere));

    MapArea candidatePosition = MapArea::Null();

    // Get the player base tile position
    MapArea colony = g_Game->Self()->GetColonyMapArea();
    Vector2 colonyTile = colony.Pos();

    // Get the unit type object
    UnitType type;
    TID unitTypeId;
    string typeName;
    unitTypeId = g_Database.EntityMapping.GetBySecond(p_buildingType);
    typeName = g_Database.EntityIdentMapping.GetByFirst(unitTypeId);
    type = BWAPI::UnitType::getType(typeName);

    if (type.isRefinery())
    {
        int bestDistance = INT_MAX;
        Unitset geysers = Broodwar->getGeysers();
        Unit currentGeyser;

        for (unsigned i = 0; i < geysers.size(); ++i)
        {
            currentGeyser = geysers[i];
            Vector2 currentPosition = Vector2(
                                          UnitPositionFromTilePosition(currentGeyser->getTilePosition().x),
                                          UnitPositionFromTilePosition(currentGeyser->getTilePosition().y));
            int currentDistance = colonyTile.Distance(currentPosition);

            if (currentDistance <= bestDistance)
            {
                bestDistance = currentDistance;
                candidatePosition = MapArea(
                                        currentPosition,
                                        type.tileWidth(),
                                        type.tileHeight());
            }
        }
        _ASSERTE(CanBuildHere(candidatePosition.Pos(), p_buildingType));
    }

    return candidatePosition;
}
MapArea WorldMap::GetSpecialBuildingPosition(EntityClassType buildingType) const
{
    if (!m_isOnline)
        DEBUG_THROW(InvalidOperationException(XcptHere));

    // Add-ons are always built in place of its parent building, it has nothing to do with
    // place adaptation
    MapArea candidatePosition = MapArea::Null();

    // Get the unit type object
    const IGameUnitType* pUnitType = g_GameImpl->GetUnitTypeByEngineId(buildingType);

    if (pUnitType->IsRefinery())
    {
        // Get the player base tile position
        MapArea colony = g_Game->Self()->GetColonyMapArea();
        Vector2 colonyTile = colony.Pos();

        int bestDistance = INT_MAX;
        auto gasFields = g_GameImpl->MapGasFields();
        TID currentGeyser;

        for (unsigned i = 0; i < gasFields->Size(); ++i)
        {
            currentGeyser = gasFields->At(i);

            Vector2 currentPosition = UnitPositionFromTilePosition(g_GameImpl->UnitTilePosition(currentGeyser));

            if (CanBuildHere(currentPosition, pUnitType->EngineId()))
            {
                int currentDistance = colonyTile.Distance(currentPosition);

                if (currentDistance <= bestDistance)
                {
                    bestDistance = currentDistance;
                    candidatePosition = MapArea(
                        currentPosition,
                        pUnitType->TileWidth(),
                        pUnitType->TileHeight());
                }
            }
        }
    }

    return candidatePosition;
}
void ArmyController::CalcEnemyData()
{
    Vector2 selfPos = Center();
    Vector2 otherPos = Vector2::Inf();

    m_closestEnemy.clear();
    m_enemyData.clear();

    for (auto& entityR : g_Game->Enemy()->Entities())
    {
        if (entityR.second->Exists() &&
            entityR.second->P(OP_IsTargetable))
        {
            otherPos = entityR.second->Position();
            int dist = selfPos.Distance(otherPos);
            m_closestEnemy.insert(make_pair(dist, entityR.first));

            auto& dat = m_enemyData[entityR.first];
            dat.Id = entityR.first;
            dat.DistanceToCenter = dist;
            dat.TargetEntityId = entityR.second->TargetId();
        }
    }

    // No enemy close to me
    if (m_closestEnemy.empty())
    {
        m_targetEntityId = INVALID_TID;
    }
    // The closest enemy to me is in sight, and it is not my last chosen one
    else if (m_targetEntityId != m_closestEnemy.begin()->second)
    {
        m_targetEntityId = m_closestEnemy.begin()->second;
        LogInfo("%s chosen enemy target %s", ToString().c_str(), g_Game->Enemy()->GetEntity(m_targetEntityId)->ToString(true).c_str());
    }
}
void Game::HandleAI(float msecs)
{
    // Run AI for computer planes
    for (int i = activePlayers_; i < TotalPlayers(); i ++)
    {
        // Bail if it's dying or stalled. We're not allowing sniping while stalling, the
        // bots are just too good a shot
        Plane *current = &players_[i];
        if (current->IsDying() || current->IsStalled())
            continue;

        // Find the closets enemy plane
        Plane *target = NULL;
        float currentRange = 9999;
        for (int j = 0; j < TotalPlayers(); j ++)
        {
            if (j == i) // Can't target self
                continue;

            // We're currently ignoring respawning players. May remove this later to make
            // the AI more aggressive
            if (currentRange > current->GetPosition().Distance(players_[j].GetPosition())
                && !players_[j].IsDying() && !players_[j].IsStalled() && !players_[j].IsInvincible())
            {
                target = &players_[j];
                currentRange = current->GetPosition().Distance(target->GetPosition());
            }
        }

        if (target == NULL) // Level off if we don't have a target
        {
            float targetAngle = 0;
            if (targetAngle > current->GetRotation())
                current->TurnLeft(msecs);
            else
                current->TurnRight(msecs);
        }
        else
        {
            // Plot an intercept course!
            Vector2 currentPosition = current->GetPosition();
            Vector2 targetPosition = target->GetPosition();
            Vector2 interceptPoint = Vector2::CollisionPoint(currentPosition, current->GetVelocity(), targetPosition, target->GetVelocity());

            // If the target is running parallel to us, go for them
            //if (interceptPoint.x == 0 && interceptPoint.y == 0)
            //    interceptPoint = targetPosition;
            
            // If the target is in front of us, try and lead it
            // Calculate time for bullet to reach intercept point
            Vector2 bulletStartPos = currentPosition + current->GetVelocity().Normalise() * (20 + MAX_SPEED + 0.5f);
            float bulletTravelTime = (bulletStartPos - interceptPoint).Length() / BULLET_SPEED;
            // Calculate target position at that time
            Vector2 projectedTargetPos = targetPosition + (target->GetVelocity() * bulletTravelTime);

            // Decide if it's worth a shot
            if (interceptPoint.Distance(projectedTargetPos) < 20)
            {
                Bullet *bullet = current->Fire();
                if (bullet != NULL)
                    bullets_.push_back(bullet);
            }

            // Don't play chicken
            // TODO: Turn away from collisions

            // Don't derp
            // TODO: Don't run into the ground

            // Attempt to maneuver for a better shot
            Vector2 currentVelocity = current->GetVelocity().Normalise();
            Vector2 targetVelocity = (currentPosition - projectedTargetPos).Normalise();

            float diffAngle = currentVelocity.Cross(targetVelocity);

            if (diffAngle < 0)
                current->TurnLeft(msecs);
            else
                current->TurnRight(msecs);

            if (DEBUG_RENDERER)
            {
                glBegin(GL_QUADS);
                    glColor3f(0, 0, 0);
                    glVertex2f(interceptPoint.x - 2, interceptPoint.y - 2);
                    glVertex2f(interceptPoint.x + 2, interceptPoint.y - 2);
                    glVertex2f(interceptPoint.x + 2, interceptPoint.y + 2);
                    glVertex2f(interceptPoint.x - 2, interceptPoint.y + 2);
                glEnd();

                glBegin(GL_QUADS);
                    glColor3f(1, 0, 1);
                    glVertex2f(projectedTargetPos.x - 15, projectedTargetPos.y - 15);
                    glVertex2f(projectedTargetPos.x + 15, projectedTargetPos.y - 15);
                    glVertex2f(projectedTargetPos.x + 15, projectedTargetPos.y + 15);
                    glVertex2f(projectedTargetPos.x - 15, projectedTargetPos.y + 15);
                glEnd();
            }
        }
    }
}
Exemple #8
0
/*!
* Identify the target state that we wish the robot to be in. This will be the target which the A* algorithm plots towards.
*/
RobotState Eagle::IdentifyTarget(RobotState &ourRobotState, RobotState &enemyRobotState, Vector2 ballPos, bool doWeHaveBall, bool &isMovingToBall)
{
	RobotState targetState;

	Vector2 ourRobotPos = ourRobotState.Position();
	Vector2 enemyRobotPos = enemyRobotState.Position();

    Vector2 ourGoalCentre = GoalCentrePosition(m_pitchSide);
    Vector2 enemyGoalCentre;

    if (m_pitchSide == eLeftSide)
    {
        enemyGoalCentre = GoalCentrePosition(eRightSide);
    }
    else
    {
        enemyGoalCentre = GoalCentrePosition(eLeftSide);
    }
    
    ballPos.Clamp(Vector2(0,0), Vector2(m_pitchSizeX-1, m_pitchSizeY-1));
	isMovingToBall = false;

	// doWeHaveBall is a value which comes from the robot's rotational sensors.
    //ourRobotState.SetHasBall(doWeHaveBall);
	ourRobotState.SetHasBall(DoesRobotHaveBall(ourRobotState, ballPos));
    enemyRobotState.SetHasBall(DoesRobotHaveBall(enemyRobotState, ballPos));

    if (m_state == ePenaltyAttack)
	{
		m_isKickingPosSet = false;

         // When taking a penalty, we want to find a free position to kick to.
        // Position should stay the same - we only want to re-orientate.
        targetState.SetPosition(ourRobotPos);

        // We'll do this by checking for intersections between us and three positions on the goal line.
        Vector2 targetPositions[3];

        targetPositions[0] = enemyGoalCentre;
        targetPositions[1] = enemyGoalCentre - Vector2(0,50);
        targetPositions[2] = enemyGoalCentre + Vector2(0,50);

        int arrayLength = sizeof(targetPositions)/sizeof(Vector2);

        Vector2 optimalShootingTarget;
        float bestDistanceFromEnemy = 0;

        // Iterate through the positions, finding the best one, based on if it's unblocked and how far it is from the enemy robot.
        for (int i=0; i < arrayLength; i++)
        {
            // Check if the target is unblocked.
            bool isBlocked = m_intersection.LineCircleIntersection(ourRobotPos, targetPositions[i], enemyRobotPos, ROBOT_RADIUS);

            if (isBlocked)
            {
                continue;
            }

            float distanceSqdToEnemy = enemyRobotPos.DistanceSquared(&targetPositions[i]);

            // Check if this beats our previous best distance.
            if (distanceSqdToEnemy > bestDistanceFromEnemy)
            {
                bestDistanceFromEnemy = distanceSqdToEnemy;
                optimalShootingTarget = targetPositions[i];
            }

            // Check that we do actually have a target set.
            if (optimalShootingTarget.IsSet())
            {
                float angleToTarget = ourRobotPos.GetAngleTo(&optimalShootingTarget);

                targetState.SetOrientation(angleToTarget);
            }
            else
            {
                targetState.SetOrientation(ourRobotState.Orientation());
            }
        }


	}
    else if (m_state == ePenaltyDefend)
	{
		m_isKickingPosSet = false;
	
		// When defending, we're permitted to move up and down the goalline.
		// Orientation should stay the same.
		targetState.SetOrientation(ourRobotState.Orientation());

		// X-axis position should be the same, y-axis should be a position extrapolated in the direction of the enemy robot.
		//float extrapolationGradient = tan(enemyRobotState.Orientation());
		// I'm experimenting with extrapolating on a line between the robot and ball instead.
		float extrapolationGradient = enemyRobotPos.Gradient(&ballPos);

		int extrapolatedY = enemyRobotPos.Y() + ((ourRobotPos.X() - enemyRobotPos.X()) * extrapolationGradient); 

		Vector2 proposedPosition(ourRobotPos.X(), extrapolatedY);
		proposedPosition.Clamp(Vector2(0,0), Vector2(m_pitchSizeX-1, m_pitchSizeY-1));

		targetState.SetPosition(proposedPosition);
	}
	else
	{
		// If we're here, assume we're in open play.
		if (!ourRobotState.HasBall())
		{
			m_isKickingPosSet = false;

			// Check if the enemy robot has the ball.
			if (enemyRobotState.HasBall())
            {
				if (m_pitchSide == eLeftSide)
				{
                    targetState.SetPosition(ourGoalCentre.X() + 50, ourGoalCentre.Y());
					targetState.SetOrientation(0);
				}
				else
				{
                    targetState.SetPosition(ourGoalCentre.X() - 50, ourGoalCentre.Y());
					targetState.SetOrientation(M_PI);
				}
            }
			else
			{
				// If we don't have the ball, the aim should be to move to the ball.
				isMovingToBall = true;
				targetState.SetPosition(ballPos);
				
				if (m_pitchSide == eLeftSide)
				{
					targetState.SetOrientation(0);
				}
				else
				{
					targetState.SetOrientation(M_PI);
				}
			}
		}
		else
		{
			// Check if the previously calculated target pos is appropriate or if we need to recalc.
			if ((m_isKickingPosSet) && ((m_kickingPos.Distance(&ourRobotPos) < 30) || (m_kickingPos.Distance(&enemyRobotPos) < 40)))
			{
				m_isKickingPosSet = false;
			}

			if (!m_isKickingPosSet)
			{
				// If we have the ball, let's move to a more appropriate place.
				// This is done regardless of whether we're shooting or not.
				/*
					This should depend on:
					1. The opposite half of the pitch to the enemy robot.
					2. Within the kicking threshold.
					3. Fairly central, but outside of the enemy robot's radius
					4. Orientated towards the goal
				*/
				bool isEnemyOnBottomSide;
			
				// Determine which half of the pitch the enemy robot is on.
				if (enemyRobotState.Position().Y() < m_pitchSizeY/2)
				{
					isEnemyOnBottomSide = true;
				}
				else
				{
					isEnemyOnBottomSide = false;
				}

				// Determine where the kicking threshold is for this side of the pitch.
		                float kickingPositionX;
		                float kickingPositionY;
		
				if (m_pitchSide == eLeftSide)
				{
                   			 kickingPositionX = m_pitchSizeX - ((KICKING_THRESHOLD/2)*m_pitchSizeX);
				}
				else
				{
                    			kickingPositionX = (KICKING_THRESHOLD/2)*m_pitchSizeX;
				}
		
		                if (isEnemyOnBottomSide)
		                {
		                    kickingPositionY = m_pitchSizeY/2 + 80;
		                }
		                else
		                {
		                    kickingPositionY = m_pitchSizeY/2 - 80;
		                }
		
						// Check if the position is within two robot radii of the enemy.
		                Vector2 proposedPosition = Vector2(kickingPositionX,kickingPositionY);

				// Check if the proposed position is too close to the enemy robot to be used.
				if (proposedPosition.Distance(&enemyRobotPos) < 2*ROBOT_RADIUS)
				{
					float adjustedYPosition;

					if (isEnemyOnBottomSide)
					{
						adjustedYPosition = proposedPosition.Y() + 2*ROBOT_RADIUS;
					}
					else
					{
						adjustedYPosition = proposedPosition.Y() - 2*ROBOT_RADIUS;
					}

					proposedPosition = Vector2( proposedPosition.X(), adjustedYPosition);
				}

				proposedPosition.Clamp(Vector2(0,0), Vector2(m_pitchSizeX-1, m_pitchSizeY-1));
				m_kickingPos = proposedPosition;

				m_isKickingPosSet = true;
			}
		
			targetState.SetPosition(m_kickingPos);
			
			// We'll do this by checking for intersections between us and three positions on the goal line.
			Vector2 targetPositions[3];

			targetPositions[0] = enemyGoalCentre;
			targetPositions[1] = enemyGoalCentre - Vector2(0,50);
			targetPositions[2] = enemyGoalCentre + Vector2(0,50);

			int arrayLength = sizeof(targetPositions)/sizeof(Vector2);

			Vector2 optimalShootingTarget;
			float bestDistanceFromEnemy = 0;

			// Iterate through the positions, finding the best one, based on if it's unblocked and how far it is from the enemy robot.
			for (int i=0; i < arrayLength; i++)
			{
				// Check if the target is unblocked.
				bool isBlocked = m_intersection.LineCircleIntersection(m_kickingPos, targetPositions[i], enemyRobotPos, ROBOT_RADIUS);

				if (isBlocked)
				{
					continue;
				}

				float distanceSqdToEnemy = enemyRobotPos.DistanceSquared(&targetPositions[i]);

				// Check if this beats our previous best distance.
				if (distanceSqdToEnemy > bestDistanceFromEnemy)
				{
					bestDistanceFromEnemy = distanceSqdToEnemy;
					optimalShootingTarget = targetPositions[i];
				}

				// Check that we do actually have a target set.
				if (optimalShootingTarget.IsSet())
				{
					float angleToTarget = m_kickingPos.GetAngleTo(&optimalShootingTarget);

					targetState.SetOrientation(angleToTarget);
				}
				else
				{
					targetState.SetOrientation(ourRobotState.Orientation());
				}
			}
		}

		targetState.SetPosition((int)targetState.Position().X(), (int)targetState.Position().Y());
	}

	
	return targetState;
}