//------------------------------------------------------------------------
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);
}
Exemple #2
0
//------------------------------------------------------------------------
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()));

}
Exemple #9
0
//------------------------------------------------------------------------
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);
}