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; }
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); } }
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; }
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); }
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(); } }
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; }
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); }
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); }