/*
================
rvMonsterConvoyGround::State_Torso_Pain
================
*/
stateResult_t rvMonsterConvoyGround::State_Torso_Pain ( const stateParms_t& parms ) {
	enum {
		STAGE_START,
		STAGE_END
	};
	
	switch ( parms.stage ) {
		case STAGE_START:
			// Force the orientation to the direction we got hit from so the animation looks correct		
			OverrideFlag ( AIFLAGOVERRIDE_NOTURN, true );
			TurnToward ( physicsObj.GetOrigin() - lastPainDir * 128.0f );
			move.current_yaw = move.ideal_yaw;
			
			// Just in case the pain anim wasnt set before we got here.
			if ( !painAnim.Length ( ) ) {
				painAnim = "pain";
			}
			
			DisableAnimState ( ANIMCHANNEL_LEGS );
			PlayAnim ( ANIMCHANNEL_TORSO, painAnim, parms.blendFrames );
			return SRESULT_STAGE ( STAGE_END );
	
		case STAGE_END:
			if ( AnimDone ( ANIMCHANNEL_TORSO, parms.blendFrames ) ) {
				return SRESULT_DONE;
			}
			return SRESULT_WAIT;
	}
	return SRESULT_ERROR;
}
void CAIVehicle::Think( void ) {
	if( !( thinkFlags & TH_THINK ) ) {
		goto Quit;
	}
	if( m_Controller.GetEntity() ) {
		// Exit the combat state if we somehow got in it.
		// Later we can fight as directed by player, but right now it's too independent
		ClearEnemy();
		// Update controls and movement dir
		UpdateSteering();
		// Speed controls, for now just AI_MOVE
		bool bMovementReq = UpdateSpeed();
		// Request move at direction
		if( bMovementReq ) {
			MoveAlongVector( m_CurAngle );
		} else {
			StopMove( MOVE_STATUS_DONE );
			// just turn if no forward/back movement is requested
			TurnToward( m_CurAngle );
		}
	}
	idAI::Think();
Quit:
	return;
}
Exemplo n.º 3
0
void rvMonsterStroggHover::CircleStrafe ( void )
{
	if ( !GetEnemy() || strafeTime < gameLocal.GetTime() || !enemy.fl.visible || !enemy.fl.inFov )
	{
		//FIXME: also stop if I bump into something
		circleStrafing = false;
		strafeTime = 0;
		SetState( "State_Combat" );
		return;
	}
	if ( !strafeTime )
	{
		strafeTime = gameLocal.GetTime() + 8000;
		//FIXME: try to see which side it clear?
		strafeRight = (gameLocal.random.RandomFloat()>0.5f);
	}

	idVec3 vel = GetPhysics()->GetLinearVelocity();
	idVec3 strafeVel = viewAxis[1] * (strafeRight?-circleStrafeSpeed:circleStrafeSpeed);
	strafeVel.z = 0.0f;
	vel += strafeVel;
	vel.Normalize();
	vel *= circleStrafeSpeed;
	physicsObj.UseVelocityMove( true );
	GetPhysics()->SetLinearVelocity( vel );
	TurnToward( GetEnemy()->GetPhysics()->GetOrigin() );
}
END_CLASS_STATES

