#include "AITest.h" #include <random> //#include <BotEngine.h> //#include <BasicEntity.h> #include "Attacks/TestProjectile.h" #include "Goals/Goal.h" #include "SteeringBehaviours.h" GameWorld* AITest::world; glm::vec3 AITest::mouseTarget(0.0); void AITest::drawTarget() { // grey target glColor3f(0.5, 0.5, 0.5); glBegin(GL_LINE_LOOP); glVertex3d(mouseTarget.x + 0.2, mouseTarget.y, mouseTarget.z); glVertex3d(mouseTarget.x - 0.2, mouseTarget.y, mouseTarget.z); glEnd(); glBegin(GL_LINE_LOOP); glVertex3d(mouseTarget.x, mouseTarget.y, mouseTarget.z + 0.2); glVertex3d(mouseTarget.x, mouseTarget.y, mouseTarget.z - 0.2); glEnd(); } void AITest::loadPlayer(int health) { auto playerBot = new Vehicle((AITest::world), glm::vec2(28.0, 28.0), glm::vec2(0.01, 0.01), 0.2f, glm::vec2(1.0, 0.0), glm::vec2(0.01f, 0.0f), 0.1f, 2.5f, 1.0f, 1.0f, health); playerBot->takePossession(); world->m_Vehicles.push_back(playerBot); } void AITest::loadBots(float spawnPercent, int seed) { auto& rooms = world->currentLevel.getRooms(); bool spawn{true}; for (std::size_t i = 0; i < world->currentLevel.getNumOfRooms(); ++i) { if (spawn) { spawn = false; continue; } auto& room = rooms[i]; // percent of a rooms area auto numberOfBots = (std::size_t)((room.max.x - room.min.x) * (room.max.y - room.min.y) * spawnPercent); for (std::size_t j = 0; j < numberOfBots; ++j) { auto bot = new Vehicle((AITest::world), world->currentLevel.getRandomSpawn(room, seed++), glm::vec2(0.01, 0.01), 0.2f, glm::vec2(1.0, 0.0), glm::vec2(0.01f, 0.0f), 0.1f, 2.5f, 1.0f, 0.1f, 100); world->m_Vehicles.push_back(bot); } } } void AITest::setAllBehaviours(int behaviour) { switch (behaviour) { case 1: { if (world->m_Vehicles.front()->getSteering()->isArriveOn()) { world->m_Vehicles.front()->getSteering()->ArriveOff(); std::cout << "ArriveOff" << std::endl; } else { world->m_Vehicles.front()->getSteering()->ArriveOn(); std::cout << "ArriveOn" << std::endl; } break; } case 2: { if (world->m_Vehicles.front()->getSteering()->isSeekOn()) { world->m_Vehicles.front()->getSteering()->SeekOff(); std::cout << "SeekOff" << std::endl; } else { world->m_Vehicles.front()->getSteering()->SeekOn(); std::cout << "SeekOn" << std::endl; } break; } case 3: { std::cout << "size of vehicles vec = " << world->m_Vehicles.size() << std::endl; for (auto vehicle : world->m_Vehicles) { if (vehicle->getSteering()->isWallAvoidanceOn()) { vehicle->getSteering()->WallAvoidanceOff(); std::cout << "WallAvoidanceOff" << std::endl; } else { vehicle->getSteering()->WallAvoidanceOn(); std::cout << "WallAvoidanceOn" << std::endl; } } break; } case 4: { for (auto vehicle : world->m_Vehicles) { if (vehicle->getSteering()->isObstacleAvoidanceOn()) { vehicle->getSteering()->ObstacleAvoidanceOff(); std::cout << "ObstacleAvoidanceOff" << std::endl; } else { vehicle->getSteering()->ObstacleAvoidanceOn(); std::cout << "ObstacleAvoidanceOn" << std::endl; } } break; } case 5: { for (auto vehicle : world->m_Vehicles) { if (vehicle->getSteering()->isWanderOn()) { vehicle->getSteering()->WanderOff(); std::cout << "WanderOff" << std::endl; } else { vehicle->getSteering()->WanderOn(); std::cout << "WanderOn" << std::endl; } } break; } default: break; } } void AITest::spawnDefaultBot() { if (!world->currentLevel.getRooms().empty()) { auto bot = new Vehicle((AITest::world), world->currentLevel.getRandomSpawn(), glm::vec2(0.01, 0.01), 0.2f, glm::vec2(1.0, 0.0), glm::vec2(0.01f, 0.0f), 0.1f, 2.5f, 1.0f, 0.1f, 100); world->m_Vehicles.push_back(bot); } } void AITest::loadObstacles() { glm::vec3 scale(0.15f); glm::vec2 posOne(0.333f, 0.333f); glm::vec2 posTwo(0.666f, 0.666f); } void AITest::botEngineInit() { // addWalls(); // loadBots(); // loadObstacles(); } void AITest::Init(GameWorld* GW) { glPushAttrib(GL_CURRENT_BIT); world = GW; // botEngineInit(); glLineWidth(5.0); glPopAttrib(); } void AITest::drawWalls() { glLineWidth(50.0); glColor3f(1.0, 1.0, 1.0); for (auto& wall : world->currentLevel.getAllWalls()) { glPushMatrix(); glBegin(GL_LINE_LOOP); glVertex3f(wall.getOriginPoint().x, 1.0f, wall.getOriginPoint().y); glVertex3f(wall.getEndPoint().x, 1.0f, wall.getEndPoint().y); glEnd(); glBegin(GL_LINE); glVertex3f(wall.getCentre().x, 1.0f, wall.getCentre().y); glVertex3f(wall.getCentre().x + wall.getNormal().x, 0.2f, wall.getCentre().y + wall.getNormal().y); glEnd(); glPopMatrix(); } glColor3f(1.0, 0.0, 0.0); for (auto& intersections : world->currentLevel.debugIntersections) { glPushMatrix(); glTranslatef(intersections.x, 1.0f, intersections.y); glRotated(90, 1.0, 0.0, 0.0); drawCircle(0.0f, 0.0f, 0.5f, 16); glPopMatrix(); } } // copied from stackoverflow void AITest::drawCircle(float cx, float cy, float r, int num_segments) { glBegin(GL_LINE_LOOP); for (int ii = 0; ii < num_segments; ii++) { float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments); // get the current angle float x = r * cosf(theta); // calculate the x component float y = r * sinf(theta); // calculate the y component glVertex2f(x + cx, y + cy); // output vertex } glEnd(); } void AITest::drawCylinder(float halfLength, float radius, int slices) { for (int i = 0; i < slices; i++) { auto theta = (float)((float)i * 2.0f * M_PI); auto nextTheta = (float)(((float)i + 1.f) * 2.0f * M_PI); glBegin(GL_TRIANGLE_STRIP); /*vertex at middle of end */ glVertex3f(0.0f, halfLength, 0.0f); /*vertices at edges of circle*/ glVertex3f(radius * cos(theta), halfLength, radius * sin(theta)); glVertex3f(radius * cos(nextTheta), halfLength, radius * sin(nextTheta)); /* the same vertices at the bottom of the cylinder*/ glVertex3f(radius * cos(nextTheta), -halfLength, radius * sin(nextTheta)); glVertex3f(radius * cos(theta), -halfLength, radius * sin(theta)); glVertex3f(0.0f, -halfLength, 0.0f); glEnd(); } } void AITest::setTarget(glm::vec3 target) { // cast vec3 to dvec3? mouseTarget = target; glm::vec2 xyTarget = glm::vec2(target.x, target.z); world->m_Vehicles.front()->getSteering()->setTarget(xyTarget); } void AITest::shootTarget(glm::vec3 target) { // cast vec3 to dvec3? // fireWeapon glm::vec2 xyTarget = glm::vec2(target.x, target.z); world->m_Vehicles.front()->fireWeapon(xyTarget); /* glm::vec2 xyTarget = glm::vec2(target.x, target.z); TestProjectile* bolt = new TestProjectile(world->m_Vehicles.front(), xyTarget); world->m_Projectiles.push_back(bolt); */ } void AITest::drawOrigin() { glPushMatrix(); glColor3f(1.0, 1.0, 1.0); glTranslated(0.0, 0.0, 0.0); glRotated(90, 1.0, 0.0, 0.0); drawCircle(0.0f, 0.0f, 0.1f, 16); glPopMatrix(); } void AITest::drawPlayer() { glPushMatrix(); // world->player. glm::vec3 pos = glm::vec3(world->player->getPosition().x, 0.0, world->player->getPosition().y); glm::vec3 scaledHeading = glm::vec3(world->player->getHeadingVec().x, 0.0, world->player->getHeadingVec().y); scaledHeading *= glm::vec3(0.2f); glColor3f(0.0, 1.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3d(pos.x, pos.y, pos.z); glVertex3d(scaledHeading.x + pos.x, scaledHeading.y + pos.y, scaledHeading.z + pos.z); glEnd(); glRotated(90, 1.0, 0.0, 0.0); drawCircle(world->player->getPosition().x, world->player->getPosition().y, world->player->getBoundingRadius(), 16); glPopMatrix(); } void AITest::setBotColour(int goal) { switch (goal) { case 11: // wander glColor3f(0.0f, 1.0f, 0.0f); break; case 13: // attack target glColor3f(1.0f, 0.0f, 0.0f); break; case 14: // hunt target glColor3f(1.0f, 0.647f, 0.0f); break; case 15: // strafe target glColor3f(1.0f, 0.412f, 0.0f); break; default: // hunt target glColor3f(0.0f, 0.0f, 1.0f); break; } } void AITest::drawBots() { for (auto& bot : world->m_Vehicles) { glPushMatrix(); glTranslatef(0, 0.1f, 0); glColor3f(0.0f, 0.0f, 1.0f); // draw feelers glBegin(GL_LINE_LOOP); glVertex3d(bot->getPosition().x, 0.0f, bot->getPosition().y); glVertex3d(bot->getSteering()->getFeelers().at(0).x, 0.0f, bot->getSteering()->getFeelers().at(0).y); glEnd(); setBotColour(bot->getBrain()->getType()); glRotated(90, 1.0f, 0.0f, 0.0f); drawCircle(bot->getPosition().x, bot->getPosition().y, bot->getBoundingRadius(), 16); glColor3f(1.0f, 0.0f, 0.0f); drawCircle(bot->getPosition().x, bot->getPosition().y, bot->getSteering()->getDBoxLength(), 16); glPopMatrix(); glColor3f(1.0f, 0.5f, 0.0f); // Orange for (auto& opponents : bot->getSensoryMem()->getListOfRecentlySensedOpponents()) { glm::vec3 oppCentre(opponents->getPosition().x, 0.2f, opponents->getPosition().y); glBegin(GL_LINE_LOOP); glVertex3d(oppCentre.x - 0.5f, oppCentre.y, oppCentre.z - 0.5f); glVertex3d(oppCentre.x - 0.5f, oppCentre.y, oppCentre.z + 0.5f); glVertex3d(oppCentre.x + 0.5f, oppCentre.y, oppCentre.z + 0.5f); glVertex3d(oppCentre.x + 0.5f, oppCentre.y, oppCentre.z - 0.5f); glEnd(); } } } /* glPushAttrib(GL_POLYGON_BIT | GL_LIGHTING_BIT); glDisable(GL_LIGHTING); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); for (auto& debug : m_debugObjects) { debug.draw(); } glPopAttrib();*/ void AITest::drawObstacles() { auto& allObstacles = world->currentLevel.getAllObstacles(); for (auto& obstacle : allObstacles) { glPushMatrix(); if (obstacle->getFlag()) glColor3f(1.0f, 0.0f, 0.0f); else glColor3f(1.0f, 1.0f, 1.0f); glTranslated(obstacle->getPosition().x, 0.0f, obstacle->getPosition().y); glRotated(90, 1.0f, 0.0f, 0.0f); drawCircle(0.0f, 0.0f, obstacle->getBoundingRadius(), 16); glPopMatrix(); } } void AITest::drawProjectiles() { glColor3f(1.0f, 1.0f, 0.0f); for (auto& projectile : world->m_Projectiles) { glPushMatrix(); glTranslated(projectile->getPosition().x, 0.2f, projectile->getPosition().y); glRotated(90, 1.0f, 0.0f, 0.0f); drawCircle(0.0f, 0.0f, 0.005f, 16); glPopMatrix(); } } void AITest::draw() { // std::cout << "redraw" << std::endl; // glClear(GL_COLOR_BUFFER_BIT); // clear window to background color // drawTriangle(); drawWalls(); drawObstacles(); // drawPlayer(); drawBots(); drawTarget(); drawProjectiles(); // glFlush(); } void AITest::drawDebug() { // drawCylinder(5.0f, 1.0, 16); glPushAttrib(GL_POLYGON_BIT | GL_LIGHTING_BIT | GL_CURRENT_BIT); glDisable(GL_LIGHTING); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(20.0f); // drawWalls(); drawTarget3D(); drawObstacles3D(); drawWalls(); drawBots3D(); // drawProjectiles3D(); drawProjectiles(); glPopAttrib(); } void AITest::drawTarget3D() { // purple target // Want to make a thick circle later glColor3f(1.0f, 0.5f, 1.0f); glPushMatrix(); // glLineWidth(20.0); glTranslatef(0, 0.2f, 0); glRotatef(90, 1.0f, 0.0f, 0.0f); drawCircle(mouseTarget.x, mouseTarget.z, 0.5f, 16); glColor3f(1.0f, 0.0f, 0.0f); glPopMatrix(); } void AITest::drawBots3D() { for (auto& bot : world->m_Vehicles) { glPushMatrix(); glTranslatef(0.0f, 0.2f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); // draw feelers if (bot->getSteering()->isWallAvoidanceOn()) { for (auto& feeler : bot->getSteering()->getFeelers()) { glBegin(GL_LINE_LOOP); glVertex3f(bot->getPosition().x, 0.0f, bot->getPosition().y); glVertex3f(feeler.x, 0.0f, feeler.y); glEnd(); } } glColor3f(1.0f, 0.0f, 0.0f); glRotatef(90, 1.0f, 0.0f, 0.0f); if (bot->getSteering()->isObstacleAvoidanceOn()) { drawCircle(bot->getPosition().x, bot->getPosition().y, bot->getSteering()->getDBoxLength(), 16); } glColor3f(0.0f, 0.0f, 1.0f); // setBotColour(bot->m_Goal); drawCircle(bot->getPosition().x, bot->getPosition().y, bot->getBoundingRadius(), 16); glPopMatrix(); glColor3f(1.0f, 0.5f, 0.0f); // Orange for (auto& opponent : bot->getSensoryMem()->getListOfRecentlySensedOpponents()) { glm::vec2 oppPos = bot->getSensoryMem() ->getLastRecordedPositionOfOpponent( opponent); glm::vec3 oppCentre(oppPos.x, 0.2, oppPos.y); glBegin(GL_LINE_LOOP); glVertex3d(oppCentre.x - 0.5f, oppCentre.y, oppCentre.z - 0.5f); glVertex3d(oppCentre.x - 0.5f, oppCentre.y, oppCentre.z + 0.5f); glVertex3d(oppCentre.x + 0.5f, oppCentre.y, oppCentre.z + 0.5f); glVertex3d(oppCentre.x + 0.5f, oppCentre.y, oppCentre.z - 0.5f); glEnd(); } } } void AITest::drawObstacles3D() { auto allObstacles = world->currentLevel.getAllObstacles(); for (auto& obstacle : allObstacles) { glPushMatrix(); if (obstacle->getFlag()) glColor3f(1.0f, 0.0f, 0.0f); else glColor3f(1.0f, 1.0f, 1.0f); glTranslated(obstacle->getPosition().x, 0.2, obstacle->getPosition().y); glRotatef(90, 1.0f, 0.0f, 0.0f); drawCircle(0.0f, 0.0f, obstacle->getBoundingRadius(), 16); glPopMatrix(); } } void AITest::drawProjectiles3D() { glColor3f(1.0f, 1.0f, 1.0f); for (auto& projectile : world->m_Projectiles) { glPushMatrix(); glTranslated(projectile->getPosition().x, 0.0f, projectile->getPosition().y); glRotated(90, 1.0f, 0.0f, 0.0f); drawCircle(0.0f, 0.0f, 0.005f, 16); glPopMatrix(); } }