cost AnyAngleAlgorithm::SmoothPath(const std::vector<xyLocCont> & path, std::vector<xyLocCont> &smoothed_path)
{
    smoothed_path.clear();

    if (path.empty())
        return INFINITE_COST;

    // Add the start.
    smoothed_path.push_back(path[0]);

    // Go over all locations on the original path, in order.
    for (unsigned int i = 1; i < path.size(); i++) {
        if (!LineOfSight(smoothed_path.back(), path[i])) // If there is no line of sight to the last location that is added to the smoothed path..
        {
            smoothed_path.push_back(path[i - 1]); // ..add the i-1st location on the original path to the smoothed path.
        }
    }

    // Add the goal.
    if (fabs(smoothed_path.back().x - path.back().x) > EPSILON || fabs(smoothed_path.back().y - path.back().y) > EPSILON)
        smoothed_path.push_back(path.back());

    // Compute path cost.
    cost c = 0;
    for (unsigned int i = 1; i < smoothed_path.size(); i++)
        c += EuclideanDistance(smoothed_path[i-1], smoothed_path[i]);

    return c;
}
Пример #2
0
void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_EMState == CHASING)
	{
		CheckEventLostPlayer();
	}
	else
	{
		CheckEventSeePlayer();
	}

	if (m_Target == NULL)
		return;

	cTracer LineOfSight(GetWorld());
	Vector3d AttackDirection(m_Target->GetPosition() - GetPosition());

	if (ReachedFinalDestination() && !LineOfSight.Trace(GetPosition(), AttackDirection, (int)AttackDirection.Length()))
	{
		// Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
		Attack(a_Dt / 1000);
	}
}
Пример #3
0
void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
    super::Tick(a_Dt, a_Chunk);

    if (m_EMState == CHASING)
    {
        CheckEventLostPlayer();
    }
    else
    {
        CheckEventSeePlayer();
    }

    if (m_Target == nullptr)
    {
        return;
    }

    cTracer LineOfSight(GetWorld());
    Vector3d MyHeadPosition = GetPosition() + Vector3d(0, GetHeight(), 0);
    Vector3d AttackDirection(m_Target->GetPosition() + Vector3d(0, m_Target->GetHeight(), 0) - MyHeadPosition);


    if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) && (GetHealth() > 0.0))
    {
        // Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
        StopMovingToPosition();
        Attack(a_Dt);
    }
}
cost AnyAngleAlgorithm::EvaluatePath(const std::vector<CornerLoc> & path, const bool validate_path)
{
    int num_los_checks_so_far = num_los_checks_;    // Do not include the line-of-sight check for path validation in statistics.
    bool valid_path = true;

    if (validate_path) {
        if (path.size() == 0) {
            valid_path = false;
        }
        else {
            // First and last locations on the path should be start and goal
            if (path[0].x != from_.x || path[0].y != from_.y)
                valid_path = false;

            if (path.back().x != to_.x || path.back().y != to_.y)
                valid_path = false;
        }
    }

    // Compute the path cost and validate the path.
    cost c = 0;
    for (unsigned int i = 0; i + 1 < path.size(); i++) {
        if (validate_path && !LineOfSight(path[i], path[i + 1]))
            valid_path = false;
        c += EuclideanDistance(path[i], path[i + 1]);
    }

    num_los_checks_ = num_los_checks_so_far; // Do not include the line-of-sight check for path validation in statistics.

    // Count the number of heading changes
    num_heading_changes_ = 0;
    num_freespace_heading_changes_ = 0;
    num_taut_corner_heading_changes_ = 0;
    num_non_taut_corner_heading_changes_ = 0;

    for (unsigned int i = 1; i + 1 < path.size(); i++) {
        if (!CoLinear(path[i - 1].x, path[i - 1].y, path[i].x, path[i].y, path[i + 1].x, path[i + 1].y)) {
            num_heading_changes_++;

            // If the turning point is not at a convex corner of an obstacle
            if (!IsConvexCorner(path[i]))
                num_freespace_heading_changes_++;

            // If the turn at the convex corner of an obstacle produces a taut path
            else if (IsTautCornerTurn(path[i - 1].x, path[i - 1].y, path[i].x, path[i].y, path[i + 1].x, path[i + 1].y))
                num_taut_corner_heading_changes_++;

            // If the turn at the convex corner of an obstacle does not produce a taut path
            else
                num_non_taut_corner_heading_changes_++;
        }
    }

    if (!valid_path)
        return INFINITE_COST;
    else
        return c;
}
Пример #5
0
void DoBuffer(struct Buffer *b, int x, int y, int dx, int w, int xn,
	      int yn)
{
	SetBuffer(x + xn, y + yn, b, w);
	if (fLOS) {
		LineOfSight(x, y, b, IS_SHADOW);
		FixBuffer(b, IS_SHADOW);
	}
	DrawBuffer(b, dx);
}
Пример #6
0
void cMonster::CheckEventLostPlayer(void)
{
	Vector3f pos;
	cTracer LineOfSight(GetWorld());
	
	if (m_Target != NULL)
	{
		pos = m_Target->GetPosition();
		if ((pos - GetPosition()).Length() > m_SightDistance || LineOfSight.Trace(GetPosition(),(pos - GetPosition()), (int)(pos - GetPosition()).Length()))
		{
			EventLosePlayer();
		}
	}
	else
	{
		EventLosePlayer();
	}
}
Пример #7
0
	virtual bool Item(cPlayer * a_Player) override
	{
		// Don't check players who are in creative gamemode
		if (a_Player->IsGameModeCreative())
		{
			return false;
		}
		
		Vector3d Direction = m_EndermanPos - a_Player->GetPosition();
		
		// Don't check players who are more then SightDistance (64) blocks away
		if (Direction.Length() > m_SightDistance)
		{
			return false;
		}
		
		// Don't check if the player has a pumpkin on his head
		if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN)
		{
			return false;
		}

		
		Vector3d LookVector = a_Player->GetLookVector();
		double dot = Direction.Dot(LookVector);
		
		// 0.09 rad ~ 5 degrees
		// If the player's crosshair is within 5 degrees of the enderman, it counts as looking
		if (dot <= cos(0.09))
		{
			return false;
		}
		
		cTracer LineOfSight(a_Player->GetWorld());
		if (LineOfSight.Trace(m_EndermanPos, Direction, static_cast<int>(Direction.Length())))
		{
			// No direct line of sight
			return false;
		}

		m_Player = a_Player;
		return true;
	}
