//------------------------------------------------------------------------ bool CItem::PlayFragment(IAction* pAction, float speedOverride, float timeOverride, float animWeight, float ffeedbackWeight, bool concentratedFire) { _smart_ptr<IAction> pActionPtr(pAction); CRY_ASSERT(pAction); if(!pAction) { return false; } CWeapon *pWeapon = static_cast<CWeapon*>(GetIWeapon()); if (pWeapon && pWeapon->IsProxyWeapon()) { return false; } bool success = false; float speed = (float)__fsel(-speedOverride, 1.0f, speedOverride); FragmentID fragID = pAction->GetFragmentID(); pAction->SetSubContext(m_subContext); IActionController *pActionController = GetActionController(); if ((fragID != FRAGMENT_ID_INVALID) && pActionController) { float fragmentDuration, transitionDuration; if (pActionController->QueryDuration(*pAction, fragmentDuration, transitionDuration)) { float duration = fragmentDuration+transitionDuration; if ((duration > 0.0f) && (timeOverride > 0.0f)) { speed = (duration / timeOverride); CRY_ASSERT((speed > 0.0f) && (speed < 99999.0f)); } if(duration > 0.f) { m_animationTime[eIGS_Owner] = (uint32) MAX((duration*1000.0f/speed) - 20, 0.0f); } pAction->SetSpeedBias(speed); pAction->SetAnimWeight(animWeight); if(concentratedFire) { pAction->SetParam(CItem::sActionParamCRCs.concentratedFire, 1.f); } if(ffeedbackWeight != 1.f) { pAction->SetParam(CItem::sActionParamCRCs.ffeedbackScale, ffeedbackWeight); } pActionController->Queue(pAction); success = true; } } return success; }
//------------------------------------------------------------------------ _smart_ptr<IAction> CItem::PlayAction(FragmentID action, int layer, bool loop, uint32 flags, float speedOverride, float animWeigth, float ffeedbackWeight) { _smart_ptr<IAction> pAction; const CWeapon* pWeapon = static_cast<CWeapon*>(GetIWeapon()); if (pWeapon && pWeapon->IsProxyWeapon()) { return pAction; } IActionController* pActionController = GetActionController(); if (pActionController && action != FRAGMENT_ID_INVALID) { SAnimationContext& animContext = pActionController->GetContext(); const CTagDefinition* pTagDefinition = animContext.controllerDef.GetFragmentTagDef(action); float timeOverride = -1.0f; bool concentratedFire = (flags&eIPAF_ConcentratedFire) != 0; TagState actionTags = TAG_STATE_EMPTY; if (pTagDefinition) { CTagState fragTags(*pTagDefinition); SetFragmentTags(fragTags); actionTags = fragTags.GetMask(); } pAction = new CItemAction(PP_PlayerAction, action, actionTags); PlayFragment(pAction, speedOverride, timeOverride, animWeigth, ffeedbackWeight, concentratedFire); } return pAction; }
//------------------------------------------------------------------------ void CItem::FixResourceName(const ItemString &inName, TempResourceName &name, int flags, const char *hand, const char *suffix, const char *pose, const char *pov, const char *env) { // the whole thing of fixing is not nice, but at least we don't allocate too often // StringHelper<TempResourceName::SIZE> name (inName.c_str(), inName.length()); name.assign(inName.c_str(), inName.length()); if(!hand) { if(m_stats.hand == eIH_Left) hand = "left"; else hand = "right"; } name.replace("%hand%", hand); if(m_stats.hand == eIH_Left) name.replace("%offhand%", "right"); else name.replace("%offhand%", "left"); if(!suffix) suffix = m_actionSuffix.c_str(); name.replace("%suffix%", suffix); if(!pose) { if(!m_sharedparams->params.pose.empty()) pose = m_sharedparams->params.pose.c_str(); else pose = ""; } name.replace("%pose%", ""); if(!pov) { if((m_stats.fp || flags&eIPAF_ForceFirstPerson) && !(flags&eIPAF_ForceThirdPerson)) pov = ITEM_FIRST_PERSON_TOKEN; else pov = ITEM_THIRD_PERSON_TOKEN; } name.replace("%pov%", pov); if(!env) { // Instead if the weapons sound proxy, the owners is used to retrieve the tail name IEntity *pOwner = GetOwner(); if(GetIWeapon() && pOwner) // restricting to weapon sounds only { if(pOwner) { IEntitySoundProxy *pSoundProxy = (IEntitySoundProxy *)pOwner->GetProxy(ENTITY_PROXY_SOUND); if(!pSoundProxy) pSoundProxy = (IEntitySoundProxy *)pOwner->CreateProxy(ENTITY_PROXY_SOUND); if(pSoundProxy) { // check for a roof 10m above the Owner // recalculate visibility when owner move more than 2 meters pSoundProxy->CheckVisibilityForTailName(10.0f, 2.0f); env = pSoundProxy->GetTailName(); } } } if(!env || !env[0] || !stricmp("indoor", env)) name.replace("%env%", ""); else { static const size_t MAX_LEN = 256; char envstr[MAX_LEN]; envstr[0] = '_'; strncpy(envstr+1, env, MAX_LEN-1); // no 0 pad, if MAX_LEN-1 are copied envstr[MAX_LEN-1] = '\0'; // always zero-terminate name.replace("%env%", envstr); } } else name.replace("%env%", env); }
//------------------------------------------------------------------------ void CItem::SpawnEffect(int slot, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale) { if (m_stats.mounted) slot=eIGS_FirstPerson; Vec3 position(0,0,0); Vec3 finalOffset = offset; SEntitySlotInfo slotInfo; if (GetEntity()->GetSlotInfo(slot, slotInfo)) { if (slotInfo.pStatObj) // entity slot { // get helper position IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotWorldTM(slot).TransformPoint(position); } else if (slotInfo.pCharacter) // bone attachment { ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (pAttachment) { const Matrix34 m = Matrix34(pAttachment->GetAttWorldAbsolute()); position = m.GetTranslation(); } else { int16 id = pCharacter->GetISkeletonPose()->GetJointIDByName(helper); if (id>=0) position = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t; position = GetEntity()->GetSlotWorldTM(slot).TransformPoint(position); } } } else if(m_stats.mounted && !m_stats.fp) { if(GetIWeapon()) { // if no helper specified, try getting pos from firing locator IWeaponFiringLocator *pLocator = GetIWeapon()->GetFiringLocator(); if (pLocator) { if(!pLocator->GetFiringPos(GetEntityId(), NULL, position)) position.Set(0.0f,0.0f,0.0f); else finalOffset = GetEntity()->GetWorldTM().TransformVector(finalOffset); } } } position += finalOffset; IParticleEffect *pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); if (pParticleEffect) pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(position, dir, scale)); }