#include "raylib.h" #include extern Vector3 playerPosition; extern bool IsSolidAt(Vector3 position, float radius); const int NPC_COUNT = 12; Vector3 enemyPosition[NPC_COUNT] = { { -72.0f, 1.0f, -72.0f }, { 72.0f, 1.0f, -72.0f }, { -72.0f, 1.0f, 72.0f }, { 72.0f, 1.0f, 72.0f }, { -48.0f, 1.0f, -36.0f }, { 48.0f, 1.0f, -36.0f }, { -48.0f, 1.0f, 36.0f }, { 48.0f, 1.0f, 36.0f }, { -28.0f, 1.0f, -68.0f }, { 28.0f, 1.0f, -68.0f }, { -28.0f, 1.0f, 68.0f }, { 28.0f, 1.0f, 68.0f } }; float enemyWalkTime[NPC_COUNT] = {}; float enemyStunTime[NPC_COUNT] = {}; float enemySpin[NPC_COUNT] = {}; const float enemySpeed = 2.4f; const float enemyStunDuration = 2.5f; bool enemyMoving[NPC_COUNT] = {}; void MoveEnemyWithCollision( int index, float moveX, float moveZ ) { Vector3 nextX = enemyPosition[index]; nextX.x += moveX; if (!IsSolidAt(nextX, 0.45f)) enemyPosition[index].x = nextX.x; Vector3 nextZ = enemyPosition[index]; nextZ.z += moveZ; if (!IsSolidAt(nextZ, 0.45f)) enemyPosition[index].z = nextZ.z; } void UpdateEnemy(float deltaTime) { for (int i = 0; i < NPC_COUNT; i++) { float dx = playerPosition.x - enemyPosition[i].x; float dz = playerPosition.z - enemyPosition[i].z; float distance = std::sqrt( dx * dx + dz * dz ); // ========================================= // MAREADO // ========================================= if (enemyStunTime[i] > 0.0f) { enemyStunTime[i] -= deltaTime; enemySpin[i] += deltaTime * 18.0f; enemyMoving[i] = false; if (enemyStunTime[i] < 0.0f) enemyStunTime[i] = 0.0f; continue; } // ========================================= // EMPUJAR JUGADOR // ========================================= if (distance > 0.001f && distance < 1.5f) { float pushX = (dx / distance) * 10.0f * deltaTime; float pushZ = (dz / distance) * 10.0f * deltaTime; Vector3 next = playerPosition; next.x += pushX; next.z += pushZ; if (!IsSolidAt(next, 0.45f)) playerPosition = next; } // ========================================= // SEGUIR JUGADOR // ========================================= if (distance > 1.8f) { dx /= distance; dz /= distance; MoveEnemyWithCollision( i, dx * enemySpeed * deltaTime, dz * enemySpeed * deltaTime ); enemyWalkTime[i] += deltaTime * 9.0f; enemyMoving[i] = true; } else { enemyMoving[i] = false; enemyWalkTime[i] = 0.0f; } } // ========================================= // CLICK DERECHO // ========================================= if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) { for (int i = 0; i < NPC_COUNT; i++) { float dx = enemyPosition[i].x - playerPosition.x; float dz = enemyPosition[i].z - playerPosition.z; float distance = std::sqrt( dx * dx + dz * dz ); if (distance < 4.0f && distance > 0.001f) { dx /= distance; dz /= distance; MoveEnemyWithCollision( i, dx * 3.5f, dz * 3.5f ); enemyStunTime[i] = enemyStunDuration; enemySpin[i] = 0.0f; enemyWalkTime[i] = 0.0f; } } } } void TeleportEnemyNearPlayer( int index, float yaw ) { if (index < 0 || index >= NPC_COUNT) return; // ========================================= // CONSERVAR LA DISTANCIA ACTUAL // ========================================= float dx = enemyPosition[index].x - playerPosition.x; float dz = enemyPosition[index].z - playerPosition.z; float oldDistance = std::sqrt( dx * dx + dz * dz ); if (oldDistance < 3.0f) oldDistance = 3.0f; // ========================================= // BUSCAR OTRA DIRECCIÓN // ========================================= float baseAngle = std::atan2( dz, dx ); for (int attempt = 0; attempt < 16; attempt++) { float angle = baseAngle + PI + attempt * 0.4f; Vector3 newPosition = { playerPosition.x + std::cos(angle) * oldDistance, 1.0f, playerPosition.z + std::sin(angle) * oldDistance }; if (!IsSolidAt(newPosition, 0.45f)) { enemyPosition[index] = newPosition; enemyStunTime[index] = 0.0f; enemySpin[index] = 0.0f; enemyWalkTime[index] = 0.0f; return; } } } int CheckEnemyHit(Vector3 bulletPosition) { for (int i = 0; i < NPC_COUNT; i++) { float hitX = bulletPosition.x - enemyPosition[i].x; float hitY = bulletPosition.y - 1.2f; float hitZ = bulletPosition.z - enemyPosition[i].z; float distance = std::sqrt( hitX * hitX + hitY * hitY + hitZ * hitZ ); if (distance < 0.8f) return i; } return -1; } void DrawEnemy() { for (int i = 0; i < NPC_COUNT; i++) { float legMove = 0.0f; float armMove = 0.0f; if (enemyMoving[i]) { legMove = std::sin(enemyWalkTime[i]) * 0.18f; armMove = std::sin(enemyWalkTime[i]) * 0.25f; } float spinX = 0.0f; float spinZ = 0.0f; if (enemyStunTime[i] > 0.0f) { spinX = std::sin(enemySpin[i]) * 0.25f; spinZ = std::cos(enemySpin[i]) * 0.25f; } DrawCube( { enemyPosition[i].x - 0.22f + spinX, 0.45f, enemyPosition[i].z + legMove + spinZ }, 0.25f, 0.9f, 0.25f, DARKGRAY ); DrawCube( { enemyPosition[i].x + 0.22f - spinX, 0.45f, enemyPosition[i].z - legMove - spinZ }, 0.25f, 0.9f, 0.25f, DARKGRAY ); DrawCube( { enemyPosition[i].x, 1.25f, enemyPosition[i].z }, 0.8f, 1.0f, 0.45f, BLUE ); DrawSphere( { enemyPosition[i].x + spinX, 2.05f, enemyPosition[i].z + spinZ }, 0.38f, BEIGE ); DrawCube( { enemyPosition[i].x - 0.55f + spinX, 1.25f + armMove, enemyPosition[i].z + spinZ }, 0.18f, 0.75f, 0.18f, BLUE ); DrawCube( { enemyPosition[i].x + 0.55f - spinX, 1.25f - armMove, enemyPosition[i].z - spinZ }, 0.18f, 0.75f, 0.18f, BLUE ); } }