int CScriptBind_Actor::GetClosestAttachment(IFunctionHandler *pH, int characterSlot, Vec3 testPos, float maxDistance, const char* suffix) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); IEntity* pEntity = pActor->GetEntity(); ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot); if (!pChar) return pH->EndFunction(); //fallback: use nearest attachment float minDiff = maxDistance*maxDistance; IAttachment* pClosestAtt = 0; IAttachmentManager* pMan = pChar->GetIAttachmentManager(); int count = pMan->GetAttachmentCount(); for (int i=0; i<count; ++i) { IAttachment* pAtt = pMan->GetInterfaceByIndex(i); if (pAtt->IsAttachmentHidden() || !pAtt->GetIAttachmentObject()) continue; AABB bbox(AABB::CreateTransformedAABB(Matrix34(pAtt->GetAttWorldAbsolute()),pAtt->GetIAttachmentObject()->GetAABB())); //gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(bbox,false,ColorB(255,0,0,100),eBBD_Faceted); //float diff = (testPos - pAtt->GetWMatrix().GetTranslation()).len2(); float diff((testPos - bbox.GetCenter()).len2()); if (diff < minDiff) { //CryLogAlways("%s distance: %.1f", pAtt->GetName(), sqrt(diff)); if (suffix[0] && !strstr(pAtt->GetName(), suffix)) continue; minDiff = diff; pClosestAtt = pAtt; } } if (!pClosestAtt) return pH->EndFunction(); //FIXME FIXME: E3 workaround char attachmentName[64]; strncpy(attachmentName,pClosestAtt->GetName(),63); attachmentName[63] = 0; char *pDotChar = strstr(attachmentName,"."); if (pDotChar) *pDotChar = 0; strlwr(attachmentName); // return pH->EndFunction(attachmentName); }
//-------------------------------------------------------------------------------------------------- // Name: SetMaterialOnEntity // Desc: Sets material on entity //-------------------------------------------------------------------------------------------------- void CGameEffect::SetMaterialOnEntity(IMaterial* pMaterial,EntityId entityId,PodArray<int>* pBodyAttachmentIndexArray) { if(pMaterial && pBodyAttachmentIndexArray) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityId); if(pEntity) { SEntitySlotInfo slotInfo; bool gotSlotInfo = pEntity->GetSlotInfo(0, slotInfo); if(gotSlotInfo && slotInfo.pCharacter) { IAttachmentManager* pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); if(pAttachmentManager) { int attachmentCount = pBodyAttachmentIndexArray->size(); for(int i=0; i<attachmentCount; i++) { IAttachment* attachment = pAttachmentManager->GetInterfaceByIndex((*pBodyAttachmentIndexArray)[i]); if(attachment) { IAttachmentObject* attachmentObj = attachment->GetIAttachmentObject(); if(attachmentObj) { attachmentObj->SetReplacementMaterial(pMaterial); } } } } } } } }//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------- // Name: InitAttachmentIndexArray // Desc: Initialises attachment index array //-------------------------------------------------------------------------------------------------- void CGameEffect::InitAttachmentIndexArray(PodArray<int> *attachmentIndexArray,PodArray<ItemString>* pAttachmentNameArray,EntityId entityId) const { if(attachmentIndexArray && pAttachmentNameArray && (entityId!=0)) { if(attachmentIndexArray->size() == 0) { // Store attachment index array const int attachmentNameCount = pAttachmentNameArray->size(); SEntitySlotInfo slotInfo; IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityId); if(pEntity) { bool gotEntitySlotInfo = pEntity->GetSlotInfo(0, slotInfo); if(gotEntitySlotInfo) { attachmentIndexArray->reserve(attachmentNameCount); if(slotInfo.pCharacter) { IAttachmentManager* attachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); if(attachmentManager) { const int attachmentCount = attachmentManager->GetAttachmentCount(); for(int n=0; n<attachmentNameCount; n++) { for(int a=0; a<attachmentCount; a++) { IAttachment* attachment = attachmentManager->GetInterfaceByIndex(a); if(attachment) { const char* currentAttachmentName = attachment->GetName(); if(strcmp(currentAttachmentName,(*pAttachmentNameArray)[n].c_str())==0) { attachmentIndexArray->push_back(a); break; } } } } } } } } } } }//-------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------ int CScriptBind_Actor::AttachVulnerabilityEffect(IFunctionHandler *pH, int characterSlot, int partid, Vec3 hitPos, float radius, const char* effect, const char* attachmentIdentifier) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); IEntity* pEntity = pActor->GetEntity(); ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot); if (!pChar || !effect) return pH->EndFunction(); //fallback: use nearest attachment float minDiff = radius*radius; IAttachment* pClosestAtt = 0; IAttachmentManager* pMan = pChar->GetIAttachmentManager(); for (int i=0; i<pMan->GetAttachmentCount(); ++i) { IAttachment* pAtt = pMan->GetInterfaceByIndex(i); float diff = (hitPos - pAtt->GetAttWorldAbsolute().t).len2(); if (diff < minDiff) { // only use specified attachments if (attachmentIdentifier[0] && !strstr(pAtt->GetName(), attachmentIdentifier)) continue; minDiff = diff; pClosestAtt = pAtt; } //CryLog("diff: %.2f, att: %s", diff, attName.c_str()); } if (!pClosestAtt) return pH->EndFunction(); //CryLog("AttachVulnerabilityEffect: closest att %s, attaching effect %s", pClosestAtt->GetName(), effect); CEffectAttachment *pEffectAttachment = new CEffectAttachment(effect, Vec3(ZERO), Vec3(0,1,0), 1.f); pClosestAtt->AddBinding(pEffectAttachment); pClosestAtt->HideAttachment(0); return pH->EndFunction(pClosestAtt->GetName()); }
void CVar::EnableDebugAnimText(IConsoleCmdArgs *args) { if (args && args->GetArgCount() > 1) { const char* szFilterName = args->GetArg(1); bool enable = true; if (args->GetArgCount() > 2) { enable = (strcmp(args->GetArg(2), "0") != 0); } CEntitySystem* pEntitySystem = GetIEntitySystem(); IEntity *entity = pEntitySystem->FindEntityByName(szFilterName); if (entity) { uint32 numSlots = entity->GetSlotCount(); for (uint32 i=0; i<numSlots; i++) { ICharacterInstance *charInst = entity->GetCharacter(i); if (charInst) { charInst->GetISkeletonAnim()->SetDebugging(enable); IAttachmentManager* pAttachmentManager = charInst->GetIAttachmentManager(); for(int32 attachmentIndex=0; attachmentIndex<pAttachmentManager->GetAttachmentCount(); ++attachmentIndex) { IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(attachmentIndex); assert(pAttachment); IAttachmentObject* pObject = pAttachment->GetIAttachmentObject(); if (pObject) { ICharacterInstance* pObjectCharInst = pObject->GetICharacterInstance(); if (pObjectCharInst) { pObjectCharInst->GetISkeletonAnim()->SetDebugging(enable); } } } } } } } }
void CBodyDestrutibilityInstance::ResetMaterials( IEntity& characterEntity, ICharacterInstance& characterInstance ) { characterEntity.SetSlotMaterial(0, NULL); IAttachmentManager *pAttachmentManager = characterInstance.GetIAttachmentManager(); CRY_ASSERT(pAttachmentManager); const uint32 attachmentCount = (uint32)pAttachmentManager->GetAttachmentCount(); for(TOriginalMaterials::iterator it = m_originalMaterials.begin(); it != m_originalMaterials.end(); ++it) { IAttachmentObject *pAttachmentObject = (it->first < attachmentCount) ? pAttachmentManager->GetInterfaceByIndex(it->first)->GetIAttachmentObject() : NULL; if (pAttachmentObject) { pAttachmentObject->SetReplacementMaterial(it->second); it->second->Release(); } } m_originalMaterials.clear(); }
//------------------------------------------------------------------------ int CScriptBind_Actor::ResetVulnerabilityEffects(IFunctionHandler *pH, int characterSlot) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); IEntity* pEntity = pActor->GetEntity(); ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot); if (pChar) { IAttachmentManager* pMan = pChar->GetIAttachmentManager(); for (int i=0; i<pMan->GetAttachmentCount(); ++i) { IAttachment* pAtt = pMan->GetInterfaceByIndex(i); if (strstr(pAtt->GetName(), "vulnerable")) pAtt->ClearBinding(); } } return pH->EndFunction(); }
void CBodyDestrutibilityInstance::ReplaceMaterial( IEntity& characterEntity, ICharacterInstance& characterInstance, IMaterial& replacementMaterial ) { IMaterial* pCurrentMaterial = characterInstance.GetIMaterial(); if ((pCurrentMaterial != NULL) && stricmp(pCurrentMaterial->GetName(), replacementMaterial.GetName())) { characterEntity.SetSlotMaterial(0, &replacementMaterial); } const bool storeOriginalReplacementMaterials = m_originalMaterials.empty(); IAttachmentManager *pAttachmentManager = characterInstance.GetIAttachmentManager(); CRY_ASSERT(pAttachmentManager); const int attachmentCount = pAttachmentManager->GetAttachmentCount(); for (int attachmentIdx = 0; attachmentIdx < attachmentCount; ++attachmentIdx) { IAttachmentObject *pAttachmentObject = pAttachmentManager->GetInterfaceByIndex(attachmentIdx)->GetIAttachmentObject(); if (pAttachmentObject) { IMaterial* pAttachMaterial = (IMaterial*)pAttachmentObject->GetBaseMaterial(); if ((pAttachMaterial != NULL) && stricmp(pAttachMaterial->GetName(), replacementMaterial.GetName())) { if (storeOriginalReplacementMaterials) { IMaterial* pOriginalReplacementMaterial = pAttachmentObject->GetReplacementMaterial(); if(pOriginalReplacementMaterial != NULL) { pOriginalReplacementMaterial->AddRef(); m_originalMaterials.push_back(TAttachmentMaterialPair((uint32)attachmentIdx, pOriginalReplacementMaterial)); } } pAttachmentObject->SetReplacementMaterial(&replacementMaterial); } } } }
//------------------------------------------------------------------------ void CDebugGun::Update( SEntityUpdateContext& ctx, int update) { if (!IsSelected()) return; static float drawColor[4] = {1,1,1,1}; static const int dx = 5; static const int dy = 15; static const float font = 1.2f; static const float fontLarge = 1.4f; IRenderer* pRenderer = gEnv->pRenderer; IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom(); pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags); pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second); ray_hit rayhit; unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; if (m_fireModes[m_fireMode].first == "pierceability") { flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask; } // use cam, no need for firing pos/dir CCamera& cam = GetISystem()->GetViewCamera(); if (gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1)) { IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager(); IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); int x = (int)(pRenderer->GetWidth() *0.5f) + dx; int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy; // draw normal ColorB colNormal(200,0,0,128); Vec3 end = rayhit.pt + 0.75f*rayhit.n; pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal); pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal); IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(pEntity) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)fontLarge, drawColor, false, pEntity->GetName()); } // material const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName(); if (matName[0]) pRenderer->Draw2dLabel((float)x, (y+=dy), (float)font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx); pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f m", rayhit.dist); if (pEntity) { IScriptTable* pScriptTable = pEntity->GetScriptTable(); // physics if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics()) { pe_status_dynamics status; if (pPhysEnt->GetStatus(&status)) { if (status.mass > 0.f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f kg", status.mass); pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "pe_type: %i", pPhysEnt->GetType()); // PartId - Part name ICharacterInstance* pCharacter = pEntity->GetCharacter(0); if (pCharacter) { CryFixedStringT<64> hit_part("unknown part"); const int FIRST_ATTACHMENT_PARTID = 1000; if (rayhit.partid >= FIRST_ATTACHMENT_PARTID) { IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(rayhit.partid - FIRST_ATTACHMENT_PARTID); if (pAttachment) { hit_part = pAttachment->GetName(); } } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); const char* szJointName = pICharacterModelSkeleton->GetJointNameByID(pSkeletonPose->getBonePhysParentOrSelfIndex(rayhit.partid)); if (szJointName && *szJointName) hit_part = szJointName; } pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "partId: %i (%s)", rayhit.partid, hit_part.c_str()); } if (status.submergedFraction > 0.f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f submerged", status.submergedFraction); if (status.v.len2() > 0.0001f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f m/s", status.v.len()); } } // class-specific stuff if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId())) { pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%8.2f health", pActor->GetHealth()); } else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId())) { const SVehicleStatus& status = pVehicle->GetStatus(); pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%.0f%% health", 100.f*status.health); pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%i passengers", status.passengerCount); if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered()) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "Running"); } } else { if (pScriptTable) { HSCRIPTFUNCTION func = 0; if (pScriptTable->GetValue("GetHealth", func) && func) { float health = 0.f; if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health)) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "%.0f health", health); } } gEnv->pScriptSystem->ReleaseFunc(func); } } } } }
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 ); } }