//------------------------------------------------------------------------ void CItem::DoSwitchAccessory(const ItemString &inAccessory) { const ItemString &accessory = (inAccessory == g_pItemStrings->SCARSleepAmmo) ? g_pItemStrings->SCARTagAmmo : inAccessory; SAccessoryParams *params = GetAccessoryParams(accessory); bool attached = false; if(params) { ItemString replacing; for(TAccessoryMap::iterator it = m_accessories.begin(); it != m_accessories.end(); it++) { SAccessoryParams *p = GetAccessoryParams(it->first); if(p && p->attach_helper == params->attach_helper) { replacing = it->first; attached = true; } } if(attached) { AttachAccessory(replacing, false, true, true); if(accessory != replacing) AttachAccessory(accessory, true, true, true); } } if(!attached) AttachAccessory(accessory, true, true, true); }
//------------------------------------------------------------------------ void CWeapon::OnPickedUp(EntityId actorId, bool destroyed) { BROADCAST_WEAPON_EVENT(OnPickedUp, (this, actorId, destroyed)); CItem::OnPickedUp(actorId, destroyed); GetEntity()->SetFlags(GetEntity()->GetFlags() | ENTITY_FLAG_NO_PROXIMITY); GetEntity()->SetFlags(GetEntity()->GetFlags() & ~ENTITY_FLAG_ON_RADAR); if(GetISystem()->IsSerializingFile() == 1) return; CActor *pActor=GetActor(actorId); if (!pActor) return; if (!IsServer()) return; // bonus ammo is always put in the actor's inv if (!m_bonusammo.empty()) { for (TAmmoMap::iterator it=m_bonusammo.begin(); it!=m_bonusammo.end(); ++it) { int count=it->second; SetInventoryAmmoCount(it->first, GetInventoryAmmoCount(it->first)+count); } m_bonusammo.clear(); } // current ammo is only added to actor's inv, if we already have this weapon if (destroyed && m_params.unique) { for (TAmmoMap::iterator it=m_ammo.begin(); it!=m_ammo.end(); ++it) { //Only add ammo to inventory, if not accessory ammo (accessories give ammo already) if(m_accessoryAmmo.find(it->first)==m_accessoryAmmo.end()) { int count=it->second; SetInventoryAmmoCount(it->first, GetInventoryAmmoCount(it->first)+count); } } } if(!gEnv->bMultiplayer && !m_initialSetup.empty() && pActor->IsClient()) { for (TAccessoryMap::iterator it=m_accessories.begin(); it!=m_accessories.end(); ++it) FixAccessories(GetAccessoryParams(it->first), true); } }
//------------------------------------------------------------------------ const char *CItem::CurrentAttachment(const ItemString &attachmentPoint) { for(TAccessoryMap::iterator it = m_accessories.begin(); it != m_accessories.end(); it++) { SAccessoryParams *params= GetAccessoryParams(it->first); if(params && params->attach_helper == attachmentPoint) return it->first.c_str(); } return 0; }
//------------------------------------------------------------------------ bool CItem::IsAccessoryHelperFree(const ItemString &helper) { for(TAccessoryMap::iterator it = m_accessories.begin(); it != m_accessories.end(); ++it) { SAccessoryParams *params = GetAccessoryParams(it->first); if(!params || params->attach_helper == helper) return false; } return true; }
//------------------------------------------------------------------------ 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); } }
//------------------------------------------------------------------------ CItem *CItem::AddAccessory(const ItemString &name) { SAccessoryParams *pAccessoryParams=GetAccessoryParams(name); if(!pAccessoryParams) { GameWarning("Trying to add unknown accessory '%s' to item '%s'!", name.c_str(), GetEntity()->GetName()); return 0; } char namebuf[128]; _snprintf(namebuf, sizeof(namebuf), "%s_%s", GetEntity()->GetName(), name.c_str()); namebuf[sizeof(namebuf)-1] = '\0'; SEntitySpawnParams params; params.pClass = m_pEntitySystem->GetClassRegistry()->FindClass(name); params.sName = namebuf; params.nFlags = ENTITY_FLAG_NO_PROXIMITY | ENTITY_FLAG_CASTSHADOW; if(pAccessoryParams->client_only) params.nFlags |= ENTITY_FLAG_CLIENT_ONLY; if(!params.pClass) { GameWarning("Trying to add unknown accessory '%s' to item '%s'!", name.c_str(), GetEntity()->GetName()); return 0; } EntityId accId=0; if(IEntity *pEntity = m_pEntitySystem->SpawnEntity(params)) accId=pEntity->GetId(); m_accessories.insert(TAccessoryMap::value_type(name, accId)); if(accId) return static_cast<CItem *>(m_pItemSystem->GetItem(accId)); return 0; }
//------------------------------------------------------------------------ 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 CItem::AttachAccessory(const ItemString &name, bool attach, bool noanim, bool force, bool initialSetup) { if(!force && IsBusy()) return; bool anim = !noanim && m_stats.fp; SAccessoryParams *params = GetAccessoryParams(name); if(!params) return; if(attach) { if(!IsAccessoryHelperFree(params->attach_helper)) return; if(CItem *pAccessory = AddAccessory(name)) { pAccessory->Physicalize(false, false); pAccessory->SetViewMode(m_stats.viewmode); if(!initialSetup) pAccessory->m_bonusAccessoryAmmo.clear(); SetCharacterAttachment(eIGS_FirstPerson, params->attach_helper, pAccessory->GetEntity(), eIGS_FirstPerson, 0); SetBusy(true); AttachAction action(pAccessory, params); if(anim) { PlayAction(params->attach_action, 0, false, eIPAF_Default|eIPAF_NoBlend); m_scheduler.TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<AttachAction>::Create(action), false); } else action.execute(this); } } else { if(CItem *pAccessory = GetAccessory(name)) { DetachAction action(pAccessory, params); if(anim) { StopLayer(params->attach_layer, eIPAF_Default|eIPAF_NoBlend); PlayAction(params->detach_action, 0, false, eIPAF_Default|eIPAF_NoBlend); m_scheduler.TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<DetachAction>::Create(action), false); SetBusy(true); } else { SetBusy(true); action.execute(this); } } } //Skip all this for the offhand if(GetEntity()->GetClass()!=CItem::sOffHandClass) FixAccessories(params, attach); //Attach silencer to 2nd SOCOM ///////////////////////////////////////////////////////////// bool isDualWield = IsDualWieldMaster(); CItem *dualWield = 0; if(isDualWield) { IItem *slave = GetDualWieldSlave(); if(slave && slave->GetIWeapon()) dualWield = static_cast<CItem *>(slave); else isDualWield = false; } if(isDualWield) dualWield->AttachAccessory(name,attach,noanim); ////////////////////////////////////////////////////////////// //Luciano - send game event g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(GetOwner(), GameplayEvent(eGE_AttachedAccessory, name, (float)attach, (void *)GetEntityId())); }
//------------------------------------------------------------------------ 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); }