Example #1
0
ILINE bool InitializePoseAlignerBipedHuman(PoseAligner::CPose& pose, IEntity& entity, ICharacterInstance& character)
{
	IDefaultSkeleton& rIDefaultSkeleton = character.GetIDefaultSkeleton();
	int jointIndexRoot = rIDefaultSkeleton.GetJointIDByName("Bip01 Pelvis");
	if (jointIndexRoot < 0)
		return false;
	int jointIndexFrontLeft = rIDefaultSkeleton.GetJointIDByName("Bip01 planeTargetLeft");
	if (jointIndexFrontLeft < 0)
		return false;
	int jointIndexFrontRight = rIDefaultSkeleton.GetJointIDByName("Bip01 planeTargetRight");
	if (jointIndexFrontRight < 0)
		return false;

	int jointIndexLeftBlend = rIDefaultSkeleton.GetJointIDByName("Bip01 planeWeightLeft");
	int jointIndexRightBlend = rIDefaultSkeleton.GetJointIDByName("Bip01 planeWeightRight");

	if (!pose.Initialize(entity, jointIndexRoot))
		return false;

	pose.SetRootOffsetMinMax(-0.4f, 0.0f);

	PoseAligner::SChainDesc chainDesc;
	chainDesc.name = "Left";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "LftLeg01";
	chainDesc.contactJointIndex = jointIndexFrontLeft;
	chainDesc.targetBlendJointIndex = jointIndexLeftBlend;
	chainDesc.bBlendProcedural = true;
	chainDesc.bTargetSmoothing = true;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, 0.0f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.6f);
	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "Right";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "RgtLeg01";	
	chainDesc.contactJointIndex = jointIndexFrontRight;
	chainDesc.targetBlendJointIndex = jointIndexRightBlend;
	chainDesc.bBlendProcedural = true;
	chainDesc.bTargetSmoothing = true;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, 0.0f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.6f);
	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	return pose.GetChainCount() != 0;
}
bool CMFXParticleEffect::AttachToCharacter( IEntity& targetEntity, const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, const Vec3& dir, float scale )
{
	if (params.partID >= 0)
	{
		//Assume character is loaded in first slot 
		//We could iterate through all available slots, but first one should be good enough
		ICharacterInstance* pCharacterInstace = targetEntity.GetCharacter(0);
		ISkeletonPose* pSkeletonPose = pCharacterInstace ? pCharacterInstace->GetISkeletonPose() : NULL;
		if (pSkeletonPose)
		{
			IDefaultSkeleton& rIDefaultSkeleton	= pCharacterInstace->GetIDefaultSkeleton();
			//It hit the character, but probably in a physicalized attached part, like armor plates, etc
			if (params.partID >= rIDefaultSkeleton.GetJointCount())
			{
				return false;
			}

			//It hit some valid joint, create an attachment
			const char* boneName = rIDefaultSkeleton.GetJointNameByID(params.partID);
			TAttachmentName attachmentName;
			GetNextCharacterAttachmentName(attachmentName);

			IAttachmentManager* pAttachmentManager = pCharacterInstace->GetIAttachmentManager();
			CRY_ASSERT(pAttachmentManager);
			
			//Remove the attachment first (in case was created before)
			pAttachmentManager->RemoveAttachmentByName(attachmentName.c_str());

			//Create attachment on nearest hit bone
			IAttachment* pAttachment = pAttachmentManager->CreateAttachment(attachmentName.c_str(), CA_BONE, boneName, false);
			if (pAttachment)
			{
				//Apply relative offsets
				const QuatT boneLocation = pSkeletonPose->GetAbsJointByID(params.partID);
				Matrix34 inverseJointTM = targetEntity.GetWorldTM() * Matrix34(boneLocation);
				inverseJointTM.Invert();
				Vec3 attachmentOffsetPosition = inverseJointTM * params.pos;
				Quat attachmentOffsetRotation = Quat(inverseJointTM) * targetEntity.GetRotation();

				CRY_ASSERT(attachmentOffsetPosition.IsValid());
				//CRY_ASSERT(attachmentOffsetRotation.IsUnit());

				pAttachment->SetAttRelativeDefault(QuatT(attachmentOffsetRotation, attachmentOffsetPosition));

				//Finally attach the effect
				CEffectAttachment* pEffectAttachment = new CEffectAttachment(particleParams.name.c_str(), Vec3(0,0,0), dir, scale);
				pAttachment->AddBinding(pEffectAttachment);
				
				return true;
			}
		}
	}

	return false;
}
void CProceduralWeaponAnimationContext::Initialize(IScope* pScope)
{
	++m_instanceCount;

	if (m_pScope != 0)
		return;

	m_pScope = pScope;
	ICharacterInstance* pCharacter = m_pScope->GetCharInst();
	if (pCharacter)
	{
		CryCreateClassInstance("AnimationPoseModifier_OperatorQueue", m_pPoseModifier);
		m_params = SParams(pCharacter->GetIDefaultSkeleton());
	}
}
//------------------------------------------------------------------------
Vec3 CVehicleViewFirstPerson::GetWorldPosGoal()
{
	Vec3 vehiclePos;

	if (m_pHelper)
	{
		vehiclePos = m_pHelper->GetVehicleSpaceTranslation();
	}
	else if(!m_sCharacterBoneName.empty())
	{
		Vec3 bonePos;
		IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_pSeat->GetPassenger());
		ICharacterInstance* pCharacter = pEntity ? pEntity->GetCharacter(0) : NULL;
		if(pCharacter)
		{
			IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton();
			uint32 id = rIDefaultSkeleton.GetJointIDByName(m_sCharacterBoneName);
			uint32 numJoints = rIDefaultSkeleton.GetJointCount();
			if(numJoints > id)
			{
				bonePos = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t;
			}
		}
		vehiclePos = pEntity ? pEntity->GetWorldTM() * bonePos : Vec3(0,0,0);	
		return vehiclePos;
	}
	else
	{
		IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId);
		CRY_ASSERT(pActor);

		vehiclePos = pActor->GetLocalEyePos() + m_offset;

		IEntity* pActorEntity = pActor->GetEntity();
		
		const Matrix34& slotTM = pActorEntity->GetSlotLocalTM(0, false);
    vehiclePos = pActorEntity->GetLocalTM() * slotTM * vehiclePos;
	}

	return m_pVehicle->GetEntity()->GetWorldTM() * vehiclePos;
}
//------------------------------------------------------------------------
void CVehicleViewFirstPerson::OnStartUsing(EntityId passengerId)
{
  CVehicleViewBase::OnStartUsing(passengerId);
	
	if(!m_sCharacterBoneName.empty())
	{
		bool errorOccurred = false;
		IEntity* pEntity = gEnv->pEntitySystem->GetEntity(passengerId);
		ICharacterInstance* pCharacter = pEntity ? pEntity->GetCharacter(0) : NULL;
		if(pCharacter)
		{
			IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton();
			uint32 id = rIDefaultSkeleton.GetJointIDByName(m_sCharacterBoneName);
			uint32 numJoints = rIDefaultSkeleton.GetJointCount();
			if(numJoints <= id)
			{
				errorOccurred = true;
			}
		}
		else
		{
			errorOccurred = true;
		}

		if(errorOccurred)
		{
			GameWarning("[%s, seat %s]: character Bone name %s not found", m_pVehicle->GetEntity()->GetName(), m_pSeat->GetName().c_str(), m_sCharacterBoneName.c_str());
		}
		else if (m_pHelper)
		{
			GameWarning("[%s, seat %s]: helper and character Bone name found, helper will be used (please only use one of these options)", m_pVehicle->GetEntity()->GetName(), m_pSeat->GetName().c_str());
		}
	}

  if (m_hideVehicle)
  {
    m_slotFlags.clear();
    HideEntitySlots(m_pVehicle->GetEntity(), true);
  }

  if (m_frameSlot != -1)
  {
    m_pVehicle->GetEntity()->SetSlotFlags(m_frameSlot, m_pVehicle->GetEntity()->GetSlotFlags(m_frameSlot) | ENTITY_SLOT_RENDER|ENTITY_SLOT_RENDER_NEAREST);    
  }

	m_passengerId = passengerId;

	m_viewPosition = GetWorldPosGoal();
	m_viewRotation = GetWorldRotGoal();

	if (m_passengerId && m_pSeat && !m_pSeat->IsDriver() && m_pSeat->IsPassengerShielded())
	{		
		// disable rendering of ocean for passenger of amphibious vehicles (we see water inside the cabin)
		if (IVehicleMovement *pMovement=m_pVehicle->GetMovement())
		{			
			if (pMovement->GetMovementType()==IVehicleMovement::eVMT_Amphibious)
			{
				I3DEngine *p3DEngine=gEnv->p3DEngine;
				p3DEngine->SetOceanRenderFlags(OCR_NO_DRAW);
			}
		}
	}

	if (m_hidePlayer)
	{
		if (IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_passengerId))
			HideEntitySlots(pEntity, true);
	}

	m_pVehicle->RegisterVehicleEventListener(this, "1stPersonView");
}
Example #6
0
//--------------------------------------------------------------------------------------------------
// Name: SpawnParticlesOnSkeleton
// Desc: Spawn particles on Skeleton
//--------------------------------------------------------------------------------------------------
void CGameEffect::SpawnParticlesOnSkeleton(IEntity* pEntity, IParticleEmitter* pParticleEmitter, uint32 numParticles,float maxHeightScale) const
{
	if((pEntity) && (numParticles>0) && (pParticleEmitter) && (maxHeightScale>0.0f))
	{
		ICharacterInstance* pCharacter = pEntity->GetCharacter(0);
		if(pCharacter)
		{
			IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton();
			ISkeletonPose* pPose = pCharacter->GetISkeletonPose();
			if(pPose)
			{
				Vec3 animPos;
				Quat animRot;

				IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId());
				if(pActor) // First try to get animation data
				{
					QuatT animLoc = pActor->GetAnimatedCharacter()->GetAnimLocation();
					animPos = animLoc.t;
					animRot = animLoc.q;
				}
				else // If no actor, then use entity data
				{
					animPos = pEntity->GetWorldPos();
					animRot = pEntity->GetWorldRotation();
				}

				animRot.Invert();

				AABB bbox;
				pEntity->GetLocalBounds(bbox);
				float bbHeight = bbox.max.z - bbox.min.z;
				// Avoid division by 0
				if(bbHeight == 0)
				{
					bbHeight = 0.0001f;
				}

				const uint32 numJoints = rIDefaultSkeleton.GetJointCount();

				for (uint32 i = 0; i < numParticles; ++i)
				{
					int id = cry_random(0U, numJoints - 1);
					int parentId = rIDefaultSkeleton.GetJointParentIDByID(id);

					if(parentId>0)
					{
						QuatT boneQuat = pPose->GetAbsJointByID(id);
						QuatT parentBoneQuat= pPose->GetAbsJointByID(parentId);
						float lerpScale = cry_random(0.0f, 1.0f);

						QuatTS loc(IDENTITY);
						loc.t = LERP(boneQuat.t,parentBoneQuat.t,lerpScale);

						float heightScale = ((loc.t.z - bbox.min.z) / bbHeight);
						if(heightScale < maxHeightScale)
						{
							loc.t = loc.t * animRot;
							loc.t = loc.t + animPos;

							pParticleEmitter->EmitParticle(NULL, NULL, &loc);
						}
					}
				}
			}
		}
	}
}//-------------------------------------------------------------------------------------------------
Example #7
0
//-----------------------------------------------------------------------
void CSpectacularKill::ReadXmlData( const IItemParamsNode* pRootNode)
{
	CRY_ASSERT(pRootNode);

	ISharedParamsManager* pSharedParamsManager = gEnv->pGame->GetIGameFramework()->GetISharedParamsManager();
	CRY_ASSERT(pSharedParamsManager);

	// If we change the SharedParamsManager to accept CRCs on its interface we could compute this once and store
	// the name's CRC32 instead of constructing it here each time this method is invoked (it shouldn't be invoked 
	// too often, though)
	const char* szEntityClassName = m_pOwner->GetEntityClassName();
	CryFixedStringT<64>	sharedParamsName;
	sharedParamsName.Format("%s_%s", SSharedSpectacularParams::s_typeInfo.GetName(), szEntityClassName);

	ISharedParamsConstPtr pSharedParams = pSharedParamsManager->Get(sharedParamsName);
	if (pSharedParams)
	{
		m_pParams = CastSharedParamsPtr<SSharedSpectacularParams>(pSharedParams);
		return;
	}

	m_pParams.reset();

	const IItemParamsNode* pParams = pRootNode->GetChild("SpectacularKill");
	if (pParams)
	{
		SSharedSpectacularParams newParams;

		const int childCount = pParams->GetChildCount();
		newParams.paramsList.reserve(childCount);

		for (int i = 0; i < childCount; ++i)
		{
			const IItemParamsNode* pTargetParams = pParams->GetChild(i);
			CRY_ASSERT(pTargetParams);

			IEntityClass* pTargetClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(pTargetParams->GetName());
			if (pTargetClass)
			{
				SSpectacularKillParams targetParams;
				const IItemParamsNode* pChildParamsNode = pTargetParams->GetChild("Params");
				const IItemParamsNode* pChildAnimsNode = pTargetParams->GetChild("Anims");

				targetParams.pEnemyClass = pTargetClass;

				if(pChildParamsNode)
				{
					pChildParamsNode->GetAttribute("impulseScale", targetParams.impulseScale);

					const char* szImpulseBone = pChildParamsNode->GetAttributeSafe("impulseBone");
					ICharacterInstance* pCharacter = m_pOwner->GetEntity()->GetCharacter(0);
					targetParams.impulseBone = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName(szImpulseBone) : -1;
				}

				if(pChildAnimsNode)
				{
					const int animCount = pChildAnimsNode->GetChildCount();
					targetParams.animations.reserve(animCount);

					for(int j = 0; j < animCount; j++)
					{
						const IItemParamsNode* pAnimNode = pChildAnimsNode->GetChild(j);

						if(pAnimNode)
						{
							SSpectacularKillAnimation newAnimation;

							newAnimation.victimAnimation = pAnimNode->GetAttributeSafe("victimAnimation");
							newAnimation.killerAnimation = pAnimNode->GetAttributeSafe("killerAnimation");

							pAnimNode->GetAttribute("optimalDist", newAnimation.optimalDist);

							if (pAnimNode->GetAttribute("targetToKillerAngle", newAnimation.targetToKillerAngle))
								newAnimation.targetToKillerAngle = DEG2RAD(newAnimation.targetToKillerAngle);

							if (pAnimNode->GetAttribute("targetToKillerAngleRange", newAnimation.targetToKillerMinDot))
								newAnimation.targetToKillerMinDot = cos_tpl(DEG2RAD(newAnimation.targetToKillerMinDot) / 2.0f);

							pAnimNode->GetAttribute("obstacleCheckStartOffset", newAnimation.vKillerObstacleCheckOffset);
							pAnimNode->GetAttribute("obstacleCheckLength", newAnimation.fObstacleCheckLength);

							targetParams.animations.push_back(newAnimation);
						}
					}
				}

				CRY_ASSERT_MESSAGE(targetParams.animations.size() > 0, string().Format("No Animations defined for %s spectacular kill", pTargetClass->GetName()));

				newParams.paramsList.push_back(targetParams);
			}
#ifdef SPECTACULAR_KILL_DEBUG
			else
			{
				GameWarning("spectacular Kill: Couldn't find entity of class '%s', skipping", pTargetParams->GetName());
			}
#endif
		}

		m_pParams = CastSharedParamsPtr<SSharedSpectacularParams>(pSharedParamsManager->Register(sharedParamsName, newParams));
	}
}
Example #8
0
//------------------------------------------------------------------------
IStatObj* CVehiclePartAnimated::GetSubGeometry(CVehiclePartBase* pPart, EVehiclePartState state, Matrix34 &localTM, bool removeFromParent)
{
	ICharacterInstance* pCharInstance = 0;
	string              jointName;
	pPart->GetGeometryName(state, jointName);
	int jointId = -1;

	if (state == eVGS_Destroyed)
	{
		pCharInstance = m_pCharInstanceDestroyed;

		if (pCharInstance)
			jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str());
	}
	else
	{
		// lookup first on intact, then on destroyed model
		pCharInstance = m_pCharInstance;

		if (pCharInstance)
			jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str());

		if (jointId == -1)
		{
			pCharInstance = m_pCharInstanceDestroyed;

			if (pCharInstance)
				jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str());
		}
	}

	if (jointId != -1)
	{
		if (ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose())
		{
			localTM = Matrix34(pCharInstance->GetISkeletonPose()->GetAbsJointByID(jointId));

			if (IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(jointId))
			{
				if (removeFromParent && (pCharInstance != m_pCharInstanceDestroyed))
				{
					if (m_intactStatObjs.find(pPart->GetName()) == m_intactStatObjs.end())
					{
						m_intactStatObjs.insert(TStringStatObjMap::value_type(pPart->GetName(), pStatObj));
					}

					SetCGASlot(jointId, NULL);
				}

				if (pPart)
				{
					m_jointParts.insert(TStringVehiclePartMap::value_type(pPart->GetName(), pPart));
				}

				return pStatObj;
			}
			else if ((state == eVGS_Default) && (pPart->GetState() != eVGS_Default))
			{
				TStringStatObjMap::const_iterator it = m_intactStatObjs.find(pPart->GetName());

				if (it != m_intactStatObjs.end())
				{
					return it->second;
				}
			}
		}
	}

	return NULL;
}
void CVehicleWeaponControlled::Update(SEntityUpdateContext& ctx, int update)
{
	IVehicle *pVehicle = m_vehicleId ? gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId) : NULL; 
  if (!m_vehicleId && GetEntity()->GetParent())
  {
    IEntity *entity = GetEntity();
    
    if (entity)
    {
      IEntity *parent = entity->GetParent();
      if (parent)
      {
				m_vehicleId = parent->GetId();
        pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(parent->GetId());
      }
    }
  }



  if (pVehicle)
  {
		IVehiclePart *pPart = pVehicle->GetWeaponParentPart(GetEntityId());
		if(pPart)
		{
			if(IVehiclePart *pParentPart = pPart->GetParent())
			{
				CRY_ASSERT(pVehicle->GetEntity());

				if(ICharacterInstance *characterInst = pVehicle->GetEntity()->GetCharacter(pParentPart->GetSlot()))
				{
					if(ISkeletonPose* pose = characterInst->GetISkeletonPose())
					{
						IDefaultSkeleton& rIDefaultSkeleton = characterInst->GetIDefaultSkeleton();
						int16 joint = rIDefaultSkeleton.GetJointIDByName(pPart->GetName());
						const QuatT &jQuat = pose->GetAbsJointByID(joint);

						Matrix34 localT(jQuat);
						localT.SetTranslation(jQuat.t/* - Vec3(0.0f, 0.75f, 0.0f)*/);

						Matrix34 vehicleWorldTm = pVehicle->GetEntity()->GetWorldTM();
						Matrix34 mat = vehicleWorldTm * localT;
						Vec3 vehicleSide2 = pPart->GetParent()->GetLocalTM(true, true).GetTranslation();

						CPlayer *pl = this->GetOwnerPlayer();

						Matrix33 mat2;
						if (!m_destination.IsEquivalent(ZERO))
						{
							Vec3 diff = GetDestination() - mat.GetTranslation(); //pPart->GetWorldTM().GetTranslation();
							diff.Normalize();

							Matrix33 loc(mat);
							loc.Invert();

							Vec3 diffLocal = loc.TransformVector(diff);

							Matrix33 desMat;
							desMat.SetRotationVDir(diffLocal, 0.0f);

							Vec3 test = GetEntity()->GetLocalTM().GetColumn0();

							Ang3 testTM(desMat);

							float za = testTM.x - m_Angles.x;
							za = (za < 0.0f) ? -gf_PI : gf_PI;
							za *= 0.05f * ctx.fFrameTime;

							m_Angles.x += za;
							Limit(m_Angles.x, -gf_PI * 0.33f, gf_PI * 0.33f);

							if (testTM.z > m_Angles.z + 0.05f)
							{
								m_Angles.z += gf_PI * factor1 * ctx.fFrameTime;        
							}
							else if (testTM.z < m_Angles.z - 0.05f)
							{
								m_Angles.z -= gf_PI * factor1 * ctx.fFrameTime;        
							}
							else
							{
								m_Angles.z = testTM.z;
							}

							Limit(m_Angles.z, -gf_PI * 0.33f, gf_PI * 0.33f);
							mat2.SetRotationXYZ(m_Angles);
						}
						else
						{
							if (!m_FireBlocked)
							{
								m_Angles.x = m_Angles.x - ctx.fFrameTime * factor2 * m_Angles.x;
								m_Angles.z = m_Angles.z - ctx.fFrameTime * factor2 * m_Angles.z;
							}
							mat2.SetRotationXYZ(m_Angles);
						}

						mat = mat * mat2; 


						GetEntity()->SetWorldTM(mat);


						if (pl)
						{
							Matrix34 worldGunMat = vehicleWorldTm * localT;

							if (!pl->IsDead())
							{

								Vec3 trans = worldGunMat.GetTranslation() - worldGunMat.GetColumn2() * 0.7f;
								worldGunMat.SetTranslation(trans);

								pl->GetEntity()->SetWorldTM(worldGunMat);


								float dot = mat.GetColumn1().dot(worldGunMat.GetColumn0());
								Update3PAnim(pl, 0.5f - dot * 0.5f, ctx.fFrameTime, mat);
							}
							else
							{

								ICharacterInstance* pCharacter = pl->GetEntity()->GetCharacter(0);
								int boneId = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName("Spine03") : 7;

								pl->LinkToMountedWeapon(0);
								if (IVehicleSeat* seat = pVehicle->GetSeatForPassenger(pl->GetEntityId()))
								{
									seat->Exit(false, true);
								}

								Matrix33 rot(worldGunMat);
								Vec3 offset(0.0f, 0.0f, 0.70f);
								Vec3 transformedOff = rot.TransformVector(offset);
								Vec3 trans = worldGunMat.GetTranslation();
								trans -= transformedOff;
								worldGunMat.SetTranslation(trans);
								pl->GetEntity()->SetWorldTM(worldGunMat);
								pl->GetEntity()->SetPos(worldGunMat.GetTranslation()); //worldGunMat.GetTranslation());
								pl->RagDollize(true);

								if (boneId > -1)
								{
									IPhysicalEntity *physEnt = pl->GetEntity()->GetPhysics();
									if (physEnt)
									{
										pe_simulation_params simulationParams;
										physEnt->GetParams(&simulationParams);

										pe_params_pos pos;
										pos.pos = GetEntity()->GetPos();
										physEnt->SetParams(&pos);

										pe_action_impulse impulse;
										impulse.ipart = boneId;
										impulse.angImpulse = Vec3(0.0f, 0.0f, 1.0f);
										impulse.impulse = worldGunMat.GetColumn1() * -1.5f * simulationParams.mass;
										physEnt->Action(&impulse);
									}
								}

								StopUse(GetOwnerId());

								SetOwnerId(0);
								StopFire();

								m_FireBlocked = true;
							} // IsDead
						} // pl
					} // pose
				} // characterInst
			} // pParentPart
		} // pPart
	} // pVehicle

  Base::Update(ctx, update);
  RequireUpdate(eIUS_General);
}
Example #10
0
void CLaserBeam::FixAttachment(IEntity* pLaserEntity)
{
	m_usingEntityAttachment = false;

	IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
	CItem* pOwnerItem = static_cast<CItem*>(pItemSystem->GetItem(m_ownerEntityId));

	if (pOwnerItem)
	{
		IEntity* pOwnerEntity = pOwnerItem->GetEntity();
		IEntity* pAttachedEntity = pOwnerEntity;
		const char* attach_helper = "laser_term";

		Vec3 offset = pOwnerItem->GetSlotHelperPos(m_geometrySlot, attach_helper, false);

		if(m_geometrySlot == eIGS_FirstPerson)
		{
			if(pOwnerItem->IsAccessory())
			{
				EntityId parentId = pOwnerItem->GetParentId();

				if(parentId)
				{
					if(CItem* pParentItem = static_cast<CItem*>(pItemSystem->GetItem(parentId)))
					{
						const SAccessoryParams* pParams = pParentItem->GetAccessoryParams(pAttachedEntity->GetClass());

						attach_helper = pParams->attach_helper.c_str();
						pAttachedEntity = pParentItem->GetEntity();
					}
				}
			}

			if(pAttachedEntity)
			{
				ICharacterInstance *pCharacter = pAttachedEntity->GetCharacter(eIGS_FirstPerson);
				if (pCharacter)
				{
					IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager();

					IAttachment *pLaserAttachment = pAttachmentManager->GetInterfaceByName(LASER_ATTACH_NAME);

					if(!pLaserAttachment)
					{
						IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(attach_helper);

						if(pAttachment)
						{
							const char* pBone = pCharacter->GetIDefaultSkeleton().GetJointNameByID(pAttachment->GetJointID());

							pLaserAttachment = pAttachmentManager->CreateAttachment(LASER_ATTACH_NAME, CA_BONE, pBone);

							if(pLaserAttachment)
							{
								QuatT relative = pAttachment->GetAttRelativeDefault();

								if(pOwnerItem->GetEntity() != pAttachedEntity)
								 {
									Matrix34 mtx(relative);
									relative.t = relative * offset;
								}

								pLaserAttachment->SetAttRelativeDefault(relative);
							}
						}
					}

					if(pLaserAttachment)
					{
						CEntityAttachment* pEntAttach = new CEntityAttachment;

						pEntAttach->SetEntityId(m_laserEntityId);
						pLaserAttachment->AddBinding(pEntAttach);
						pLaserAttachment->HideAttachment(0);

						m_usingEntityAttachment = true;
					}		
				}
			}
		}	

		if(!m_usingEntityAttachment && pOwnerEntity)
		{
			pOwnerEntity->AttachChild(pLaserEntity);
			pLaserEntity->SetLocalTM(Matrix34::CreateTranslationMat(offset));
		}
	}
}
Example #11
0
//------------------------------------------------------------------------
EntityEffects::TAttachedEffectId CItem::AttachEffect(int slot, bool attachToAccessory, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime)
{
	if(!g_pGameCVars->i_particleeffects)
	{
		return 0;
	}
	
	Vec3 finalOffset(offset);
	string helperName(helper);

	if(attachToAccessory)
	{
		SEntitySlotInfo slotInfo;
		QuatT accessoryOffset;

		accessoryOffset.SetIdentity();
		const char* accessoryHelper = "";
		const char* accessoryName = NULL;

		const int numAccessories = m_accessories.size();

		for (int curIndex = 0; curIndex < numAccessories; curIndex++)
		{
			IEntity* pAccessory = gEnv->pEntitySystem->GetEntity(m_accessories[curIndex].accessoryId);

			if(pAccessory && pAccessory->GetSlotInfo(slot, slotInfo))
			{
				if(slotInfo.pStatObj)
				{
					accessoryOffset.t = slotInfo.pStatObj->GetHelperPos(helper);

					if(!accessoryOffset.t.IsZero())
					{
						accessoryOffset.q = pAccessory->GetRotation();
						accessoryOffset.t += pAccessory->GetPos();

						accessoryName = m_accessories[curIndex].pClass->GetName();
						break;
					}
				}

				if(slotInfo.pCharacter)
				{
					IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager();
					IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper);

					if(pAttachment)
					{
						accessoryHelper = GetAccessoryParams(m_accessories[curIndex].pClass)->attach_helper.c_str();
						accessoryName = m_accessories[curIndex].pClass->GetName();

						accessoryOffset = pAttachment->GetAttAbsoluteDefault();

						break;
					}
				}
			}
		}

		if(accessoryName)
		{
			bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj);

			if (!validSlot || slotInfo.pStatObj)
			{
				if (validSlot)
				{
					Matrix34 mtx = GetEntity()->GetSlotLocalTM(slot, false) * Matrix34(accessoryOffset);
					finalOffset += mtx.GetTranslation();				
				}
			
				EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last);

				return m_effectsController.AttachParticleEffect(effectName, attachParams);
			}
			else if (slotInfo.pCharacter)	// bone attachment
			{
				ICharacterInstance *pCharacter = slotInfo.pCharacter;
				IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager();
				IAttachment *pAttachment = NULL; 

				helperName = string().Format("%s_%s", helper, accessoryName);
				pAttachment = pAttachmentManager->GetInterfaceByName(helperName.c_str());

				if(!pAttachment)
				{
					IAttachment* pAccessoryAttachment = pAttachmentManager->GetInterfaceByName(accessoryHelper);

					if(pAccessoryAttachment)
					{
						const char* bone = pCharacter->GetIDefaultSkeleton().GetJointNameByID(pAccessoryAttachment->GetJointID());
						pAttachment = pAttachmentManager->CreateAttachment(helperName.c_str(), CA_BONE, bone);
						if (pAttachment)
						{
							QuatT relative = pAccessoryAttachment->GetAttRelativeDefault();
							relative = relative * accessoryOffset;
							relative.t = relative * finalOffset;

							finalOffset.zero();

							pAttachment->SetAttRelativeDefault(relative);
						}
					}
				}
			}
		}
	}

	EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last);
	return m_effectsController.AttachParticleEffect(effectName, slot, helperName, attachParams);
}
Example #12
0
ILINE bool InitializePoseAlignerDeer(PoseAligner::CPose& pose, IEntity& entity, ICharacterInstance& character)
{
	IDefaultSkeleton& rIDefaultSkeleton = character.GetIDefaultSkeleton();
	int jointIndexRoot = rIDefaultSkeleton.GetJointIDByName("Def_COG_jnt");
	if (jointIndexRoot < 0)
		return false;
	int jointIndexBackLeft = rIDefaultSkeleton.GetJointIDByName("Def_L_ToeEnd_jnt");
	if (jointIndexBackLeft < 0)
		return false;
	int jointIndexBackRight = rIDefaultSkeleton.GetJointIDByName("Def_R_ToeEnd_jnt");
	if (jointIndexBackRight < 0)
		return false;
	int jointIndexFrontLeft = rIDefaultSkeleton.GetJointIDByName("Def_L_WristEnd_jnt");
	if (jointIndexFrontLeft < 0)
		return false;
	int jointIndexFrontRight = rIDefaultSkeleton.GetJointIDByName("Def_R_WristEnd_jnt");
	if (jointIndexFrontRight < 0)
		return false;

	if (!pose.Initialize(entity, jointIndexRoot))
		return false;

	pose.SetRootOffsetMinMax(-0.1f, 0.04f);

	PoseAligner::SChainDesc chainDesc;
	chainDesc.name = "Left";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "LftLeg01";
	chainDesc.contactJointIndex = jointIndexBackLeft;
	chainDesc.bBlendProcedural = true;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.4f);

	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "Left";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "RgtLeg01";
	chainDesc.contactJointIndex = jointIndexBackRight;
	chainDesc.bBlendProcedural = true;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.4f);

	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "FrontLeft";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "LftArm01";
	chainDesc.contactJointIndex = jointIndexFrontLeft;
	chainDesc.bBlendProcedural = true;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.02f);

	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "FrontRight";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "RgtArm01";
	chainDesc.contactJointIndex = jointIndexFrontRight;
	chainDesc.bBlendProcedural = true;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -0.05f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.02f);

	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	return pose.GetChainCount() != 0;
}
Example #13
0
ILINE bool InitializePoseAlignerScorcher(PoseAligner::CPose& pose, IEntity& entity, ICharacterInstance& character)
{
	IDefaultSkeleton& rIDefaultSkeleton = character.GetIDefaultSkeleton();
	int jointIndexRoot = rIDefaultSkeleton.GetJointIDByName("hips_joint");
	if (jointIndexRoot < 0)
		return false;
	int jointIndexBackLeft = rIDefaultSkeleton.GetJointIDByName("l_bwd_leg_end_joint");
	if (jointIndexBackLeft < 0)
		return false;
	int jointIndexBackLeftBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightBackLeft");
	if (jointIndexBackLeftBlend < 0)
		return false;
	int jointIndexBackRight = rIDefaultSkeleton.GetJointIDByName("r_bwd_leg_end_joint");
	if (jointIndexBackRight < 0)
		return false;
	int jointIndexBackRightBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightBackRight");
	if (jointIndexBackRightBlend < 0)
		return false;
	int jointIndexFrontLeft = rIDefaultSkeleton.GetJointIDByName("l_fwd_leg_end_joint");
	if (jointIndexFrontLeft < 0)
		return false;
	int jointIndexFrontLeftBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightFrontLeft");
	if (jointIndexFrontLeftBlend < 0)
		return false;
	int jointIndexFrontRight = rIDefaultSkeleton.GetJointIDByName("r_fwd_leg_end_joint");
	if (jointIndexFrontRight < 0)
		return false;
	int jointIndexFrontRightBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightFrontRight");
	if (jointIndexFrontRightBlend < 0)
		return false;

	if (!pose.Initialize(entity, jointIndexRoot))
		return false;

	pose.SetRootOffsetMinMax(-1.0f, 1.0f);

	PoseAligner::SChainDesc chainDesc;
	chainDesc.name = "Left";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "LftLeg01";
	chainDesc.contactJointIndex = jointIndexBackLeft;
	chainDesc.targetBlendJointIndex = jointIndexBackLeftBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f);
	chainDesc.bTargetSmoothing = true;
	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "Left";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "RgtLeg01";
	chainDesc.contactJointIndex = jointIndexBackRight;
	chainDesc.targetBlendJointIndex = jointIndexBackRightBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f);
	chainDesc.bTargetSmoothing = true;
	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "FrontLeft";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "LftArm01";
	chainDesc.contactJointIndex = jointIndexFrontLeft;
	chainDesc.targetBlendJointIndex = jointIndexFrontLeftBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f);
	chainDesc.bTargetSmoothing = true;
	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "FrontRight";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "RgtArm01";
	chainDesc.contactJointIndex = jointIndexFrontRight;
	chainDesc.targetBlendJointIndex = jointIndexFrontRightBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, -1.0f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, 0.15f);
	chainDesc.bTargetSmoothing = true;
	if (PoseAligner::CContactRaycastPtr pContactRaycast = new PoseAligner::CContactRaycast(entity))
	{
		pContactRaycast->SetLength(1.0f);
		chainDesc.pContactReporter = pContactRaycast;
	}
	if (!pose.CreateChain(chainDesc))
		return false;

	return pose.GetChainCount() != 0;
}
Example #14
0
ILINE bool InitializePoseAlignerPinger(PoseAligner::CPose& pose, IEntity& entity, ICharacterInstance& character)
{
	IDefaultSkeleton& rIDefaultSkeleton = character.GetIDefaultSkeleton();

	const bool bIsMP = gEnv->bMultiplayer;

	IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(entity.GetId());
	if (bIsMP && !pVehicle)
		return false;

#define CREATEPINGERCONTACTREPORTER \
	if(bIsMP) \
	{ \
		if (_smart_ptr<CContactRaycastPinger> pContactRaycast = new CContactRaycastPinger(*pVehicle,3.f)) \
		{ \
			chainDesc.pContactReporter = pContactRaycast; \
		} \
	} \
	else \
	{ \
		if (_smart_ptr<PoseAligner::CContactRaycast> pContactRaycast = new PoseAligner::CContactRaycast(entity)) \
		{ \
			pContactRaycast->SetLength(4.f); \
			chainDesc.pContactReporter = pContactRaycast; \
		} \
	}

	int jointIndexRoot = rIDefaultSkeleton.GetJointIDByName("Pelvis");
	if (jointIndexRoot < 0)
		return false;
	int jointIndexFrontLeft = rIDefaultSkeleton.GetJointIDByName("planeAlignerLeft");
	if (jointIndexFrontLeft < 0)
		return false;
	int jointIndexFrontLeftBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightLeft");
	if (jointIndexFrontLeftBlend < 0)
		return false;
	int jointIndexFrontRight = rIDefaultSkeleton.GetJointIDByName("planeAlignerRight");
	if (jointIndexFrontRight < 0)
		return false;
	int jointIndexFrontRightBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightRight");
	if (jointIndexFrontRightBlend < 0)
		return false;
	int jointIndexFrontCenter = rIDefaultSkeleton.GetJointIDByName("planeAlignerCenter");
	if (jointIndexFrontCenter < 0)
		return false;
	int jointIndexFrontCenterBlend = rIDefaultSkeleton.GetJointIDByName("planeLockWeightCenter");
	if (jointIndexFrontCenterBlend < 0)
		return false;

	if (!pose.Initialize(entity, jointIndexRoot))
		return false;

	PoseAligner::SChainDesc chainDesc;
	chainDesc.name = "Left";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "LftLeg01";
	chainDesc.contactJointIndex = jointIndexFrontLeft;
	chainDesc.targetBlendJointIndex = jointIndexFrontLeftBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, bIsMP?-1.8f:-1.8f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, bIsMP?+0.75f:+1.f);
	chainDesc.bForceNoIntersection = true;

	float rootMax = -chainDesc.offsetMin.z;
	float rootMin = -chainDesc.offsetMax.z;

	CREATEPINGERCONTACTREPORTER;

	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "Right";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "RgtLeg01";
	chainDesc.contactJointIndex = jointIndexFrontRight;
	chainDesc.targetBlendJointIndex = jointIndexFrontRightBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, bIsMP?-1.8f:-1.8f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, bIsMP?+0.75f:+1.f);
	chainDesc.bForceNoIntersection = true;

	rootMax = min(rootMax,-chainDesc.offsetMin.z);
	rootMin = max(rootMin,-chainDesc.offsetMax.z);

	CREATEPINGERCONTACTREPORTER;

	if (!pose.CreateChain(chainDesc))
		return false;

	chainDesc.name = "Center";
	chainDesc.eType = IAnimationPoseAlignerChain::eType_Limb;
	chainDesc.solver = "CtrLeg01";
	chainDesc.contactJointIndex = jointIndexFrontCenter;
	chainDesc.targetBlendJointIndex = jointIndexFrontCenterBlend;
	chainDesc.offsetMin = Vec3(0.0f, 0.0f, bIsMP?-2.f:-2.f);
	chainDesc.offsetMax = Vec3(0.0f, 0.0f, bIsMP?+1.3f:+1.6f);
	chainDesc.bForceNoIntersection = true;

	rootMax = min(rootMax,-chainDesc.offsetMin.z);
	rootMin = max(rootMin,-chainDesc.offsetMax.z);

	CREATEPINGERCONTACTREPORTER;

	pose.SetRootOffsetMinMax(rootMin, rootMax);
	pose.SetRootOffsetAverage(!bIsMP);

	if (!pose.CreateChain(chainDesc))
		return false;

	return pose.GetChainCount() != 0;
}
const Vec3& CTacticalManager::GetTacticalIconWorldPos(const EntityId tacticalEntityId, IEntity* pTacticalEntity, bool& inOutIsHeadBone)
{
	CRY_ASSERT(tacticalEntityId != 0);
	CRY_ASSERT(pTacticalEntity != NULL);
	if (pTacticalEntity == NULL)
	{
		return m_tempVec3.Set(0.0f,0.0f,0.0f);
	}

	// Try to get pos from headbone if don't have an override pos
	TTacticalEntityToOverrideEntities::const_iterator iter = m_tacEntityToOverrideEntities.find(tacticalEntityId);
	if (iter == m_tacEntityToOverrideEntities.end()) 
	{
		static IEntityClass* s_pTurretEntityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Turret");

		IEntityClass* pEntityClass = pTacticalEntity->GetClass();
		if (pEntityClass != NULL && pEntityClass == s_pTurretEntityClass)
		{
			ICharacterInstance* pCharacterInstance = pTacticalEntity->GetCharacter(0);
			if (pCharacterInstance != NULL)
			{
				IDefaultSkeleton& rIDefaultSkeleton = pCharacterInstance->GetIDefaultSkeleton();
				ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose();
				CRY_ASSERT(pSkeletonPose != NULL);

				const int16 jointId = rIDefaultSkeleton.GetJointIDByName("arcjoint");
				if (0 <= jointId)
				{
					QuatT boneLocation = pSkeletonPose->GetAbsJointByID(jointId);
					m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t);
					return m_tempVec3;
				}
			}
		}


		CUICVars* pCVars = g_pGame->GetUI()->GetCVars();
		if (pCVars->hud_InterestPointsAtActorsHeads == 1)
		{
			CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(tacticalEntityId)); // Only want units to go from headbone, since vehicles have headbone as well
			if(pActor)
			{
				if(pActor->HasBoneID(BONE_HEAD))
				{
					QuatT boneLocation = pActor->GetBoneTransform(BONE_HEAD);
					m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t) + Vec3(0.0f, 0.0f, 0.25f);
					inOutIsHeadBone = true;
					return m_tempVec3;
				}
				else if(pActor->HasBoneID(BONE_SPINE))
				{
					QuatT boneLocation = pActor->GetBoneTransform(BONE_SPINE);
					m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t);
					return m_tempVec3;
				}
			}
		}

		return GetTacticalIconCenterBBoxWorldPos(pTacticalEntity);
	}
	else // Override entity exists so it determines position
	{
		IEntity* pOverrideEntity = gEnv->pEntitySystem->GetEntity(iter->second);
		if (pOverrideEntity)
		{
			m_tempVec3 = pOverrideEntity->GetWorldPos();
			return m_tempVec3;
		}
		else
		{
			GameWarning("CTacticalManager::GetTacticalIconWorldPos: ID exists in mapping but failed to find entity, defaulting to center bounding box position");
			return GetTacticalIconCenterBBoxWorldPos(pTacticalEntity);
		}
	}
}
bool CVehiclePartSuspensionPart::Init(IVehicle *pVehicle, const CVehicleParams &table, IVehiclePart *pParent, CVehicle::SPartInitInfo &initInfo, int partType)
{
	if (!inherited::Init(pVehicle, table, pParent, initInfo, partType))
		return false;
	
	m_animatedRoot = CAST_VEHICLEOBJECT(CVehiclePartAnimated, GetParent(true));
	m_jointId = -1;
	m_ikFlags = 0;

	if (m_animatedRoot)
	{
		if(CVehicleParams subPartTable = table.findChild("SubPart"))
		{
			// We need to remove this part from the animated root, otherwise we have two parts
			// NB: for now we are not doing anything with the physics - infact its preferable
			// if we dont have physics on suspension arms!
			const char*	geoName = subPartTable.getAttr("geometryname");
			ICharacterInstance* pCharInstance = m_animatedRoot->GetEntity()->GetCharacter(m_animatedRoot->GetSlot());
			if (pCharInstance)
			{
				IDefaultSkeleton& rIDefaultSkeleton = pCharInstance->GetIDefaultSkeleton();
				ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose();
				m_jointId = rIDefaultSkeleton.GetJointIDByName(geoName);
				pSkeletonPose->SetStatObjOnJoint(m_jointId, NULL);
			}
		}
	}
	else
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CVehiclePartSuspensionPart: needs to have an AnimatedPart as a parent!");
		return false;
	}

	CVehicleParams ikTable = table.findChild("IK");
	if (!ikTable)
		return false;

	const char* targetPartName = ikTable.getAttr("target");
	m_targetPart = static_cast<CVehiclePartBase*>(pVehicle->GetPart(targetPartName));
	if (m_targetPart==NULL)
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CVehiclePartSuspensionPart: couldn't find target part: '%s'", targetPartName);
		return false;
	}

	// Set up the target
	m_targetOffset.zero();
	const char* targetHelper = ikTable.getAttr("targetHelper");
	if (targetHelper && targetHelper[0])
	{
		if (IVehicleHelper* pHelper = m_pVehicle->GetHelper(targetHelper))
		{
			// NB: this is in vehicle space, and needs translating in PostInit()
			m_targetOffset = pHelper->GetLocalTM().GetTranslation();
			m_ikFlags |= k_flagTargetHelper;
		}
	}
	Vec3 offset(0);
	ikTable.getAttr("offset", offset);
	m_targetOffset += offset;
	
	m_mode = k_modeStretch;
	const char* mode = ikTable.getAttr("mode");
	if (strcmp(mode,"rotate")==0)
		m_mode = k_modeRotate;
	if (strcmp(mode,"stretch")==0)
		m_mode = k_modeStretch;
	if (strcmp(mode,"snap")==0)
		m_mode = k_modeSnapToEF;
			
	bool bIgnoreTargetRotation=0;
	ikTable.getAttr("ignoreTargetRotation", bIgnoreTargetRotation);
	if (bIgnoreTargetRotation)
		m_ikFlags |= k_flagIgnoreTargetRotation;

	return true;
}