void CAIVehicle::PlayerFrob( idPlayer *player ) {
	idVec3 origin;
	idMat3 axis;
	// =============== DISMOUNT ===============
	if( m_Controller.GetEntity() ) {
		if( m_Controller.GetEntity() == player ) {
			player->Unbind();
			SetController( NULL );
		}
	}
	// =============== MOUNT ===============
	else {
		// attach player to the joint
		GetJointWorldTransform( m_RideJoint, gameLocal.time, origin, axis );
		// put the player in a crouch, so their view is low to the animal
		// without actually clipping into it
		idPhysics_Player *playerPhys = ( idPhysics_Player * ) player->GetPhysics();
		// TODO: look up PMF_DUCKED somehow (make those flags statics in the idPhysics_Player class?)
		// for now, using 1 since we know that is PMF_DUCKED
		// Or, we could move mount and dismount to idPhysics_Player...
		playerPhys->SetMovementFlags( playerPhys->GetMovementFlags() | 1 );
		player->SetOrigin( origin + m_RideOffset * axis );
		player->BindToJoint( this, m_RideJoint, true );
		SetController( player );
	}
}
/*
=====================
rvMonsterStroggHover::UpdateLightDef
=====================
*/
void rvMonsterStroggHover::UpdateLightDef ( void ) {
	if ( jointHeadlight != INVALID_JOINT )
	{
		idVec3 origin;
		idMat3 axis;

		if ( jointHeadlightControl != INVALID_JOINT ) {
			idAngles jointAng;
			jointAng.Zero();
			jointAng.yaw = 10.0f * sin( ( (gameLocal.GetTime()%2000)-1000 ) / 1000.0f * idMath::PI );
			jointAng.pitch = 7.5f * sin( ( (gameLocal.GetTime()%4000)-2000 ) / 2000.0f * idMath::PI );

			animator.SetJointAxis( jointHeadlightControl, JOINTMOD_WORLD, jointAng.ToMat3() );
		}

		GetJointWorldTransform ( jointHeadlight, gameLocal.time, origin, axis );
	
		//origin += (localOffset * axis);
		
		// Include this part in the total bounds 
		// FIXME: bounds are local
		//parent->AddToBounds ( worldOrigin );
		//UpdateOrigin ( );
		
		if ( lightHandle != -1 ) {
			renderLight.origin = origin;
			renderLight.axis   = axis;	
			
			gameRenderWorld->UpdateLightDef( lightHandle, &renderLight );	
		}
	}
}
void idActor::Attach( idEntity *ent ) {
#if 0
	idVec3			origin;
	noMat3			axis;
	jointHandle_t	joint;
	idStr			jointName;
	idAttachInfo	&attach = attachments.Alloc();
	idAngles		angleOffset;
	idVec3			originOffset;

	jointName = ent->spawnArgs.GetString( "joint" );
	joint = animator.GetJointHandle( jointName );
	if ( joint == INVALID_JOINT ) {
		gameLocal.Error( "Joint '%s' not found for attaching '%s' on '%s'", jointName.c_str(), ent->GetClassname(), name.c_str() );
	}

	angleOffset = ent->spawnArgs.GetAngles( "angles" );
	originOffset = ent->spawnArgs.GetVector( "origin" );

	attach.channel = animator.GetChannelForJoint( joint );
	GetJointWorldTransform( joint, gameLocal.time, origin, axis );
	attach.ent = ent;

	ent->SetOrigin( origin + originOffset * renderEntity.axis );
	noMat3 rotate = angleOffset.ToMat3();
	noMat3 newAxis = rotate * axis;
	ent->SetAxis( newAxis );
	ent->BindToJoint( this, joint, true );
	ent->cinematic = cinematic;
#endif
}
Beispiel #4
0
/*
================
sdClientAnimated::Event_GetJointPos

returns the position of the joint in worldspace
================
*/
void sdClientAnimated::Event_GetJointPos( jointHandle_t jointnum ) {
	idVec3 offset;
	idMat3 axis;

	if ( !GetJointWorldTransform( jointnum, gameLocal.time, offset, axis ) ) {
		offset.Zero();
		gameLocal.Warning( "Joint # %d out of range on client entity '%s'", jointnum, GetName() );
	}

	sdProgram::ReturnVector( offset );
}
/*
================
hhWeaponAutoCannon::Ticker
================
*/
void hhWeaponAutoCannon::Ticker() {
    idVec3 boneOriginL, boneOriginR;
    idMat3 boneAxisL, boneAxisR;

    if( beamSystem.IsValid() ) {
        GetJointWorldTransform( sparkBoneL, boneOriginL, boneAxisL );
        GetJointWorldTransform( sparkBoneR, boneOriginR, boneAxisR );

        if( (boneOriginL - boneOriginR).Length() > sparkGapSize ) {
            if( !beamSystem->IsHidden() ) {
                beamSystem->Hide();
                SetShaderParm( SHADERPARM_MODE, 0.0f );
            }
        } else if ( owner->CanShowWeaponViewmodel() ) {
            if( beamSystem->IsHidden() ) {
                beamSystem->Show();
                SetShaderParm( SHADERPARM_MODE, 1.0f );
            }
        }

        beamSystem->SetOrigin( boneOriginL );
        beamSystem->SetTargetLocation( boneOriginR );
    }
}
Beispiel #6
0
/*
================
rvMonsterBerserker::Frame_ChargeGroundImpact
================
*/
stateResult_t rvMonsterBerserker::Frame_ChargeGroundImpact ( const stateParms_t& parms ) {
	idVec3			start;
	idVec3			end;
	idMat3			axis;
	trace_t			tr;

	GetJointWorldTransform ( animator.GetJointHandle ( "R_lowerArm_Real" ), gameLocal.time, start, axis );
	
	end    = start;
	end.z -= 128;
// RAVEN BEGIN
// ddynerman: multiple clip worlds
	gameLocal.TracePoint ( this, tr, start, end, MASK_SHOT_BOUNDINGBOX, this );
// RAVEN END
	
	gameLocal.PlayEffect ( gameLocal.GetEffect( spawnArgs, "fx_ground_impact" ), tr.endpos, idVec3(0,0,1).ToMat3() ); 
	
	return SRESULT_OK;
}
Beispiel #7
0
/*
================
rvMonsterBerserker::Frame_DoBlastAttack
================
*/
stateResult_t rvMonsterBerserker::Frame_DoBlastAttack ( const stateParms_t& parms ) {
	float			i;
	idVec3			start;
	idMat3			axis;
	idAngles		angles ( 0.0f, move.current_yaw, 0.0f );
	const idDict*	blastDict;

	blastDict = gameLocal.FindEntityDefDict ( spawnArgs.GetString ( "def_attack_spike" ), false );
	if ( !blastDict ) {
		gameLocal.Error ( "missing projectile on spike attack for AI entity '%s'", GetName ( ) ) ;
		return SRESULT_OK;
	}

	GetJointWorldTransform ( animator.GetJointHandle ( "end_spike" ), gameLocal.time, start, axis );

	for( i = 0; i < 32; i++ ) {
		angles.yaw += (360.0f / 32.0f);
		AttackProjectile ( blastDict, start, angles );
	}
	
	return SRESULT_OK;
}
/*
================
rvVehicleAnimated::Think
================
*/
void rvVehicleAnimated::Think ( void ) {

	rvVehicle::Think();	

	float rate = 0.0f;
	usercmd_t& cmd = positions[0].mInputCmd;
	idVec3 delta;

	if( positions[0].IsOccupied() && !IsFrozen() && IsMovementEnabled() )	{
		
		if (( g_vehicleMode.GetInteger() == 0 && !( cmd.buttons & BUTTON_STRAFE )) || 	// If we're in the old driving mode and we aren't strafing or...
			( g_vehicleMode.GetInteger() != 0 && ( cmd.buttons & BUTTON_STRAFE )))		// If we're in the new driving mode and we are strafing
		{
			rate = SignZero(cmd.forwardmove) * turnRate;
			rate *= idMath::MidPointLerp( 0.0f, 0.9f, 1.0f, idMath::Fabs(cmd.rightmove) / 127.0f );
			viewAngles.yaw += Sign(cmd.rightmove) * rate * MS2SEC(gameLocal.GetMSec());	
		}
	}

	viewAngles.Normalize360();
	animator.GetDelta( gameLocal.time - gameLocal.GetMSec(), gameLocal.time, delta );
	delta += additionalDelta;

	idStr alignmentJoint;
	if ( g_vehicleMode.GetInteger() != 0 && spawnArgs.GetString( "alignment_joint", 0, alignmentJoint ) ) {
		idVec3 offset;
		idMat3 axis;
		GetJointWorldTransform( animator.GetJointHandle( alignmentJoint ), gameLocal.time, offset, axis );
		delta *= axis;
	} else {
		viewAxis = viewAngles.ToMat3() * physicsObj.GetGravityAxis();
		delta *= viewAxis;
	}
			
	physicsObj.SetDelta( delta );
	additionalDelta.Zero();
}
/*
================
idTestModel::Think
================
*/
void idTestModel::Think()
{
	idVec3 pos;
	idMat3 axis;
	idAngles ang;
	int	i;
	
	if( thinkFlags & TH_THINK )
	{
		if( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) )
		{
			StopSound( SND_CHANNEL_ANY, false );
			if( head.GetEntity() )
			{
				head.GetEntity()->StopSound( SND_CHANNEL_ANY, false );
			}
			switch( g_testModelAnimate.GetInteger() )
			{
				default:
				case 0:
					// cycle anim with origin reset
					if( animator.NumFrames( anim ) <= 1 )
					{
						// single frame animations end immediately, so just cycle it since it's the same result
						animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
						if( headAnim )
						{
							headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
						}
					}
					else
					{
						animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
						if( headAnim )
						{
							headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
							if( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) )
							{
								// loop the body anim when the head anim is longer
								animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
							}
						}
					}
					animator.RemoveOriginOffset( false );
					break;
					
				case 1:
					// cycle anim with fixed origin
					animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( true );
					if( headAnim )
					{
						headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 2:
					// cycle anim with continuous origin
					animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( false );
					if( headAnim )
					{
						headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 3:
					// frame by frame with continuous origin
					animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( false );
					if( headAnim )
					{
						headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 4:
					// play anim once
					animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( false );
					if( headAnim )
					{
						headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 5:
					// frame by frame with fixed origin
					animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( true );
					if( headAnim )
					{
						headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
			}
			
			mode = g_testModelAnimate.GetInteger();
		}
		
		if( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) )
		{
			starttime = gameLocal.time;
			StopSound( SND_CHANNEL_ANY, false );
			animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
			if( headAnim )
			{
				headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
				if( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) )
				{
					// loop the body anim when the head anim is longer
					animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
				}
			}
		}
		
		if( headAnimator )
		{
			// copy the animation from the body to the head
			for( i = 0; i < copyJoints.Num(); i++ )
			{
				if( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE )
				{
					idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose();
					GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
					pos -= head.GetEntity()->GetPhysics()->GetOrigin();
					headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat );
					headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat );
				}
				else
				{
					animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
					headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos );
					headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis );
				}
			}
		}
		
		// update rotation
		RunPhysics();
		
		physicsObj.GetAngles( ang );
		physicsObj.SetAngularExtrapolation( extrapolation_t( EXTRAPOLATION_LINEAR | EXTRAPOLATION_NOSTOP ), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero );
		
		idClipModel* clip = physicsObj.GetClipModel();
		if( clip != NULL && animator.ModelDef() )
		{
			idVec3 neworigin;
			idMat3 axis;
			jointHandle_t joint;
			
			joint = animator.GetJointHandle( "origin" );
			animator.GetJointTransform( joint, gameLocal.time, neworigin, axis );
			neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin();
			clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() );
		}
	}
	
	UpdateAnimation();
	Present();
	
	if( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim )
	{
		gameLocal.Printf( "^5 Anim: ^7%s  ^5Frame: ^7%d/%d  Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
						  animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
		if( headAnim )
		{
			gameLocal.Printf( "^5 Head: ^7%s  ^5Frame: ^7%d/%d  Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
							  headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
		}
		else
		{
			gameLocal.Printf( "\n\n" );
		}
	}
}
Beispiel #10
0
/*
================
rvMonsterRepairBot::UpdateRepairs
================
*/
void rvMonsterRepairBot::UpdateRepairs ( repairBotArm_t& arm ) {
	trace_t tr;
	idVec3	origin;
	idMat3	axis;

	if ( arm.joint == INVALID_JOINT ) {
		return;
	}

	if ( gameLocal.time > repairEndTime ) {
		StopRepairs ( arm ) ;
		return;
	}

	// If the repair time has been crossed we need to start/stop the repairs
	if ( gameLocal.time > arm.repairTime ) {
		if ( arm.repairing ) {
			StopRepairs ( arm );
			arm.repairTime = gameLocal.time + gameLocal.random.RandomInt ( 500 );
			arm.repairing  = false;
		} else {
			arm.repairTime = gameLocal.time + gameLocal.random.RandomInt ( 2500 );
			arm.repairing  = true;
		}				
	} 
	
	if ( !arm.repairing ) {
		return;
	}
			
	// Left repair effect
	GetJointWorldTransform ( arm.joint, gameLocal.time, origin, axis );
	gameLocal.TracePoint ( this, tr, origin, origin + axis[0] * repairEffectDist, MASK_SHOT_RENDERMODEL, this );

	if ( tr.fraction >= 1.0f ) {		
		StopRepairs ( arm );
	} else {
		// Start the repair effect if not already started
		if ( !arm.effectRepair ) {
			arm.effectRepair = PlayEffect ( "fx_repair", arm.joint, true );
		}
		// If the repair effect is running then set its end origin
		if ( arm.effectRepair ) {	
			arm.effectRepair->SetEndOrigin ( tr.endpos );
		}
		// Start the impact effect
		if ( !arm.effectImpact ) {
			arm.effectImpact = PlayEffect ( "fx_repair_impact", tr.endpos, tr.c.normal.ToMat3(), true );

		} else {
			// Calculate the local origin and axis from the given globals
			idVec3 localOrigin = (tr.endpos - renderEntity.origin) * renderEntity.axis.Transpose ( );
			idMat3 localAxis   = tr.c.normal.ToMat3 ();// * renderEntity.axis.Transpose();
			arm.effectImpact->SetOrigin ( localOrigin );
			arm.effectImpact->SetAxis ( localAxis );
		}

		if( gameLocal.GetTime() > arm.periodicEndTime ) {// FIXME: Seems dumb to keep banging on this if the fx isn't defined.
			gameLocal.PlayEffect( spawnArgs, "fx_repair_impact_periodic", tr.endpos, tr.c.normal.ToMat3() );
			arm.periodicEndTime = gameLocal.GetTime() + SEC2MS( rvRandom::flrand(spawnArgs.GetVec2("impact_fx_delay_range", "1 1")) );
		}
	}
}
/*
================
rvMonsterStroggHover::Think
================
*/
void rvMonsterStroggHover::Think ( void ) {
	idAI::Think ( );
	
	if ( !aifl.dead )
	{
		// If thinking we should play an effect on the ground under us
		if ( !fl.hidden && !fl.isDormant && (thinkFlags & TH_THINK ) && !aifl.dead ) {
			trace_t tr;
			idVec3	origin;
			idMat3	axis;
			
			// Project the effect 80 units down from the bottom of our bbox
			GetJointWorldTransform ( jointDust, gameLocal.time, origin, axis );
			
	// RAVEN BEGIN
	// ddynerman: multiple clip worlds
			gameLocal.TracePoint ( this, tr, origin, origin + axis[0] * (GetPhysics()->GetBounds()[0][2]+80.0f), CONTENTS_SOLID, this );
	// RAVEN END

			// Start the dust effect if not already started
			if ( !effectDust ) {
				effectDust = gameLocal.PlayEffect ( gameLocal.GetEffect ( spawnArgs, "fx_dust" ), tr.endpos, tr.c.normal.ToMat3(), true );
			}
			
			// If the effect is playing we should update its attenuation as well as its origin and axis
			if ( effectDust ) {
				effectDust->Attenuate ( 1.0f - idMath::ClampFloat ( 0.0f, 1.0f, (tr.endpos - origin).LengthFast ( ) / 127.0f ) );
				effectDust->SetOrigin ( tr.endpos );
				effectDust->SetAxis ( tr.c.normal.ToMat3() );
			}
			
			// If the hover effect is playing we can set its end origin to the ground
			/*
			if ( effectHover ) {
				effectHover->SetEndOrigin ( tr.endpos );
			}
			*/
		} else if ( effectDust ) {
			effectDust->Stop ( );
			effectDust = NULL;
		}

		//Try to circle strafe or pursue
		if ( circleStrafing )
		{
			CircleStrafe();
		}
		else if ( !inPursuit )
		{
			if ( !aifl.action && move.fl.done && !aifl.scripted )
			{
				if ( GetEnemy() )
				{
					if ( DistanceTo( GetEnemy() ) > 2000.0f 
						|| (GetEnemy()->GetPhysics()->GetLinearVelocity()*(GetEnemy()->GetPhysics()->GetOrigin()-GetPhysics()->GetOrigin())) > 1000.0f )
					{//enemy is far away or moving away from us at a pretty decent speed
						TryStartPursuit();
					}
				}
			}
		}
		else
		{
			Pursue();
		}

		//Dodge
		if ( !circleStrafing ) {
			if( combat.shotAtTime && gameLocal.GetTime() - combat.shotAtTime < 1000.0f ) {
				if ( nextBombFireTime < gameLocal.GetTime() - 3000 ) {
					if ( gameLocal.random.RandomFloat() > evadeChance ) {
						//40% chance of ignoring it - makes them dodge rockets less often but bullets more often?
						combat.shotAtTime = 0;
					} else if ( evadeDebounce < gameLocal.GetTime() ) {
						//ramps down from 400 to 100 over 1 second
						float speed = evadeSpeed - ((((float)(gameLocal.GetTime()-combat.shotAtTime))/1000.0f)*(evadeSpeed-(evadeSpeed*0.25f)));
						idVec3 evadeVel = viewAxis[1] * ((combat.shotAtAngle >= 0)?-1:1) * speed;
						evadeVel.z *= 0.5f;
						move.addVelocity += evadeVel;
						move.addVelocity.Normalize();
						move.addVelocity *= speed;
						/*
						if ( move.moveCommand < NUM_NONMOVING_COMMANDS ) {
							//just need to do it once?
							combat.shotAtTime = 0;
						}
						*/
						if ( evadeDebounceRate > 1 )
						{
							evadeDebounce = gameLocal.GetTime() + gameLocal.random.RandomInt( evadeDebounceRate ) + (ceil(((float)evadeDebounceRate)/2.0f));
						}
					}
				}
			}
		}

		//If using melee rush to nav to him, stop when we're close enough to attack
		if ( combat.tacticalCurrent == AITACTICAL_MELEE 
			&& move.moveCommand == MOVE_TO_ENEMY
			&& !move.fl.done
			&& nextBombFireTime < gameLocal.GetTime() - 3000
			&& enemy.fl.visible && DistanceTo( GetEnemy() ) < 2000.0f ) {
			StopMove( MOVE_STATUS_DONE );
			ForceTacticalUpdate();
		} else {
			//whenever we're not in the middle of something, force an update of our tactical
			if ( !aifl.action ) {
				if ( !aasFind ) {
					if ( move.fl.done ) {
						if ( !inPursuit && !circleStrafing ) {
							ForceTacticalUpdate();
						}
					}
				}
			}
		}
	}

	//update light
//	if ( lightOn ) {
		UpdateLightDef ( );
//	}
}