//------------------------------------------------------------------------
void CReplayActor::ProcessEvent(SEntityEvent &event)
{
	switch (event.event)
	{
	case ENTITY_EVENT_PREPHYSICSUPDATE:
		{
			const int currentFrameId = gEnv->pRenderer->GetFrameID();
			if(currentFrameId==m_lastFrameUpdated)
				return;
			m_lastFrameUpdated = currentFrameId;

			if (m_pActionController)
			{
				float frameTime = gEnv->pTimer->GetFrameTime();
				m_pActionController->Update(frameTime);
			}

			ICharacterInstance* pShadowCharacter = GetShadowCharacter();
			if (pShadowCharacter)
			{
				QuatTS pose = (QuatTS)GetEntity()->GetWorldTM();
				SAnimationProcessParams params;
				params.locationAnimation = pose;
				params.bOnRender = 1;
				params.zoomAdjustedDistanceFromCamera = (GetISystem()->GetViewCamera().GetPosition()-pose.t).GetLength();
				pShadowCharacter->StartAnimationProcessing(params);
				//--- Ensure that we disable the automatic update if we're doing it explicitly
				pShadowCharacter->SetFlags( pShadowCharacter->GetFlags()&(~CS_FLAG_UPDATE) );
			}

			ICharacterInstance *pCharacter = GetEntity()->GetCharacter(0);
			ISkeletonPose *pSkelPose = pCharacter ? pCharacter->GetISkeletonPose() : NULL;

			if(pSkelPose)
			{
				ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton();

				// GetJointIDByName() returns -1 if it fails; m_headBoneID is initialised to -2
				// since -1 is failure and 0+ are valid bone indices.
				if (m_headBoneID == -2)
				{
					// TODO: Should move this to an initialisation function
					m_headBoneID = pICharacterModelSkeleton->GetJointIDByName("Bip01 Head");
					m_cameraBoneID = pICharacterModelSkeleton->GetJointIDByName("Bip01 Camera");
				}

				if (m_headBoneID > -1)
				{
					m_headPos = pSkelPose->GetAbsJointByID(m_headBoneID);
				}
				if (m_cameraBoneID > -1)
				{
					m_cameraPos = pSkelPose->GetAbsJointByID(m_cameraBoneID);
				}
			}
		}
		break;
	case ENTITY_EVENT_DONE:
	case ENTITY_EVENT_RETURNING_TO_POOL:
		{
			SAFE_RELEASE(m_pActionController);
			SAFE_DELETE(m_pAnimContext);
			m_itemList.OnActionControllerDeleted();
		}
		break;
	}
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------
bool CItem::SetGeometry(int slot, const ItemString &name, const Vec3 &poffset, const Ang3 &aoffset, float scale, bool forceReload)
{
	bool changedfp=false;

	switch(slot)
	{
	case eIGS_Arms:
	{
		if(!name || forceReload)
		{
			GetEntity()->FreeSlot(slot);
#ifndef ITEM_USE_SHAREDSTRING
			m_geometry[slot].resize(0);
#else
			m_geometry[slot].reset();
#endif
		}

		ResetCharacterAttachment(eIGS_FirstPerson, ITEM_ARMS_ATTACHMENT_NAME);

		ICharacterInstance *pCharacter=0;

		if(name && name[0])
		{
			if(name != m_geometry[slot])
				GetEntity()->LoadCharacter(slot, name);

			DrawSlot(eIGS_Arms, false);

			pCharacter = GetEntity()->GetCharacter(eIGS_Arms);
		}
		else if(m_pForcedArms)
		{
			pCharacter = m_pForcedArms;
		}
		else
		{
			int armsId=m_stats.hand==eIH_Right?0:1;
			pCharacter = GetOwnerActor()?GetOwnerActor()->GetFPArms(armsId):0;
		}

		if(pCharacter)
		{
			pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE));
			SetCharacterAttachment(eIGS_FirstPerson, ITEM_ARMS_ATTACHMENT_NAME, pCharacter, 0);
		}
	}
	break;

	case eIGS_FirstPerson:
	case eIGS_ThirdPerson:
	default:
	{
		if(!name || forceReload)
		{
			GetEntity()->FreeSlot(slot);
#ifndef ITEM_USE_SHAREDSTRING
			m_geometry[slot].resize(0);
#else
			m_geometry[slot].reset();
#endif
		}

		DestroyAttachmentHelpers(slot);

		if(name && name[0])
		{
			if(m_geometry[slot] != name)
			{
				const char *ext = PathUtil::GetExt(name.c_str());

				if((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0))
					GetEntity()->LoadCharacter(slot, name, 0);
				else
					GetEntity()->LoadGeometry(slot, name, 0, 0);

				changedfp=slot==eIGS_FirstPerson;
			}

			CreateAttachmentHelpers(slot);

			SetDefaultIdleAnimation(slot, g_pItemStrings->idle);
		}

		if(slot == eIGS_FirstPerson)
		{
			ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson);

			if(pCharacter)
			{
				pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE));
			}
		}
		else if(slot == eIGS_Destroyed)
			DrawSlot(eIGS_Destroyed, false);
	}
	break;
	}

	Matrix34 slotTM;
	slotTM = Matrix34::CreateRotationXYZ(aoffset);
	slotTM.Scale(Vec3(scale, scale, scale));
	slotTM.SetTranslation(poffset);
	GetEntity()->SetSlotLocalTM(slot, slotTM);

	if(changedfp && m_stats.mounted)
	{
		PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true);
		ForceSkinning(true);

		if(!m_mountparams.pivot.empty())
		{
			Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false);
			Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_mountparams.pivot.c_str(), false);
			tm.AddTranslation(pivot);

			GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm);
		}

		GetEntity()->InvalidateTM();
	}

	m_geometry[slot] = name ? name : "";

	ReAttachAccessories();

	return true;
}
Ejemplo n.º 3
0
void CAICorpse::SetupFromSource( IEntity& sourceEntity, ICharacterInstance& characterInstance, const uint32 priority)
{
	// 1.- Move resources from source entity, into AICorpse
	GetEntity()->SetFlags(GetEntity()->GetFlags() | (ENTITY_FLAG_CASTSHADOW));

	sourceEntity.MoveSlot(GetEntity(), 0);

	// Moving everything from one slot into another will also clear the render proxies in the source.
	// Thus, we need to invalidate the model so that it will be properly reloaded when a non-pooled
	// entity is restored from a save-game.
	CActor* sourceActor = static_cast<CActor*>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(sourceEntity.GetId()));
	if (sourceActor != NULL)
	{
		sourceActor->InvalidateCurrentModelName();
	}

	// 2.- After 'MoveSlot()', characterInstance is now stored inside CAICorpse
	// It needs to be now updated from the entity system
	characterInstance.SetFlags( characterInstance.GetFlags() | CS_FLAG_UPDATE );

