TItemName CGameStateRecorder::GetItemName(EntityId id, CItem** pItemOut)
{
	if(id)
	{
		CItem* pItem = (CItem*)(gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(id));
		if(pItem && pItem->GetEntity())
		{
			if(pItemOut)
				*pItemOut = pItem;
			return pItem->GetEntity()->GetName();
		}
	}
	return 0;
}
IAttachmentManager* CLaserBeam::GetLaserCharacterAttachmentManager()
{
	IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
	CItem* pOwnerItem = static_cast<CItem*>(pItemSystem->GetItem(m_ownerEntityId));

	if (pOwnerItem)
	{
		IEntity* pAttachedEntity = pOwnerItem->GetEntity();

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

			if(parentId)
			{
				if(IEntity* pParentEnt = gEnv->pEntitySystem->GetEntity(parentId))
				{
					pAttachedEntity = pParentEnt;
				}
			}
		}				

		if (ICharacterInstance *pCharacter = pAttachedEntity->GetCharacter(eIGS_FirstPerson))
		{
			return pCharacter->GetIAttachmentManager();				
		}
	}

	return NULL;
}
//------------------------------------------------------------------------
void CItem::ReAttachAccessory(const ItemString &name)
{
	CItem *pAccessory = GetAccessory(name);
	SAccessoryParams *params = GetAccessoryParams(name);

	if(pAccessory && params)
	{
		SetCharacterAttachment(eIGS_FirstPerson, params->attach_helper.c_str(), pAccessory->GetEntity(), eIGS_FirstPerson, 0);

		Vec3 position = GetSlotHelperPos(eIGS_ThirdPerson, params->attach_helper.c_str(), false);
		GetEntity()->AttachChild(pAccessory->GetEntity());
		Matrix34 tm(Matrix34::CreateIdentity());
		tm.SetTranslation(position);
		pAccessory->GetEntity()->SetLocalTM(tm);
		pAccessory->SetParentId(GetEntityId());
		pAccessory->Physicalize(false, false);
		PlayLayer(params->attach_layer, eIPAF_Default|eIPAF_NoBlend);
	}
}
Exemple #4
0
//------------------------------------------------------------------------
int CScriptBind_Item::CanUseVehicle(IFunctionHandler *pH, ScriptHandle userId)
{
	CItem *pItem = GetItem(pH);
	if (!pItem)
		return pH->EndFunction();

	IEntity* pParent = pItem->GetEntity()->GetParent();
	if(pParent)
	{
		IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pParent->GetId());
		if(pVehicle)
		{
			return pH->EndFunction(pVehicle->IsUsable((EntityId)userId.n));
		}
	}

	return pH->EndFunction(pItem->CanUse((EntityId)userId.n));
}
int CScriptBind_Weapon::GetAccessory(IFunctionHandler *pH, const char *accessoryName)
{
	CWeapon *pWeapon = GetWeapon(pH);
	if (!pWeapon)
		return pH->EndFunction();

	CItem *pItem = pWeapon->GetAccessory(accessoryName);					
	
	if(!pItem)
		return 0;

	IEntity *pEntity  = pItem->GetEntity();

	if(!pEntity)
		return 0;
	
	IScriptTable *pScriptTable = pEntity->GetScriptTable();

	return pH->EndFunction( pScriptTable );
}
//------------------------------------------------------------------------
void CItem::AttachAccessoryPlaceHolder(const ItemString &name, bool attach)
{
	const SAccessoryParams *params = GetAccessoryParams(name);

	if(!params)
		return;

	CItem *pPlaceHolder = GetAccessoryPlaceHolder(name);

	if(!pPlaceHolder)
		return;

	if(attach)
	{
		SetCharacterAttachment(eIGS_FirstPerson, params->attach_helper, pPlaceHolder->GetEntity(), eIGS_FirstPerson, 0);
		PlayLayer(params->attach_layer, eIPAF_FirstPerson, false);
	}
	else
	{
		ResetCharacterAttachment(eIGS_FirstPerson, params->attach_helper);
		StopLayer(params->attach_layer, eIPAF_FirstPerson, false);
	}
}
void CPlayerRotation::GetStanceAngleLimits(float &minAngle,float &maxAngle)
{
	EStance stance = m_player.GetStance();

	switch(stance)
	{
	default:
	case STANCE_CROUCH:
	case STANCE_STAND:
		minAngle = -80.0f;
		maxAngle = 80.0f;
		break;

	case STANCE_PRONE:
		minAngle = -35.0f;
		maxAngle = 45.0f;
		break;
	}

	//Limit camera rotation on ladders(to prevent clipping)
	if(m_player.m_stats.isOnLadder)
	{
		minAngle = -40.0f;
		maxAngle = 80.0f;
	}

	if(m_stats.grabbedHeavyEntity!=0)
	{
		minAngle = -35.0f;  //Limit angle to prevent clipping, throw objects at feet, etc...
	}

	// SNH: additional restriction based on weapon type if prone.
	if(m_player.GetStance() == STANCE_PRONE && g_pGameCVars->g_proneAimAngleRestrict_Enable != 0)
	{
		float dist = 0.0f;
		CItem *pItem = (CItem *)(m_player.GetCurrentItem());

		if(pItem)
			dist = pItem->GetParams().raise_distance;

		SMovementState movestate;
		m_player.m_pMovementController->GetMovementState(movestate);

		// try a cylinder intersection test
		IPhysicalEntity *pIgnore[2];
		pIgnore[0] = m_player.GetEntity()->GetPhysics();
		pIgnore[1] = pItem ? pItem->GetEntity()->GetPhysics() : NULL;

		primitives::cylinder cyl;
		cyl.r = 0.05f;
		cyl.axis = movestate.aimDirection;
		cyl.hh = dist;
		cyl.center = movestate.weaponPosition + movestate.aimDirection*cyl.hh;

		//gEnv->pRenderer->GetIRenderAuxGeom()->DrawCylinder(cyl.center, cyl.axis, cyl.r, cyl.hh, ColorF(0.4f,1.0f,0.6f, 0.2f));

		float n = 0.0f;
		geom_contact *contacts;
		intersection_params params;
		WriteLockCond lockContacts;
		params.bStopAtFirstTri = false;
		params.bSweepTest = false;
		params.bNoBorder = true;
		params.bNoAreaContacts = true;
		n = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(primitives::cylinder::type, &cyl, Vec3(0,0,2),
				ent_static|ent_terrain, &contacts, 0,
				geom_colltype_player, &params, 0, 0, pIgnore, pIgnore[1]?2:1), lockContacts;
		int ret = (int)n;

		geom_contact *currentc = contacts;

		for(int i=0; i<ret; i++)
		{
			geom_contact *contact = currentc;

			if(contact && (fabs_tpl(contact->n.z)>0.2f))
			{
				Vec3 dir = contact->pt - movestate.weaponPosition;
				dir.NormalizeSafe();
				Vec3 horiz = dir;
				horiz.z = 0.0f;
				horiz.NormalizeSafe();
				float cosangle = dir.Dot(horiz);
				Limit(cosangle, -1.0f, 1.0f);
				float newMin = acos_tpl(cosangle);
				newMin = -newMin * 180.0f / gf_PI;
				//float col[] = {1,1,1,1};
				//gEnv->pRenderer->Draw2dLabel(100,100, 1.0f, col, false, "minangle: %.2f", newMin);
				//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(contact->pt, 0.03f, ColorF(1,0,0,1));
				minAngle = MAX(newMin, minAngle);
			}

			++currentc;
		}
	}

	minAngle *= gf_PI/180.0f;
	maxAngle *= gf_PI/180.0f;
}
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->GetICharacterModel()->GetICharacterModelSkeleton()->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));
		}
	}
}
void CMountedGunController::Update(EntityId mountedGunID, float frameTime)
{
    CRY_ASSERT_MESSAGE(m_pControlledPlayer, "Controlled player not initialized");

    CItem* pMountedGun = static_cast<CItem*>(gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(mountedGunID));

    bool canUpdateMountedGun = (pMountedGun != NULL) && (pMountedGun->GetStats().mounted);

    if (canUpdateMountedGun)
        {
            IMovementController * pMovementController = m_pControlledPlayer->GetMovementController();
            assert(pMovementController);

            SMovementState info;
            pMovementController->GetMovementState(info);

            IEntity* pMountedGunEntity = pMountedGun->GetEntity();
            const Matrix34& lastMountedGunWorldTM = pMountedGunEntity->GetWorldTM();

            Vec3 desiredAimDirection = info.aimDirection.GetNormalized();

            // AI can switch directions too fast, prevent snapping
            if(!m_pControlledPlayer->IsPlayer())
                {
                    const Vec3 currentDir = lastMountedGunWorldTM.GetColumn1();
                    const float dot = clamp(currentDir.Dot(desiredAimDirection), -1.0f, 1.0f);
                    const float reqAngle = cry_acosf(dot);
                    const float maxRotSpeed = 2.0f;
                    const float maxAngle = frameTime * maxRotSpeed;
                    if(fabs(reqAngle) > maxAngle)
                        {
                            const Vec3 axis = currentDir.Cross(desiredAimDirection);
                            if(axis.GetLengthSquared() > 0.001f) // current dir and new dir are enough different
                                {
                                    desiredAimDirection = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle);
                                }
                        }
                }

            bool isUserClient = m_pControlledPlayer->IsClient();

            IEntity* pMountedGunParentEntity = pMountedGunEntity->GetParent();
            IVehicle *pVehicle = NULL;
            if(pMountedGunParentEntity && m_pControlledPlayer)
                pVehicle = m_pControlledPlayer->GetLinkedVehicle();

            CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();

            //For client update always, for others only when there is notable change
            if (!pVehicle && (isUserClient || (!desiredAimDirection.IsEquivalent(lastMountedGunWorldTM.GetColumn1(), 0.003f))))
                {
                    Quat rotation = Quat::CreateRotationVDir(desiredAimDirection, 0.0f);
                    pMountedGunEntity->SetRotation(rotation);

                    if (isUserClient && pRecordingSystem)
                        {
                            // Only record the gun position if you're using the gun.
                            pRecordingSystem->OnMountedGunRotate(pMountedGunEntity, rotation);
                        }
                }

            const Vec3 vInitialAimDirection = GetMountDirection(pMountedGun, pMountedGunParentEntity);
            assert( vInitialAimDirection.IsUnit() );

            //Adjust gunner position and animations
            UpdateGunnerLocation(pMountedGun, pMountedGunParentEntity, vInitialAimDirection);

            const float aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(-desiredAimDirection));
            const float pitchLimit = sin_tpl(DEG2RAD(30.0f));
            const float animHeight = fabs_tpl(clamp(desiredAimDirection.z * (float)__fres(pitchLimit), -1.0f, 1.0f));

            const float aimUp = (float)__fsel(-desiredAimDirection.z, 0.0f, animHeight);
            const float aimDown = (float)__fsel(desiredAimDirection.z, 0.0f, animHeight);

            if (pRecordingSystem)
                {
                    pRecordingSystem->OnMountedGunUpdate(m_pControlledPlayer, aimrad, aimUp, aimDown);
                }

            if(!m_pControlledPlayer->IsThirdPerson())
                {
                    UpdateFirstPersonAnimations(pMountedGun, desiredAimDirection);
                }

            if(m_pMovementAction)
                {
                    const float aimUpParam = aimUp;
                    const float aimDownParam = aimDown;
                    const float aimMovementParam = CalculateAnimationTime(aimrad);

                    m_pMovementAction->SetParam(MountedGunCRCs.aimUpParam, aimUpParam);
                    m_pMovementAction->SetParam(MountedGunCRCs.aimDownParam, aimDownParam);
                    m_pMovementAction->SetParam(MountedGunCRCs.aimMovementParam, aimMovementParam);
                }

            UpdateIKMounted(pMountedGun);
        }
}
void CReplayActor::UpdateScopeContexts()
{
	if (m_pActionController)
	{
		//--- Update variable scope contexts
		CItem *pItem = static_cast<CItem*>(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(m_gunId));
		ICharacterInstance *pICharInst = (m_flags & eRAF_FirstPerson) && pItem ? pItem->GetEntity()->GetCharacter(0) : NULL;
		IMannequin &mannequinSys = gEnv->pGame->GetIGameFramework()->GetMannequinInterface();

		const int contextID = PlayerMannequin.contextIDs.Weapon;
		if (contextID >= 0)
		{
			const uint32 numScopes = m_pActionController->GetContext().controllerDef.m_scopeDef.size();
			ICharacterInstance *scopeCharInst = NULL;
			for (uint32 s=0; s<numScopes; s++)
			{
				if (m_pActionController->GetContext().controllerDef.m_scopeDef[s].context == contextID)
				{
					scopeCharInst = m_pActionController->GetScope(s)->GetCharInst();
					break;
				}
			}
			if (scopeCharInst != pICharInst)
			{
				if (pICharInst)
				{
					const SParams& weaponParams = pItem->GetParams();
					const IAnimationDatabase *animDB = !weaponParams.adbFile.empty() ? mannequinSys.GetAnimationDatabaseManager().Load(weaponParams.adbFile.c_str()) : NULL;
					if (animDB)
					{
						m_pActionController->SetScopeContext(contextID, *pItem->GetEntity(), pICharInst, animDB);
					}
					else
					{
						m_pActionController->ClearScopeContext(contextID, false);
					}
				}
				else
				{
					m_pActionController->ClearScopeContext(contextID, false);
				}
			}
		}

		const uint32 NUM_ACCESSORY_SLOTS = 2;
		uint32 ACCESSORY_CONTEXT_IDS[NUM_ACCESSORY_SLOTS] = {PlayerMannequin.contextIDs.attachment_top, PlayerMannequin.contextIDs.attachment_bottom};
		for (uint32 attachmentSlot=0; attachmentSlot<NUM_ACCESSORY_SLOTS; attachmentSlot++)
		{
			const int attachmentContextID = ACCESSORY_CONTEXT_IDS[attachmentSlot];
			ICharacterInstance *scopeCharInst = NULL;
			ICharacterInstance *accessoryCharInst = NULL;
			CItem *accessory = NULL;
			const char *contextName = m_pActionController->GetContext().controllerDef.m_scopeContexts.GetTagName(attachmentContextID);

			const uint32 numScopes = m_pActionController->GetContext().controllerDef.m_scopeDef.size();
			for (uint32 s=0; s<numScopes; s++)
			{
				if (m_pActionController->GetContext().controllerDef.m_scopeDef[s].context == attachmentContextID)
				{
					scopeCharInst = m_pActionController->GetScope(s)->GetCharInst();
					break;
				}
			}

			if (pItem)
			{
				//--- Find attachments
				const CItem::TAccessoryArray &accessories = pItem->GetAccessories();
				for (CItem::TAccessoryArray::const_iterator iter=accessories.begin(); iter != accessories.end(); ++iter)
				{
					const CItem::SAccessoryInfo &accessoryInfo = *iter;
					const SAccessoryParams *aparams = pItem->GetAccessoryParams(accessoryInfo.pClass);

					if (strcmp(aparams->attach_helper.c_str(), contextName) == 0)
					{
						//--- Found a match
						accessory = pItem->GetAccessory(accessoryInfo.pClass);
						accessoryCharInst = accessory->GetEntity()->GetCharacter(0);
						break;
					}
				}
			}

			if (scopeCharInst != accessoryCharInst)
			{
				if (accessoryCharInst && !accessory->GetParams().adbFile.empty())
				{
					const IAnimationDatabase *animDB = mannequinSys.GetAnimationDatabaseManager().Load(accessory->GetParams().adbFile.c_str());
					if (animDB)
					{
						m_pActionController->SetScopeContext(attachmentContextID, *pItem->GetEntity(), accessoryCharInst, animDB);
					}
				}
				else
				{
					m_pActionController->ClearScopeContext(attachmentContextID, false);
				}
			}
		}
	}
}
Exemple #11
0
//------------------------------------------------------------------------
int CScriptBind_Item::OnUsed(IFunctionHandler *pH, ScriptHandle userId)
{
	CItem *pItem = GetItem(pH);
	if (!pItem)
		return pH->EndFunction();

	CActor *pActor = GetActor((EntityId)userId.n);
	if (!pActor)
		return pH->EndFunction();

	if (pItem->CanUse((EntityId)userId.n))
	{
		if(IEntity* pParent = pItem->GetEntity()->GetParent())
		{
			IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pParent->GetId());
			if(pVehicle)
			{
				CPlayer* pPlayer = static_cast<CPlayer*>(pActor);
				IInteractor* pInteractor = pPlayer->GetInteractor();
				return pH->EndFunction( pVehicle->OnUsed((EntityId)userId.n, pInteractor->GetOverSlotIdx()) );
			}
		}

		pActor->UseItem(pItem->GetEntityId());
		return pH->EndFunction(true);
	}
	else if (pItem->CanPickUp((EntityId)userId.n))
	{
		//Should be always the client...
		if (pActor->IsClient())
		{
			CPlayer* pClientPlayer = static_cast<CPlayer*>(pActor);
			const SInteractionInfo& interactionInfo = pClientPlayer->GetCurrentInteractionInfo();
			bool expectedItem = (interactionInfo.interactiveEntityId == pItem->GetEntityId());
			bool expectedInteraction =	(interactionInfo.interactionType == eInteraction_PickupItem) || 
																	(interactionInfo.interactionType == eInteraction_ExchangeItem);
			if (!expectedItem || !expectedInteraction)
			{
				return pH->EndFunction();
			}

			if (interactionInfo.interactionType == eInteraction_ExchangeItem)
			{
				IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
				CItem* pCurrentItem = static_cast<CItem*>(pActor->GetCurrentItem());
				CItem* pExchangeItem = static_cast<CItem*>(pItemSystem->GetItem(interactionInfo.swapEntityId));
				if (pExchangeItem && pCurrentItem)
					pExchangeItem->ScheduleExchangeToNextItem(pActor, pItem, pCurrentItem);
			}
			else
			{
				pActor->PickUpItem(pItem->GetEntityId(), true, true);
			}
		}
		else
		{
			pActor->PickUpItem(pItem->GetEntityId(), true, true);
		}
		return pH->EndFunction(true);
	}

	return pH->EndFunction();
}