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); } }
//------------------------------------------------------------------------ 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, ¶ms, 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); } } } } }
//------------------------------------------------------------------------ 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(); }