Exemple #1
0
void CharacterController::UpdateAITarget(const Ogre::Vector3& target, std::shared_ptr< Environment > env, float velocity)
{
	if (target.squaredDistance(_CurrentTarget) > 0.001 || _CurrentPathAge > 0.1)
	{
		//boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
		_CurrentPath = env->QueryPath(GetPosition(), target);
		//boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
		_CurrentPathIndex = 0;
		_CurrentTarget = target;
		_CurrentVelocity = velocity;
		//std::cerr << "Pathfinding in " << (t2-t1).total_microseconds() << " µs\n";
	}
}
void EnemyCharacter::_actionShoot(const std::string& target)
{
	//look at entity target
	LevelData::BaseEntity* entity = LuaManager::getSingleton().getEntity(target);
	//if the target isn't a NPC/Enemy, I don't want my enemy wasting his ammo.
	if(entity->getType() == LevelData::NPC || entity->getType() == LevelData::ENEMY)
	{
		Ogre::Vector3 targetPosition = static_cast<NPCCharacter*>(entity)->getPosition();

		Ogre::Vector3 sourcePosition = _node->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z;
		sourcePosition.y = 0;

		Utility::rotateToTarget(_node,targetPosition,true);

		//after rotation, fire?
		_currentWeapon.weapon->fire();
		_damageInterface->registerShotAtPlayer(_currentWeapon.weapon->getGunshotData(),sourcePosition.squaredDistance(targetPosition));
	}
}
Exemple #3
0
//-------------------------------------------------------------------------------
void Crate::unpausedTick(const Ogre::FrameEvent &evt)
{
    GraLL2GameObject::unpausedTick(evt);

    //If gotta move, move.
    if (mMoving)
    {
        btTransform oldTrans, bodyTrans;
        mFixedBody->getMotionState()->getWorldTransform(oldTrans);
        mBody->getMotionState()->getWorldTransform(bodyTrans);

        Ogre::Real speed = CRATE_MOVE_SPEED * evt.timeSinceLastFrame;
        Ogre::Vector3 currPos = BtOgre::Convert::toOgre(oldTrans.getOrigin());

        if (currPos.squaredDistance(mTarget) < speed*speed)
        {
            //If next move'll take us overboard, just jump to the target.
            mFixedBody->getMotionState()->setWorldTransform(btTransform(oldTrans.getRotation(), BtOgre::Convert::toBullet(mTarget)));
            mMoving = false;
        }
        else
        {
            //Else move toward target.
            btVector3 vel = BtOgre::Convert::toBullet((mTarget - currPos).normalisedCopy() * speed);
            mFixedBody->getMotionState()->setWorldTransform(btTransform(oldTrans.getRotation(), oldTrans.getOrigin() + vel));
        }

        //Update the body itself. Y = Y of body X,Z = X,Z of fixed body.
        mFixedBody->getMotionState()->getWorldTransform(oldTrans);
        mBody->setWorldTransform(btTransform(oldTrans.getRotation(), btVector3(oldTrans.getOrigin().x(), bodyTrans.getOrigin().y(), oldTrans.getOrigin().z())));

        if (!mSound->isPlaying())
            mSound->play();
    }
    else if (mSound->isPlaying())
        mSound->stop();

    //We might fall of.
    checkFell();
    
    //Python utick event.
    NGF_PY_CALL_EVENT(utick, evt.timeSinceLastFrame);
}
Exemple #4
0
// units can be changed to a pointer that has UnitNodes removed when no longer needed.
//  This will use less memory, but is more complicated.
void Game::checkUnitUnit(QuadtreeNode *node, std::vector<UnitNodes> units)
{
    units.insert(units.begin(), node->units.begin(), node->units.end());
    if(node->children)
    {
        for(int i=0; i<4; i++)
        {
            checkUnitUnit(&node->children[i], units);
        }
    }
    // If a QuadtreeNode has no children.
    //   This is a LEAF. All nodes in std::vector units are in a possible collision.
    else
    {
        // Check each unit in units with every other unit in units.
        for(unsigned int i = 0; i<units.size(); i++)
        {
            GAME::UnitNodes *unitsI = &units.at(i);
            // Must be called to clean up the unitController enemy pointers first.
            unitsI->unitController->cleanUpEnemyPointers();
            Ogre::Vector3 ILocation = unitsI->unitController->getPosition();
            ILocation.y = 0;

            float unitsISquaredCombatRadii = float(unitsI->unitController->combatRadii
                                                   * unitsI->unitController->combatRadii);
            float unitsISquaredDetectionRadii = float(unitsI->unitController->detectionRadii
                                                * unitsI->unitController->detectionRadii);

            for(unsigned int j = 0; j<units.size(); j++)
            {
                GAME::UnitNodes *unitsJ = &units.at(j);

                if( i==j || unitsJ->unitController->isHidden() )
                    continue;

                if( !unitsI->unitController->getConfusedBy() &&	unitsI->controller != unitsJ->controller &&
                        unitsJ->unitController->getConfusedBy() != unitsI->controller )
                {
                    // Improves preformance by doing this less often.
                    Ogre::Vector3 JLocation = unitsJ->unitController->getPosition();
                    JLocation.y = 0;
                    float squaredDistance = ILocation.squaredDistance(JLocation);

                    // CHECK FOR COMBAT
                    if (unitsISquaredCombatRadii >= squaredDistance)
                    {
                        //units.at(i) IN RANGE OF units.at(j).
                        unitsI->unitController->inCombat(unitsJ->unitController);
                    }
                    // CHECK FOR DETECTION
                    if (unitsISquaredDetectionRadii >= squaredDistance)
                    {
                        //units.at(i) IN RANGE OF units.at(j).
                        unitsI->unitController->enemyUnitInRange(unitsJ->unitController);
                    }
                }
                else if( unitsI->unitController->getConfusedBy() &&
                         unitsI->unitController->getConfusedBy() != unitsJ->controller )
                {
                    Ogre::Vector3 JLocation = unitsJ->unitController->getPosition();
                    JLocation.y = 0;

                    float squaredDistance = ILocation.squaredDistance(JLocation);


                    // CHECK FOR COMBAT
                    if (unitsISquaredCombatRadii >= squaredDistance)
                    {
                        //units.at(i) IN RANGE OF units.at(j).
                        unitsI->unitController->inCombat(unitsJ->unitController);
                    }
                    // CHECK FOR DETECTION
                    if (unitsISquaredDetectionRadii >= squaredDistance)
                    {
                        //units.at(i) IN RANGE OF units.at(j).
                        unitsI->unitController->enemyUnitInRange(unitsJ->unitController);
                    }
                }
            }
        }
    }
    // Should not need since the data is passed, not the memory location.
    //units.erase(units.end() - node->units.size(), units.end());
}
void Tank::update(const float& deltaTime, std::vector<PowerUpSpawn*> mPowerUpSpawns){
	
	//this check must be first
	if (!isAlive())
	{
		deathTimer -= deltaTime;

		if (deathTimer <= 0.f)
		{
			deathTimer = 0.f;
			resetAll();
			
			std::random_device rd;
			std::mt19937 random(rd());

			if (tankSide == 1)
			{
				std::uniform_real_distribution<double> randomGen1(1, 5);
				int tempNumber = randomGen1(random);
				std::uniform_real_distribution<double> randomGen2(0, 36);
				int tempNumber2 = (36 * (int)randomGen2(random)) + (int)tempNumber;

				Ogre::Vector3 position = pathFindingGraph->getPosition(tempNumber2);

				mTankBodyNode->setPosition(position);
			} else if(tankSide == 2){
				std::uniform_real_distribution<double> randomGen1(31, 35);
				int tempNumber = randomGen1(random);
				std::uniform_real_distribution<double> randomGen2(0, 36);
				int tempNumber2 = (36 * (int)randomGen2(random)) + (int)tempNumber;
				
				Ogre::Vector3 position = pathFindingGraph->getPosition(tempNumber2);

				mTankBodyNode->setPosition(position);
			}
			mTankBodyNode->setVisible(true);
			setSelected(false);
		}
	}

	//Check for tank powerups
	sphereSceneTime += deltaTime;
	if(sphereSceneTime > 0.2)
	{
		sphereSceneTime = 0;

		Ogre::Vector3 tankCenter = mTankBodyNode->getPosition();
		int location;
		bool found = false;

		for(int i = 0; i < mPowerUpSpawns.size(); i++)
		{
			Ogre::Vector3 powerUpLocation = mPowerUpSpawns[i]->spawnNode->getPosition();
			if(tankCenter.squaredDistance(powerUpLocation) < 5625) //squaredDistance is better
			{
				found = true;
				location = i;
			}
		}
		if (found)
		{
			if(mPowerUpSpawns[location]->getIsPowerUp())
			{
				char tempType = mPowerUpSpawns[location]->pickupPowerUp(mSceneMgr);

				printf("Got Powerup %c\n", tempType);

				switch(tempType)
				{
					case ('H'): //health
					{
						hp += 0.1f;
						if (hp > 1.0f)
						{
							hp = 1.0f;
						}
						printf("Got Health\n");

						//update healthbar
						float healthBarAdjuster = (1.0 - hp) / 2;
						mHealthBarBB->setTexcoordRect(0.0 + healthBarAdjuster, 0.0, 0.5 + healthBarAdjuster, 1.0);
					}
					break;
					case ('R'): //fire rate
					{
						fireRate = 1.f;
						powerUpDurationR = 6.f;
					}
					break;
					case ('S'): //speed
					{
						mRotSpd = 75.0f;
						ms = 100.f;
						mMoveSpd = 100.f;
						powerUpDurationS = 6.f;
					}
					break;
					case ('P'): //damage
					{
						dmg = 30.f;
						powerUpDurationP = 6.f;
					}
					break;
					default:
						printf("Unknown Powerup\n");
					break;
				}
			}
			currentState = WANDER;
			resetWander();
			wanderAStar();
		}
	}

	decrementPowerups(deltaTime);

	//weapontimer
	weaponTimer += deltaTime;

	//seek powerups
	/*
	Ogre::Real distancePowerUp = 0;
	int powerUpNo = 0;
	bool firstTimeDistanceCheck = true;
	for(int i = 0; i < mPowerUpSpawns.size(); i++)
	{
		if(mPowerUpSpawns[i]->getIsPowerUp())
		{
			Ogre::Real tempDistancePowerUp = mTankBodyNode->getPosition().distance(mPowerUpSpawns[i]->getPowerLocation());

			if(firstTimeDistanceCheck)
			{
				firstTimeDistanceCheck = false;
				distancePowerUp = tempDistancePowerUp;
			}
			if(tempDistancePowerUp < distancePowerUp)
			{
				distancePowerUp = tempDistancePowerUp;
				powerUpNo = i;
			}
		}
	}*/
	/*
	if(distancePowerUp < 500 && distancePowerUp > 0 && currentState != POSSESSED)
	{
		if(mPowerUpSpawns[powerUpNo]->getIsPowerUp())
		{
			if(currentState != SEEK)
			{
				currentState = SEEK;
				seekTarget = mPowerUpSpawns[powerUpNo]->getPowerLocation();
				seekAStar();
			}
			
		}
		else 
			currentState = WANDER;
		
	}*/
	
	//check if the user is like somewhere and stopped ocassionally 
	if (currentState != POSSESSED)
	{
		checkPosition += deltaTime;
		if(checkPosition > 3)
		{
			if(mTankBodyNode->getPosition().x == previousLocation.x)
			{
				if(mTankBodyNode->getPosition().z == previousLocation.z)
				{
					checkWhereAt();
				}
			}
			checkPosition = 0;
			previousLocation = mTankBodyNode->getPosition();
		}
	
		checkOrientation += deltaTime;
		if(checkOrientation > 15)
		{
			if(currentState != A_STAR)
			{
				if(!orientationEquals(initBodyOrientation, mTankBodyNode->getOrientation()))
				{
					mTankBodyNode->setOrientation(initBodyOrientation);
				}
				if(!orientationEquals(initBarrelOrientation, mTankBarrelNode->getOrientation()))
				{
					mTankBarrelNode->setOrientation(initBarrelOrientation);
				}
				if(!orientationEquals(initTurretOrientation, mTankTurretNode->getOrientation()))
				{
					mTankTurretNode->setOrientation(initTurretOrientation);
				}
			}
			checkOrientation = 0;
		}
	}

	//no movement for body yet

	//A_STAR, SEEK, WANDER, ESCAPE, STOP
	switch(currentState)
	{
		case A_STAR:
			//initiate astar
			if(tankStarted == false)
			{
				tankStarted = true;
				aStar(tankSide); //creates the path to get out of there
			}
			else
			{
				aStarMovement(deltaTime);
			}
		break;
		case FIRE:
		{
			Ogre::Vector3 targetPosition = getPredictPos(target);
			targetPosition.y = 16.f;

			Ogre::Degree angle = getShootingAngle(targetPosition);

			mTankTurretNode->lookAt(targetPosition, Ogre::Node::TransformSpace::TS_WORLD, Ogre::Vector3::NEGATIVE_UNIT_X);
			//barrelDegree = angle;
			if (weaponTimer > 4)
			{
				tnkMgr->createProjectile(mTankBodyNode->getPosition(), mTankTurretNode->_getDerivedOrientation(), angle, shootingVelocity, dmg);
				weaponTimer = 0;
			}
			if (target->hp <= 0 || mTankBodyNode->getPosition().distance(target->getPosition()) > 600 )
				currentState = WANDER;
		}
		case WANDER:
			//wander(deltaTime);
			wanderMovement(deltaTime);
			break;
	
		case SEEK:
			//seek(mPowerUpSpawns[powerUpNo]->getPowerLocation(), deltaTime);

			//seek(Ogre::Vector3::ZERO, deltaTime);
			//seekMovement(deltaTime);
		break;
		case ESCAPE:
			
		break;
		case STOP:
		
		break;

		case POSSESSED: {
			Ogre::Vector3 rayDest;

			if (mMove < 0)
				rayDest = mTankBodyNode->getOrientation() * Ogre::Vector3(-1,0,0);
			else if (mMove > 0)
				rayDest = mTankBodyNode->getOrientation() * Ogre::Vector3(1,0,0);


			//THIS IS WHERE THE TANK IS MOVED WHEN PROCESSING

			//if (rayDest != NULL)
			{
				Ogre::Ray shootToCheckWall = Ogre::Ray(mTankBodyNode->getPosition(), rayDest);

				Ogre::RaySceneQuery* mRaySceneQuery = mSceneMgr->createRayQuery(shootToCheckWall, Ogre::SceneManager::ENTITY_TYPE_MASK);
				mRaySceneQuery->setSortByDistance(true);

				// Ray-cast and get first hit
				Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute();
				Ogre::RaySceneQueryResult::iterator itr = result.begin();

				bool hit = false;
				for (itr = result.begin(); itr != result.end(); itr++) 
				{
					
					std::string x = itr->movable->getName();
					printf("Check %s \n", x.c_str());

					if (x[0] == 'C' && itr->distance < 10)
					{
						printf("Too close to %s: %f \n", x.c_str(), (float)itr->distance);
						hit = true;
					}
				}

				if(hit == false)
				{
				
					mTankBodyNode->translate(mMove * deltaTime * mMoveSpd, 0, 0, Ogre::Node::TransformSpace::TS_LOCAL);
				}
			}		

			mTankBodyNode->yaw(Ogre::Degree(bodyRotate * deltaTime * mRotSpd));

			// Rotate the tank turret
			mTankTurretNode->yaw(Ogre::Degree(turretRotation * deltaTime * mRotSpd * 1.5));

			turretDegree += turretRotation;

			//to move barrel change barrelRotation
			float barrelChange = barrelRotation * deltaTime * mRotSpd;
			barrelDegree += barrelChange;

			if(barrelDegree > 30)
				barrelDegree = 30;
			else if(barrelDegree < 0)
				barrelDegree = 0;
			else
				mTankBarrelNode->roll(Ogre::Degree(-barrelChange));				
		}

		break;
	}

	Ogre::Vector3 setpos = mTankBodyNode->getPosition();
	setpos.y = 13.f;
	mTankBodyNode->setPosition(setpos);

}
//Probably the most involved behavior so far.
void NPCCharacter::_behaviorTalk(const std::string& targetName)
{
	//have to start moving to the target entity until the distance is acceptable
	LevelData::BaseEntity* targetEnt = LuaManager::getSingleton().getEntity(targetName);

	//Can't talk to a trigger zone or door(though I *could* do the door, it would be an easter egg).
	if(targetEnt->getType() != LevelData::NPC && targetEnt->getType() != LevelData::ENEMY)
	{
		_isBhvFinished = true;
		return;
	}

	if(targetEnt->getType() == LevelData::NPC)
	{
		NPCCharacter* targetNpc = static_cast<NPCCharacter*>(targetEnt);

		//choosing to ignore the y-value to get a true 4 unit distance horizontally from the target.
		//might remove if it doesn't make a difference.
		Ogre::Vector3 tgtNpc = targetNpc->getPosition(); tgtNpc.y = 0;
		Ogre::Vector3 pos = getPosition(); pos.y = 0;

		//position has to be less than 16 units to talk to the entity.
		//chose to use 18 instead due to float inaccuracies(might have a value like 16.0178)
		if(tgtNpc.squaredDistance(pos) > 18)
		{
			//move towards the entity(not using the _behaviorMove function though)
			//or can I??
			//yes I can actually. *does a jig*
			//generate a more correct position
			Ogre::Vector3 target,tmp;
			tmp = targetNpc->getPosition() - getPosition(); //distance and direction to the target
			tmp.y = 0;
			Ogre::Real len = tmp.normalise();
			//original + (unit direction vector * desired distance from target[non-squared])
			target = getPosition() + (tmp * ( len - 1));

			_behaviorMove(target);

			if(_isBhvFinished)
			{
				//reached the destination, but behavior isn't done yet.
				_isBhvFinished = false;
			}
		}
		else
		{
			//rotate to face the target
			Ogre::Vector3 dir = tgtNpc - pos; dir.normalise();
			Ogre::Vector3 src = _node->getOrientation() * Ogre::Vector3::NEGATIVE_UNIT_Z;
			src.y = 0;

			_node->rotate(src.getRotationTo(dir));

			//make sure any other blends are finished first.
			if(_animHandler.getTarget() == nullptr)
			{
				//this ends the behavior until the talk animation or sound file is implemented
				_isBhvFinished = true;

				//this would be the actual way to finish the behavior(or even with the end of a sound file)
				if(_animHandler.getSource()->getAnimationName() == "Talk")
				{
					_isBhvFinished = true;
				}
				else
				{
					//start the blend to the talk animation.
					//_animHandler.blend([animation],[blend technique],.2,true);
				}
			}
		}

		return;
	}

	if(targetEnt->getType() == LevelData::ENEMY)
	{
		//nothing for now.

		return;
	}


	return;
}