Пример #8
0
void DrawScreen(struct Buffer *b, TActor * player1, TActor * player2)
{
	static int x = 0;
	static int y = 0;
	int xNoise, yNoise;

	if (screenShaking) {
		xNoise = rand() & 7;
		yNoise = rand() & 7;
	} else
		xNoise = yNoise = 0;

	if (player1 && player2) {
		if (abs(player1->tileItem.x - player2->tileItem.x) < gOptions.xSplit
		    && abs(player1->tileItem.y - player2->tileItem.y) < gOptions.ySplit) {
			SetClip(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
			// One screen
			x = (player1->tileItem.x +
			     player2->tileItem.x) / 2;
			y = (player1->tileItem.y +
			     player2->tileItem.y) / 2;

			SetBuffer(x + xNoise, y + yNoise, b, X_TILES);
			if (fLOS) {
				LineOfSight(player1->tileItem.x,
					    player1->tileItem.y, b,
					    IS_SHADOW);
				LineOfSight(player2->tileItem.x,
					    player2->tileItem.y, b,
					    IS_SHADOW2);
				FixBuffer(b, IS_SHADOW | IS_SHADOW2);
			}
			DrawBuffer(b, 0);
		} else {
			SetClip(0, 0, (SCREEN_WIDTH / 2) - 1, SCREEN_HEIGHT - 1);
			DoBuffer(b, player1->tileItem.x, player1->tileItem.y, 0, X_TILES_HALF, xNoise, yNoise);
			SetLeftEar(player1->tileItem.x, player1->tileItem.y);
			SetClip((SCREEN_WIDTH / 2) + 1, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
			DoBuffer(b, player2->tileItem.x, player2->tileItem.y, (SCREEN_WIDTH / 2) + 1, X_TILES_HALF, xNoise, yNoise);
			SetRightEar(player2->tileItem.x, player2->tileItem.y);
			x = player1->tileItem.x;
			y = player1->tileItem.y;
			BlackLine();
		}
	} else if (player1) {
		SetClip(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
		DoBuffer(b, player1->tileItem.x, player1->tileItem.y, 0,
			 X_TILES, xNoise, yNoise);
		SetLeftEar(player1->tileItem.x, player1->tileItem.y);
		SetRightEar(player1->tileItem.x, player1->tileItem.y);
		x = player1->tileItem.x;
		y = player1->tileItem.y;
	} else if (player2) {
		SetClip(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
		DoBuffer(b, player2->tileItem.x, player2->tileItem.y, 0,
			 X_TILES, xNoise, yNoise);
		SetLeftEar(player2->tileItem.x, player2->tileItem.y);
		SetRightEar(player2->tileItem.x, player2->tileItem.y);
		x = player2->tileItem.x;
		y = player2->tileItem.y;
	} else
		DoBuffer(b, x, y, 0, X_TILES, xNoise, yNoise);
	SetClip(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
}
Пример #9
0
void Bladj(phylo Intree)
{

  int i, j, q, z, l = 0;
  int *action;
  int *AgeFixed;
  char nameI[50];
  float ageI;
  int matched;
  char line[201];  // array of characters from input line
  int lineending;

  // Dimension things:
  action = ivector(0, Intree.nnodes -1);
  AgeFixed = ivector(0, Intree.nnodes -1);

  // Fix ages for nodes of terminal taxa in Phylogeny:
  for (i = 0; i < Intree.nnodes; i++)
    {
      // terminal nodes
      if (Intree.noat[i] == 0)
        {
          Intree.age[i] = 0.0;
          AgeFixed[i] = 1;
        }
      else
        {
          Intree.age[i] = 99999.9;
          AgeFixed[i] = 0;
        }
    }

  // pre-read
  lineending = whatnewline(INFILEA);
  
  //Fix node ages for nodes found in ages file
  Fa = fopen(INFILEA, "r");
  while (myfgets(line, 200, Fa, lineending) != NULL)
    {
      sscanf(line, "%s %f", nameI, &ageI); // string
      matched = 0;
      for (z = 0; z < Intree.nnodes; z++)
        {
          if (strcmp(Intree.taxon[z], nameI) == 0)
            {
              Intree.age[z] = ageI;
              AgeFixed[z] = 1;
              matched = 1;
            }
        }
    }
  fclose(Fa);

  //TODO will crash if no name/age for deepest node, need to add check for this

  // The algorithm:
  // 1. create network of fixed age nodes between the root and the other
  //    fixed age nodes, choosing the order of nodes to operate on first
  //    using age, then number of intervening nodes.

  for (i = 0; i < Intree.nnodes; i++)
    {
      q = 0;
      for (j = i+1; j < Intree.nnodes; j++)
        {
          // find all the line-of-site ages
          action[q] = 0;
      
          // correct for errors in ages
          if ((LineOfSight(Intree, AgeFixed, i, j) == 1) && \
              (Intree.age[j] >= Intree.age[i])) AgeFixed[j] = 0;
      
          if ((AgeFixed[j] == 1) && (LineOfSight(Intree, AgeFixed, i, j) == 1))
            {
              // printf("%d+%d  ",i, j);
              action[q] = j;
              q++;
            }
        }
      
      // Now sort the action  
      SortAction(Intree, action, q, i);
      
      // Adjust lengths
      for (l = 0; l < q; l++)
        {
          Adjust(Intree, AgeFixed, i, action[l]);
          //printf("i%d action%d\n",i, action[l]);
        }
    }
  if (FYOUT) FyOut(Intree) ;
  else Fy2newRec(Intree);
  
}