#if AI_CORPSES_ENABLE_SERIALIZE
	m_modelName = characterInstance.GetFilePath();
#endif

	// 3.- Search for any attached weapon and clone them
	IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();

	IAttachmentManager* pAttachmentManager = characterInstance.GetIAttachmentManager();
	const uint32 attachmentCount = (uint32)pAttachmentManager->GetAttachmentCount();
	for(uint32 i = 0; i < attachmentCount ; ++i)
	{
		IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(i);
		assert(pAttachment != NULL);

		IAttachmentObject* pAttachmentObject = pAttachment->GetIAttachmentObject();
		if((pAttachmentObject == NULL) || (pAttachmentObject->GetAttachmentType() != IAttachmentObject::eAttachment_Entity))
			continue;

		const EntityId attachedEntityId = static_cast<CEntityAttachment*>(pAttachmentObject)->GetEntityId();

		IItem* pItem = pItemSystem->GetItem(attachedEntityId);
		if(pItem != NULL)
		{
			if(AllowCloneAttachedItem( pItem->GetEntity()->GetClass() ))
			{
				if(m_attachedItemsInfo.size() < m_attachedItemsInfo.max_size())
				{
					AttachedItem attachedItemInfo;
					attachedItemInfo.pClass = pItem->GetEntity()->GetClass();
					attachedItemInfo.attachmentName = pAttachment->GetName();

					attachedItemInfo.id = CloneAttachedItem( attachedItemInfo, pAttachment );
					m_attachedItemsInfo.push_back(attachedItemInfo);
				}
			}
		}	
	}

	//Only accept requested priority if it has attached weapons
	m_priority = (m_attachedItemsInfo.size() > 0) ? priority : 0;

	//Force physics to sleep immediately (if not already)
	IPhysicalEntity* pCorpsePhysics = GetEntity()->GetPhysics();
	if(pCorpsePhysics != NULL)
	{
		pe_action_awake awakeAction;
		awakeAction.bAwake = 0;
		pCorpsePhysics->Action( &awakeAction );
	}
}