/*
================
rvMonsterStroggMarine::State_Torso_RollAttack 
================
*/
stateResult_t rvMonsterStroggMarine::State_Torso_RollAttack ( const stateParms_t& parms ) {
	enum { 
		TORSO_ROLLATTACK_ROLL,
		TORSO_ROLLATTACK_FACE,
		TORSO_ROLLATTACK_FIRE,
		TORSO_ROLLATTACK_FINISH
	};

	TurnToward(enemy.lastKnownPosition);

	switch ( parms.stage ) {
		// Start the roll attack animation
		case TORSO_ROLLATTACK_ROLL:			
			// Full body animations
			DisableAnimState ( ANIMCHANNEL_LEGS );

			// Play the roll
			PlayAnim ( ANIMCHANNEL_TORSO, "dive_turn", parms.blendFrames );	
			move.fl.noTurn = false;
			//FaceEnemy();
			return SRESULT_STAGE ( TORSO_ROLLATTACK_FACE );
			
		// Wait for roll animation to finish
		case TORSO_ROLLATTACK_FACE:
			if ( AnimDone ( ANIMCHANNEL_LEGS, 6 ) ) {
				return SRESULT_STAGE ( TORSO_ROLLATTACK_FIRE );
			}
			return SRESULT_WAIT;
	
		// Play fire animation
		case TORSO_ROLLATTACK_FIRE:
			if ( !enemy.ent || !enemy.fl.visible )
			{//whoops! rolled out of LOS
				return SRESULT_DONE;			
			}
			if ( enemy.fl.inFov )
			{
				PlayAnim ( ANIMCHANNEL_TORSO, "shotgun_range_attack", parms.blendFrames );
				return SRESULT_STAGE ( TORSO_ROLLATTACK_FINISH );
			}
			return SRESULT_WAIT;

		// Wait for fire animation to finish
		case TORSO_ROLLATTACK_FINISH:
			if ( AnimDone ( ANIMCHANNEL_TORSO, 2 ) ) {
				return SRESULT_DONE;			
			}
			return SRESULT_WAIT;
	}	
	return SRESULT_ERROR;
}
Exemplo n.º 5
0
void CUnitScript::TickAnims(int deltaTime, AnimType type, std::list< std::list<AnimInfo*>::iterator >& doneAnims) {
	switch (type) {
		case AMove: {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;

				// NOTE: we should not need to copy-and-set here, because
				// MoveToward/TurnToward/DoSpin modify pos/rot by reference
				float3 pos = pieces[ai->piece]->GetPosition();

				if (MoveToward(pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime))) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetPosition(pos);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;

		case ATurn: {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;
				float3 rot = pieces[ai->piece]->GetRotation();

				if (TurnToward(rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime))) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetRotation(rot);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;

		case ASpin: {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;
				float3 rot = pieces[ai->piece]->GetRotation();

				if (DoSpin(rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime)) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetRotation(rot);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;

		default: {
		} break;
	}
}
Exemplo n.º 6
0
/**
 * @brief Called by the engine when we are registered as animating. If we return -1 it means that
 *        there is no longer anything animating
 * @param deltaTime int delta time to update
 * @return 0 if there are still animations going, -1 else
 */
int CUnitScript::Tick(int deltaTime)
{
	std::vector<struct AnimInfo *> remove;

	for (std::list<struct AnimInfo *>::iterator it = anims.begin(); it != anims.end(); ) {
		struct AnimInfo *ai = *it;

		bool done = false;

		switch (ai->type) {
			case AMove: {
				float3 pos = pieces[ai->piece]->GetPosition();
				done = MoveToward(pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime));
				pieces[ai->piece]->SetPosition(pos);
			} break;
			case ATurn: {
				float3 rot = pieces[ai->piece]->GetRotation();
				done = TurnToward(rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime));
				pieces[ai->piece]->SetRotation(rot);
			} break;
			case ASpin: {
				float3 rot = pieces[ai->piece]->GetRotation();
				done = DoSpin(rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime);
				pieces[ai->piece]->SetRotation(rot);
			} break;
		}

		// Queue for removal (UnblockAll may add new anims)
		if (done) {
			remove.push_back(ai);
		}
		++it;
	}

	//Tell listeners to unblock?
	for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) {
		UnblockAll(*it); //! NOTE: UnblockAll might result in new anims being added
	}

	for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) {
		anims.remove(*it);
		delete *it;
	}

	return anims.empty() ? -1 : 0;
}
Exemplo n.º 7
0
/**
 * @brief Called by the engine when we are registered as animating. If we return -1 it means that
 *        there is no longer anything animating
 * @param deltaTime int delta time to update
 * @return 0 if there are still animations going, -1 else
 */
