float Vector2::AngleBetween(Vector2 rhs) const { Vector2 perp = Vector2(rhs.y, -rhs.x); float len1 = GetLength(); float len2 = rhs.GetLength(); float angle = acos(Dot(rhs)); if (rhs.Dot(perp) > 0) return angle; else return -angle; }
GLColorBuffer GLDepthOfFieldFilter::Blur(GLColorBuffer buffer, GLColorBuffer coc, Vector2 offset, int divide) { SPADES_MARK_FUNCTION(); // do gaussian blur GLProgram *program = blurProgram; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = buffer.GetWidth(); int h = buffer.GetHeight(); int w2 = w / divide; int h2 = h / divide; static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform("texture"); static GLProgramUniform blur_cocUniform("cocTexture"); static GLProgramUniform blur_offset("offset"); program->Use(); blur_positionAttribute(program); blur_textureUniform(program); blur_cocUniform(program); blur_offset(program); blur_cocUniform.SetValue(1); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, coc.GetTexture()); blur_textureUniform.SetValue(0); dev->ActiveTexture(0); qr.SetCoordAttributeIndex(blur_positionAttribute()); // x-direction float len = offset.GetLength(); float sX = 1.f / (float)w, sY = 1.f / (float)h; while(len > .5f){ GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w2, h2, false); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); dev->BindTexture(IGLDevice::Texture2D, buffer.GetTexture()); blur_offset.SetValue(offset.x * sX, offset.y * sY); qr.Draw(); buffer = buf2; offset *= .125f; len *= .125f; } return buffer; }
bool UpdateGame(void) { Matrix2 orientation(gameShip.m_orientation); Vector2 gravity(0.0f,-0.004f); //gameShip.AddBodyForce(gravity); float k = 0.001f; if(debugSpring1) { Vector2 force = gameSpring1 - (gameShip.m_position + orientation * gameAnchor1); gameShip.AddBodyForce(force * k,gameShip.m_position + orientation * gameAnchor1); } if(debugSpring2) { Vector2 force = gameSpring2 - (gameShip.m_position + orientation * gameAnchor2); gameShip.AddBodyForce(force * k,gameShip.m_position + orientation * gameAnchor2); } if(HIWORD(GetAsyncKeyState(VK_LEFT))) { gameShip.m_rearEngineOrientation += GetElapsedTime() / 50.0f; gameShip.m_frontEngineOrientation += GetElapsedTime() / 50.0f; } if(HIWORD(GetAsyncKeyState(VK_RIGHT))) { gameShip.m_rearEngineOrientation -= GetElapsedTime() / 50.0f; gameShip.m_frontEngineOrientation -= GetElapsedTime() / 50.0f; } if(HIWORD(GetAsyncKeyState('B'))) { gameShip.m_mainEngineOrientation += GetElapsedTime() / 50.0f; } if(HIWORD(GetAsyncKeyState('N'))) { gameShip.m_mainEngineOrientation -= GetElapsedTime() / 50.0f; } if(HIWORD(GetAsyncKeyState(VK_UP))) { Matrix2 rotation(gameShip.m_frontEngineOrientation + gameShip.m_orientation); gameShip.AddBodyForce(rotation * Vector2(0.0f,0.002f),gameShip.m_position + orientation * gameShip.m_frontEnginePosition); gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_frontEnginePosition); } if(HIWORD(GetAsyncKeyState(VK_SPACE))) { Matrix2 rotation(gameShip.m_mainEngineOrientation + gameShip.m_orientation); gameShip.AddBodyForce(rotation * Vector2(0.0f,0.004f),gameShip.m_position + orientation * gameShip.m_mainEnginePosition); gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_mainEnginePosition); gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_mainEnginePosition); } if(HIWORD(GetAsyncKeyState(VK_UP))) { Matrix2 rotation(gameShip.m_rearEngineOrientation + gameShip.m_orientation); gameShip.AddBodyForce(rotation * Vector2(0.0f,0.001f),gameShip.m_position + orientation * gameShip.m_rearEnginePosition); gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_rearEnginePosition); } gameShip.UpdateBody(); gameEmitter.UpdateParticles(); for(unsigned long i = 0; i < gameMissles.GetSize(); ++i) { Matrix2 orientation(gameMissles[i]->m_orientation); gameMissles[i]->AddBodyForce(gravity); Vector2 target = Matrix2(-gameMissles[i]->m_orientation) * (gameMissles[i]->m_target - gameMissles[i]->m_position); bool left = false,right = false; if(gameMissles[i]->m_life > 50.0f) { if(target.x > -0.1f && target.x < 0.1f && target.y > 0) left = right = true; else if(target.x < 0) right = true; else left = true; } if(left) { gameMissles[i]->AddBodyForce(orientation * Vector2(0.0f,0.008f),gameMissles[i]->m_position + orientation * gameMissles[i]->m_engines[0]); gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[0]); gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[0]); } if(right) { gameMissles[i]->AddBodyForce(orientation * Vector2(0.0f,0.008f),gameMissles[i]->m_position + orientation * gameMissles[i]->m_engines[1]); gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[1]); gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[1]); } gameMissles[i]->UpdateBody(); gameMissles[i]->m_life += GetElapsedTime(); if(gameMissles[i]->m_spring) { Vector2 force = *gameMissles[i]->m_spring - gameMissles[i]->m_position; gameMissles[i]->AddBodyForce(force * k); } if(gameMissles[i]->m_life > 1500.0f || target.GetLength() < 0.4f) { for(unsigned long j = 0; j < 256; ++j) gameEmitter.AddParticle(Vector2Normalize(Vector2(randf(),randf())) * randf() / 6.0f,gameMissles[i]->m_position); delete gameMissles[i]; gameMissles.Erase(i); --i; } } return true; }
bool AIDeerBehavior::Update( float dt ) { if ( Behavior::Update(dt) ) return true; DeerActor* dActor = dynamic_cast<DeerActor*>(this->zActor); //static float testInterval = 0; //Just for debugging. //testInterval += dt; this->zIntervalCounter += dt; //this->zIntervalCounter += dt; this->zFearIntervalCounter += dt; //this->zAlertnessIntervalCounter += deltaTime; int nrOfPredators = 0; bool nearbyPredatorsExist = false; //Perform checking for entities here. float shortestDistance = 99999; float finalDistance = 0; int maximumNodesTest = 5; //Determine closest threat/target //std::set<Actor*> aSet = this->GetTargets(); for(auto i = this->zNearDynamicActors.cbegin(); i != this->zNearDynamicActors.cend(); i++)//for(auto i = aSet.cbegin(); i != aSet.cend(); i++) { finalDistance = (dActor->GetPosition().GetXZ() - (*i)->GetPosition().GetXZ()).GetLength(); if( finalDistance < this->zMinimumDistance && !dynamic_cast<DeerActor*>((*i)) && dynamic_cast<BioActor*>((*i)) && dynamic_cast<BioActor*>((*i))->IsAlive() ) { dynamic_cast<BioActor*>(*i)->zValid = true; if(finalDistance < shortestDistance) { shortestDistance = finalDistance; this->zMainActorTarget = (*i); //Decide which is the biggest threat here, i.e. the main target. For the moment, proximity is the deciding factor. Could use some more complexity. } nrOfPredators++; } else if( BioActor* bioActor = dynamic_cast<BioActor*>(*i) ) { bioActor->zValid = false; } } //for(int i = 0; i < this->GetCurrentTargets(); i++) //{ // xDistance = dActor->GetPosition().x - this->zTargets[i].position.x; //Math, could use optimization, I think. // //yDistance = this->GetPosition().y - this->zTargets[i].position.y; // zDistance = dActor->GetPosition().z - this->zTargets[i].position.z; // finalDistance = sqrt(xDistance * xDistance + zDistance * zDistance); // if( finalDistance < this->zMinimumDistance && this->zTargets[i].kind != DEER) // { // this->zTargets[i].valid = true; // if(finalDistance < shortestDistance) // { // shortestDistance = finalDistance; // this->zMainTarget = this->zTargets[i]; //Decide which is the biggest threat here, i.e. the main target. For the moment, proximity is the deciding factor. Could use some more complexity. // } // nrOfPredators++; // } // else // { // this->zTargets[i].valid = false; // } //} if(nrOfPredators > 0) { nearbyPredatorsExist = true; } else { nearbyPredatorsExist = false; } //Time to assess threats. if( dActor->GetHealth() < this->GetPreviousHealth() ) //In theory, used to check if the animal has been attacked. { this->SetFearLevel( this->GetFearLevel() + this->zFearAtDamageDone); } this->SetPreviousHealth( dActor->GetHealth() ); if(this->zFearIntervalCounter > this->zFearInterval) //Basically, each amount of fearinterval seconds the fear increases or decreases. { this->zFearIntervalCounter = 0; if(nearbyPredatorsExist) { //Getting values and such, comparing animal health against that of other entities, types and more. //calculate current fear level: float fear = 0; //- for each dangerous entity detected, add some fear, fear could be based on type. Deers are afraid of humans for example. fear += this->zExtraFearWithNumberOfPlayers * nrOfPredators; if(shortestDistance < this->zTooCloseInDistance) //The target is too close. Could expand this to incorporate more than one target. { fear += zExtraFearWithCloseProximity; } //std::set<Actor*> aSet = this->GetTargets(); for(auto i = this->zNearDynamicActors.cbegin(); i != this->zNearDynamicActors.cend(); i++)//for(auto i = aSet.cbegin(); i != aSet.cend(); i++) { if(dynamic_cast<BioActor*>((*i))) { if(dynamic_cast<BioActor*>((*i))->zValid == true) { //Do a mathematical check, see if anyone is right in front of the deer. But... how? http://www.youtube.com/watch?v=gENVB6tjq_M Vector3 actorPosition = dActor->GetPosition(); float dotProduct = dActor->GetDir().GetDotProduct( (*i)->GetPosition() - actorPosition ); if(dotProduct > this->zFieldOfView)//This sight is relatively wide, since it is a deer. If this is true, then the deer sees a player. { //Which means, it is even more afraid. fear += zExtraFearAtSight; } if(dynamic_cast<BioActor*>((*i))->GetVelocity() > this->zThreatMovementSpeedThreshold) { fear += this->zExtraFearAtThreatMovementSpeed; } if(dynamic_cast<BioActor*>((*i))->GetHealth() != 0) // No dbz here! { fear -= (dActor->GetHealth() / dynamic_cast<BioActor*>((*i))->GetHealth()) / nrOfPredators; //If the animal is faced with a very weak player(s), it gets some confidence. This is reduced with each player present. } } } } this->SetFearLevel( this->GetFearLevel() + fear * this->zConfidenceKoef); //5 is unrelated to the movementNoise. Probably not good enough math. The theory is that the animal is constantly getting more afraid. } else //No threat detected. Calming down. { this->SetFearLevel( this->GetFearLevel() - this->zFearDecrease); } } //Change state of mind. if(this->GetFearLevel() == 0.0f && !nearbyPredatorsExist) { this->SetMentalState(CALM); //this->SetScale(Vector3(0.01f, 0.01f, 0.01f)); } else if(this->GetFearLevel() > 0.0f && this->GetFearLevel() <= this->zSupspiciousToAggressiveThreshold) { this->SetMentalState(SUSPICIOUS); //this->SetScale(Vector3(0.03f, 0.03f, 0.03f)); } else if(this->GetFearLevel() > this->zSupspiciousToAggressiveThreshold && this->GetFearLevel() <= zAggressiveToAfraidThreshold && nearbyPredatorsExist) { if(this->GetMentalState() != AGGRESSIVE) { this->zCurrentPath.clear(); this->SetIfNeedPath(true); this->SetMentalState(AGGRESSIVE); //this->SetScale(Vector3(0.05f, 0.05f, 0.05f)); } } else if(this->GetFearLevel() > zAggressiveToAfraidThreshold && this->GetFearLevel() <= this->GetFearMax()) { if(this->GetMentalState() != AFRAID) { this->zCurrentPath.clear(); this->SetIfNeedPath(true); this->SetMentalState(AFRAID); //this->SetScale(Vector3(3.09f, 3.09f, 3.09f)); } } else { this->SetMentalState(SUSPICIOUS); } //Act based on state of mind. if(this->GetMentalState() == CALM) //Relaxed behaviour. No threat detected. { this->zCurrentDistanceFled = 0; this->zPanic = false; if(this->zIntervalCounter > this->zCalmActionInterval && this->GetIfNeedPath()) { this->zIntervalCounter = 0; srand((unsigned int)time(0)); this->zCalmActionInterval = (float)(rand() % this->zCalmRandomInterval + this->zCalmRandomAddition); this->zCurrentPath.clear(); //Since a new path is gotten, and the old one might not have been completed, we clear it just in case. //this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, this->GetPosition().x + rand() % 14 - 7, this->GetPosition().z + rand() % 14 - 7, this->zCurrentPath, 20); //Get a small path to walk, short and does not have to lead anywhere. this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, dActor->GetPosition().x + rand() % zDistanceToWalkWhenCalm - zDistanceToWalkWhenCalm/2, dActor->GetPosition().z + rand() % zDistanceToWalkWhenCalm - zDistanceToWalkWhenCalm/2, this->zCurrentPath, maximumNodesTest); this->SetIfNeedPath(false); } } else if(this->GetMentalState() == SUSPICIOUS) //Might have heard something, is suspicious. { this->zCurrentDistanceFled = 0; this->zPanic = false; if(this->zIntervalCounter > this->zCalmActionInterval && this->GetIfNeedPath()) //The increase in time is supposed to represent listening, waiting for something to happen. { this->zIntervalCounter = 0; srand((unsigned int)time(0)); this->zCalmActionInterval = (float)(rand() % this->zSupsiciousRandomInterval + this->zSupsiciousAddition); this->zCurrentPath.clear(); //this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, this->GetPosition().x + rand() % 8 - 4, this->GetPosition().z + rand() % 8 - 4, this->zCurrentPath, 20); //Get a small path to walk, quite short (since the animal is nervous) and does not have to lead anywhere. this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, dActor->GetPosition().x + rand() % zDistanceToWalkWhenSuspicious - zDistanceToWalkWhenSuspicious/2, dActor->GetPosition().z + rand() % zDistanceToWalkWhenSuspicious - zDistanceToWalkWhenSuspicious/2, this->zCurrentPath, maximumNodesTest); this->SetIfNeedPath(false); } } else if(this->GetMentalState() == AGGRESSIVE) //Is outright trying to harm the target. { this->zCurrentDistanceFled = 0; this->zPanic = false; float lastDistance = (dActor->GetPosition().GetXZ() - this->zMainActorTarget->GetPosition().GetXZ()).GetLength(); if( this->GetIfNeedPath() == true ) { this->SetIfNeedPath(false); this->zCurrentPath.clear(); if( !this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, this->zMainActorTarget->GetPosition().x, this->zMainActorTarget->GetPosition().z, this->zCurrentPath, maximumNodesTest) == false ) //Get the path, with the target that is to be attacked as the goal position. Depending on the animal, make the distance slightly large. //!this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, this->zMainTarget.position.x, this->zMainTarget.position.z, this->zCurrentPath, 40) == false { this->SetIfNeedPath(true); } this->SetLastDistanceCheck( lastDistance ); } if( this->zIntervalCounter > 1.5 && this->GetIfNeedPath() == false ) { this->zIntervalCounter = 0; if( lastDistance < this->GetLastDistanceCheck() / 2) // The animal has traveled towards its goal halfway, at this point, it is safe to asume the goal has moved. { this->zCurrentPath.clear(); this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, this->zMainActorTarget->GetPosition().x, this->zMainActorTarget->GetPosition().z, this->zCurrentPath, maximumNodesTest); //this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, this->zMainTarget.position.x, this->zMainTarget.position.z, this->zCurrentPath, 40); } float distance; float shortestDistance = 99999; Actor* mostLikelyTarget = this->zMainActorTarget; //std::set<Actor*> aSet = this->GetTargets(); for(auto i = this->zNearDynamicActors.cbegin(); i != this->zNearDynamicActors.cend(); i++)//for(auto i = aSet.cbegin(); i != aSet.cend(); i++) { if(dynamic_cast<BioActor*>((*i))) { if(dynamic_cast<BioActor*>((*i))->zValid == true) { distance = (dActor->GetPosition().GetXZ() - (*i)->GetPosition().GetXZ()).GetLength(); if(distance < shortestDistance) //Something that is a larger threat is based on distance. { shortestDistance = distance; mostLikelyTarget = (*i); } } } } if(shortestDistance < this->GetLastDistanceCheck() / this->zNewTargetCloseByAFactorOf) // The animal has gotten closer to a larger threat, and is now following that target instead. { this->SetIfNeedPath(true); this->zMainActorTarget = mostLikelyTarget; } } } else if(this->GetMentalState() == AFRAID) //Is afraid, need to run. { //if( this->zIntervalCounter > 1.5 && this->GetIfNeedPath() == false ) if(this->GetIfNeedPath() == true) { this->SetIfNeedPath(false); if(nearbyPredatorsExist && this->zIntervalCounter > 2.5) { this->zIntervalCounter = 0.0f; this->zDestination = this->ExaminePathfindingArea(); //this->zCurrentPath.clear(); //if(!this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, this->zDestination.x, this->zDestination.z,this->zCurrentPath, maximumNodesTest) ) //!this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, awayFromThreatX, awayFromThreatZ,this->zCurrentPath,80) //{ // this->SetIfNeedPath(true); //} } else if(this->zPanic == true) { //Get random direction and run there. float awayFromThreatX; float awayFromThreatZ; int directionX = rand() % 2; int directionZ = rand() % 2; if(directionX == 0) { awayFromThreatX = dActor->GetPosition().x + this->zFleeDistance; } else { awayFromThreatX = dActor->GetPosition().x - this->zFleeDistance; } if(directionZ == 0) { awayFromThreatZ = dActor->GetPosition().z + this->zFleeDistance; } else { awayFromThreatZ = dActor->GetPosition().z - this->zFleeDistance; } this->zDestination.x = awayFromThreatX; this->zDestination.z = awayFromThreatZ; //this->zCurrentPath.clear(); //if( !this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, awayFromThreatX, awayFromThreatZ,this->zCurrentPath, maximumNodesTest) ) //!this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, awayFromThreatX, awayFromThreatZ,this->zCurrentPath,80) //{ // this->SetIfNeedPath(true); //} } else //It has started to run, but still need to go further. { Vector3 direction = dActor->GetDir(); direction.Normalize(); this->zDestination.x += ( direction.x * this->zFleeDistance ); this->zDestination.z += ( direction.z * this->zFleeDistance ); //this->zCurrentPath.clear(); //if( !this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, this->zDestination.x, this->zDestination.z,this->zCurrentPath, maximumNodesTest) ) //!this->zPathfinder.Pathfinding(this->GetPosition().z, this->GetPosition().x, awayFromThreatX, awayFromThreatZ,this->zCurrentPath,80) //{ // this->SetIfNeedPath(true); //} } } else//It is already running. { //one or more entities should not collide with each other and stop. (I am not sure this is something to be handled here or elsewhere. } } //Move the animal along path. this->zPreviousVelocity = dActor->GetVelocity(); Vector3 oldPos = dActor->GetPosition(); this->zPanic = false; //this->zPreviousPos = this->GetPosition(); if(this->GetMentalState() == CALM && this->zCurrentPath.size() > 0 || this->GetMentalState() == SUSPICIOUS && this->zCurrentPath.size() > 0) { bool reachedNode = false; if( (dActor->GetPosition().x > this->zCurrentPath.back().x - 0.2 && dActor->GetPosition().x < this->zCurrentPath.back().x + 0.2) && ( dActor->GetPosition().z > this->zCurrentPath.back().y - 0.2 && dActor->GetPosition().z < this->zCurrentPath.back().y + 0.2 ) ) { reachedNode = true; } if(reachedNode) { this->zCurrentPath.pop_back(); //reachedNode = false; } /*double result = atan2( (this->zCurrentPath.back().y - this->GetPosition().z), (this->zCurrentPath.back().x - this->GetPosition().x) ); result = result; this->SetDirection( Vector3( cos(result), 0.0f, sin(result) )); */ if(this->zCurrentPath.size() > 0) { Vector3 goal(this->zCurrentPath.back().x, 0, this->zCurrentPath.back().y); Vector3 direction = goal - dActor->GetPosition(); direction.Normalize(); dActor->SetDir( direction ); Vector2 testProperDirection; testProperDirection.x = dActor->GetDir().x; testProperDirection.y = dActor->GetDir().z; testProperDirection.Normalize(); dActor->SetDir(Vector3(testProperDirection.x, 0.0f, testProperDirection.y)); } /*if(dActor->GetVelocity() > this->zWalkingVelocity) { dActor->SetVelocity(this->zPreviousVelocity - 100 * dt); } else if(dActor->GetVelocity() < this->zWalkingVelocity) { dActor->SetVelocity(this->zPreviousVelocity + 100 * dt); }*/ dActor->SetVelocity(this->zWalkingVelocity); //if(testInterval > 2.0) //Mainly for testing purposes. //{ // testInterval = 0; // dActor->SetPosition(Vector3(this->zCurrentPath.back().x, 0, this->zCurrentPath.back().y) ); //} dynamic_cast<BioActor*>(this->GetActor())->SetState(STATE_WALKING); dActor->SetPosition(dActor->GetPosition() + dActor->GetDir() * dt * dActor->GetVelocity()); } else if(this->GetMentalState() == AGGRESSIVE && this->zCurrentPath.size() > 0) { bool reachedNode = false; if( (dActor->GetPosition().x > this->zCurrentPath.back().x - 0.2 && dActor->GetPosition().x < this->zCurrentPath.back().x + 0.2) && ( dActor->GetPosition().z > this->zCurrentPath.back().y - 0.2 && dActor->GetPosition().z < this->zCurrentPath.back().y + 0.2 ) ) { reachedNode = true; } if(reachedNode) { this->zCurrentPath.pop_back(); //reachedNode = false; } /*double result = atan2( (this->zCurrentPath.back().y - this->GetPosition().z), (this->zCurrentPath.back().x - this->GetPosition().x) ); result = result; this->SetDirection( Vector3( cos(result), 0.0f, sin(result) )); */ if(this->zCurrentPath.size() > 0) { Vector3 goal(this->zCurrentPath.back().x, 0, this->zCurrentPath.back().y); Vector3 direction = goal - dActor->GetPosition(); direction.Normalize(); dActor->SetDir( direction ); Vector2 testProperDirection; testProperDirection.x = dActor->GetDir().x; testProperDirection.y = dActor->GetDir().z; if(testProperDirection.GetLength() > 0.0f) { testProperDirection.Normalize(); } dActor->SetDir(Vector3(testProperDirection.x, 0.0f, testProperDirection.y)); } /* if(dActor->GetVelocity() > this->zAttackingVelocity) { dActor->SetVelocity(this->zPreviousVelocity - 100 * dt); } else if(dActor->GetVelocity() < this->zAttackingVelocity) { dActor->SetVelocity(this->zPreviousVelocity + 100 * dt); }*/ dActor->SetVelocity(this->zAttackingVelocity); dynamic_cast<BioActor*>(this->GetActor())->SetState(STATE_RUNNING); dActor->SetPosition(dActor->GetPosition() + dActor->GetDir() * dt * dActor->GetVelocity()); } else if(this->GetMentalState() == AFRAID /*&& this->zCurrentPath.size() > 0*/) { /*double result = atan2( (this->zCurrentPath.back().y - this->GetPosition().z), (this->zCurrentPath.back().x - this->GetPosition().x) ); result = result; this->SetDirection( Vector3( cos(result), 0.0f, sin(result) )); */ dynamic_cast<BioActor*>(this->GetActor())->SetState(STATE_RUNNING); //Vector3 goal(this->zCurrentPath.back().x, 0, this->zCurrentPath.back().y); //Vector3 direction = goal - dActor->GetPosition(); if(this->zCurrentPath.size() > 0) { bool reachedNode = false; if( (dActor->GetPosition().x > this->zCurrentPath.back().x - 0.2 && dActor->GetPosition().x < this->zCurrentPath.back().x + 0.2) && ( dActor->GetPosition().z > this->zCurrentPath.back().y - 0.2 && dActor->GetPosition().z < this->zCurrentPath.back().y + 0.2 ) ) { reachedNode = true; } if(reachedNode) { this->zCurrentPath.pop_back(); //reachedNode = false; } } if(this->zCurrentPath.size() > 0) { Vector3 goal(this->zCurrentPath.back().x, 0, this->zCurrentPath.back().y); Vector3 direction = goal - dActor->GetPosition(); direction.Normalize(); dActor->SetDir( direction ); } else { Vector3 direction = this->zDestination - dActor->GetPosition(); direction.Normalize(); dActor->SetDir( direction ); } dActor->SetVelocity(this->zFleeingVelocity); Vector3 nextPos = dActor->GetPosition() + dActor->GetDir() * dt * dActor->GetVelocity(); if(!this->zWorld->IsBlockingAt(Vector2(nextPos.x,nextPos.z)) && this->zCurrentPath.size() == 0) { Vector2 testProperDirection; testProperDirection.x = dActor->GetDir().x; testProperDirection.y = dActor->GetDir().z; testProperDirection.Normalize(); dActor->SetDir(Vector3(testProperDirection.x, 0.0f, testProperDirection.y)); dynamic_cast<BioActor*>(this->GetActor())->SetState(STATE_RUNNING); dActor->SetPosition(dActor->GetPosition() + dActor->GetDir() * dt * dActor->GetVelocity()); this->zCurrentDistanceFled += dt * dActor->GetVelocity(); } else if(this->zCurrentPath.size() > 0) { Vector2 testProperDirection; testProperDirection.x = dActor->GetDir().x; testProperDirection.y = dActor->GetDir().z; testProperDirection.Normalize(); dActor->SetDir(Vector3(testProperDirection.x, 0.0f, testProperDirection.y)); dynamic_cast<BioActor*>(this->GetActor())->SetState(STATE_RUNNING); dActor->SetPosition(dActor->GetPosition() + dActor->GetDir() * dt * dActor->GetVelocity()); this->zCurrentDistanceFled += dt * dActor->GetVelocity(); } else if(this->zCurrentPath.size() == 0) { this->zCurrentPath.clear(); this->zPathfinder.Pathfinding(dActor->GetPosition().x, dActor->GetPosition().z, dActor->GetPosition().x + dActor->GetDir().x * 5.0f, dActor->GetPosition().z + dActor->GetDir().z * 5.0f, this->zCurrentPath, 40); //dActor->SetPosition(Vector3(50,0,50)); } } if(this->GetMentalState() == AFRAID && this->zCurrentDistanceFled < this->zFleeDistance) { this->SetIfNeedPath(true); } else { this->SetIfNeedPath(true); } float groundHeight = 0.0f; try { groundHeight = this->zWorld->CalcHeightAtWorldPos( Vector2(dActor->GetPosition().x, dActor->GetPosition().z)); } catch(...) { } Vector3 actorPosition = dActor->GetPosition(); Vector3 currentPos = actorPosition; actorPosition.y = groundHeight; dActor->SetPosition(actorPosition); if(oldPos == currentPos) { dynamic_cast<BioActor*>(this->GetActor())->SetState(STATE_IDLE); } //Rotate Animal static Vector3 defaultMeshDir = Vector3(0.0f, 0.0f, 1.0f); Vector3 meshDirection = dActor->GetDir(); meshDirection.y = 0; meshDirection.Normalize(); Vector3 around = Vector3(0.0f, 1.0f, 0.0f); float angle = -acos(meshDirection.GetDotProduct(defaultMeshDir)); if (meshDirection.x > 0.0f) angle *= -1; dActor->SetRotation(Vector4(0.0f, 0.0f, 0.0f, 1.0f)); dActor->SetRotation(around, angle); return false; }