int CUnitScript::Tick(int deltaTime)
{
	std::vector<struct AnimInfo *> remove;

	for (std::list<struct AnimInfo *>::iterator it = anims.begin(); it != anims.end(); ) {
		struct AnimInfo *ai = *it;

		bool done = false;

		switch (ai->type) {
			case AMove:
				done = MoveToward(pieces[ai->piece]->pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime));
				break;
			case ATurn:
				done = TurnToward(pieces[ai->piece]->rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime));
				break;
			case ASpin:
				done = DoSpin(pieces[ai->piece]->rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime);
				break;
		}

		// Queue for removal (UnblockAll may add new anims)
		if (done) {
			remove.push_back(ai);
			it = anims.erase(it);
		}
		else {
			++it;
		}
	}

	//Tell listeners to unblock?
	for (std::vector<struct AnimInfo *>::iterator it = remove.begin(); it != remove.end(); ++it) {
		UnblockAll(*it);
		delete *it;
	}

	if (anims.empty())
		return -1;
	else
		return 0;
}
Exemplo n.º 8
0
//Called by the engine when we are registered as animating. If we return -1 it means that
//there is no longer anything animating
int CCobInstance::Tick(int deltaTime) 
{
	int done;
	list<struct AnimInfo *>::iterator it = anims.begin();
	list<struct AnimInfo *>::iterator cur;

	while (it != anims.end()) {
		//Advance it, so we can erase cur safely
		cur = it++;		

		done = false;
		pieces[(*cur)->piece].updated = true;

		switch ((*cur)->type) {
			case AMove:
				done = MoveToward(pieces[(*cur)->piece].coords[(*cur)->axis], (*cur)->dest, (*cur)->speed / (1000 / deltaTime));
				break;
			case ATurn:
				done = TurnToward(pieces[(*cur)->piece].rot[(*cur)->axis], (*cur)->dest, (*cur)->speed / (1000 / deltaTime));
				break;
			case ASpin:
				done = DoSpin(pieces[(*cur)->piece].rot[(*cur)->axis], (*cur)->dest, (*cur)->speed, (*cur)->accel, 1000 / deltaTime);
				break;
		}

		//Tell listeners to unblock?
		if (done) {
			UnblockAll(*cur);
			delete *cur;
			anims.erase(cur);
		}

	}

	if (anims.size() == 0) 
		return -1;
	else
		return 0;
}
Exemplo n.º 9
0
void hhHarvesterSimple::AnimMove( void ) {
	idVec3				goalPos;
	idVec3				delta;
	idVec3				goalDelta;
	float				goalDist;
	monsterMoveResult_t	moveResult;
	idVec3				newDest;

	// Turn on physics to prevent flying harvesters
	BecomeActive(TH_PHYSICS);

	idVec3 oldorigin = physicsObj.GetOrigin();
#ifdef HUMANHEAD //jsh wallwalk
	idMat3 oldaxis = GetGravViewAxis();
#else
	idMat3 oldaxis = viewAxis;
#endif

	AI_BLOCKED = false;

	if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ 
		move.lastMoveOrigin.Zero();
		move.lastMoveTime = gameLocal.time;
	}

	move.obstacle = NULL;
	if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) {
		TurnToward( lastVisibleEnemyPos );
		goalPos = oldorigin;
	} else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) {
		TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() );
		goalPos = oldorigin;
	} else if ( GetMovePos( goalPos ) ) {
		if ( move.moveCommand != MOVE_WANDER ) {
			CheckObstacleAvoidance( goalPos, newDest );
			TurnToward( newDest );
		} else {
			TurnToward( goalPos );
		}
	}
		
	Turn();	

	if ( move.moveCommand == MOVE_SLIDE_TO_POSITION ) {
		if ( gameLocal.time < move.startTime + move.duration ) {
			goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time );
			delta = goalPos - oldorigin;
			delta.z = 0.0f;
		} else {
			delta = move.moveDest - oldorigin;
			delta.z = 0.0f;
			StopMove( MOVE_STATUS_DONE );
		}
	} else if ( allowMove ) {
#ifdef HUMANHEAD //jsh wallwalk
		GetMoveDelta( oldaxis, GetGravViewAxis(), delta );
#else
		GetMoveDelta( oldaxis, viewAxis, delta );
#endif
	} else {
		delta.Zero();
	}

	if ( move.moveCommand == MOVE_TO_POSITION ) {
		goalDelta = move.moveDest - oldorigin;
		goalDist = goalDelta.LengthFast();
		if ( goalDist < delta.LengthFast() ) {
			delta = goalDelta;
		}
	}
	
#ifdef HUMANHEAD //shrink functionality
	float scale = renderEntity.shaderParms[SHADERPARM_ANY_DEFORM_PARM1];
	if ( scale > 0.0f && scale < 2.0f ) {
		delta *= scale;
	}
#endif
	physicsObj.SetDelta( delta );
	physicsObj.ForceDeltaMove( disableGravity );

	RunPhysics();

	if ( ai_debugMove.GetBool() ) {
		// HUMANHEAD JRM - so we can see if grav is on or off
		if(disableGravity) {
			gameRenderWorld->DebugLine( colorRed, oldorigin, physicsObj.GetOrigin(), 5000 );
		} else {
			gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 );
		}
	}

	moveResult = physicsObj.GetMoveResult();
	if ( !af_push_moveables && attack.Length() && TestMelee() ) {
		DirectDamage( attack, enemy.GetEntity() );
	} else {
		idEntity *blockEnt = physicsObj.GetSlideMoveEntity();
		if ( blockEnt && blockEnt->IsType( hhHarvesterSimple::Type ) ) {
			StopMove( MOVE_STATUS_BLOCKED_BY_MONSTER );
			return;
		}
		if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) {
			KickObstacles( viewAxis[ 0 ], kickForce, blockEnt );
		}
	}

	BlockedFailSafe();

	AI_ONGROUND = physicsObj.OnGround();

	idVec3 org = physicsObj.GetOrigin();
	if ( oldorigin != org ) {
		TouchTriggers();
	}

	if ( ai_debugMove.GetBool() ) {
		gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec );
		gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec );
		gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true );
		DrawRoute();
	}
}