void CClientMeleeCollisionController::HandleBlocked(HOBJECT hTarget, const LTVector& vPos, const LTVector& vDir) { // Get the proper weapon record... CClientWeapon* pClientWeapon = g_pClientWeaponMgr->GetCurrentClientWeapon(); HWEAPON hWeapon = pClientWeapon ? pClientWeapon->GetWeaponRecord() : NULL; //!!ARL: Use Attacker's weapon instead? (will need to be sent from server - probably along with block info) HWEAPONDATA hWeaponData = g_pWeaponDB->GetWeaponData(hWeapon, !USE_AI_DATA); // Spawn a block effect for it... const char* pszBlockFX = g_pWeaponDB->GetString(hWeaponData, "BlockFX"); CLIENTFX_CREATESTRUCT fxcs(pszBlockFX, 0, LTRigidTransform(vPos, LTRotation(vDir, LTVector(0,1,0)))); g_pGameClientShell->GetSimulationTimeClientFXMgr().CreateClientFX(NULL, fxcs, true); // Let the server objects know they've blocked / been blocked. CAutoMessage cMsg; cMsg.Writeuint8(MID_OBJECT_MESSAGE); cMsg.WriteObject(m_hObject); cMsg.Writeuint32(MID_MELEEBLOCK); cMsg.WriteObject(hTarget); g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED); // Disable attacker's collision (i.e. stop attacking). DisableCollisions(); // For local player attackers, send a BlockRecoil stimulus so a proper animation can be played. if (m_hObject == g_pPlayerMgr->GetMoveMgr()->GetObject()) { CPlayerBodyMgr::Instance().HandleAnimationStimulus("CS_RecoilFromBlock"); } }
void CClientFXMgr::OnSpecialEffectNotify(HOBJECT hObject, ILTMessage_Read *pMsg) { char sName[MAX_CLIENTFX_NAME_LEN + 1]; uint32 dwFxFlags = 0; bool bUseTargetData = false; HOBJECT hTargetObj = NULL; bool bStartInst = true; HMODELNODE hNode = INVALID_MODEL_NODE; bool bHasParentObject = false; LTRigidTransform tTransform; tTransform.Init(); // Cache the initial message position for later use if there is a dependency. // This must be cached before any read operations. uint32 dwInitialMsgPos = pMsg->Tell( ); // Read in the type of client fx uint8 nId = pMsg->Readuint8(); switch( nId ) { case SFX_CLIENTFXGROUP : { if( !hObject ) return; // Retrieve the ID of the object pMsg->ReadString(sName, LTARRAYSIZE(sName)); dwFxFlags = pMsg->Readuint32(); bUseTargetData = pMsg->Readbool(); if( bUseTargetData ) { hTargetObj = pMsg->ReadObject(); } uint32 nUserFlags; m_pClientDE->Common()->GetObjectFlags(hObject, OFT_User, nUserFlags); if(hObject && !(nUserFlags & USRFLG_SFX_ON)) { bStartInst = false; } } break; case SFX_CLIENTFXGROUPINSTANT : { // Retrieve the ID of the object pMsg->ReadString(sName, LTARRAYSIZE(sName)); bool bLoop = pMsg->Readbool(); bool bNoSmoothShutdown = pMsg->Readbool(); dwFxFlags = ( bLoop ? FXFLAG_LOOP : 0 ) | ( bNoSmoothShutdown ? FXFLAG_NOSMOOTHSHUTDOWN : 0 ); bHasParentObject = pMsg->Readbool(); if( bHasParentObject ) { hObject = pMsg->ReadObject(); hNode = pMsg->Readuint32(); } else { hObject = NULL; tTransform.m_vPos = pMsg->ReadLTVector(); tTransform.m_rRot = pMsg->ReadCompLTRotation(); } bUseTargetData = pMsg->Readbool(); if( bUseTargetData ) { hTargetObj = pMsg->ReadObject(); } } break; default: return; } if( (bUseTargetData && hTargetObj == INVALID_HOBJECT) || (bHasParentObject && hObject == INVALID_HOBJECT) ) { // The ClientFX depends on the target object but it is not yet available on the client. // Add the message to the target dependent message list for object polling. uint32 nCurPos = pMsg->Tell( ); pMsg->SeekTo( dwInitialMsgPos ); SpecialFXNotifyMessageHandler::Instance().AddMessage( *pMsg, hObject ); pMsg->SeekTo( nCurPos ); // Don't create the ClientFX until the target is valid. return; } // If we got here we don't yet have this special FX so we have to start it running CLIENTFX_CREATESTRUCT fxcs(sName, dwFxFlags, hObject, tTransform); fxcs.m_bUseTargetData = bUseTargetData; fxcs.m_hTargetObject = hTargetObj; fxcs.m_hNode = hNode; fxcs.m_vTargetOffset.Init(); //create the new effect StartNewClientFX(fxcs, bStartInst, false); }
void CClientFXMgr::OnSpecialEffectNotify(HOBJECT hObject, ILTMessage_Read *pMsg) { uint32 dwServerID = 0; char sName[256]; uint32 dwFxFlags; LTVector vPos; LTRotation rRot; uint8 nId; bool bUseTargetData; HOBJECT hTargetObj = LTNULL; LTVector vTargetPos(0.0f, 0.0f, 0.0f); bool bStartInst = true; // Read in the type of client fx nId = pMsg->Readuint8(); switch( nId ) { case SFX_CLIENTFXGROUP : { if( !hObject ) return; // Retrieve the ID of the object pMsg->ReadString(sName, sizeof(sName)); dwFxFlags = pMsg->Readuint32(); bUseTargetData = !!(pMsg->Readuint8()); if( bUseTargetData ) { hTargetObj = pMsg->ReadObject(); vTargetPos = pMsg->ReadCompPos(); } m_pClientDE->GetObjectPos(hObject, &vPos); m_pClientDE->GetObjectRotation(hObject, &rRot); uint32 nUserFlags; m_pClientDE->Common()->GetObjectFlags(hObject, OFT_User, nUserFlags); if(hObject && !(nUserFlags & USRFLG_SFX_ON)) { bStartInst = false; } } break; case SFX_CLIENTFXGROUPINSTANT : { // Retrieve the ID of the object pMsg->ReadString(sName, sizeof(sName)); dwFxFlags = pMsg->Readuint32(); vPos = pMsg->ReadCompPos(); rRot = pMsg->ReadCompLTRotation(); hObject = pMsg->ReadObject(); bUseTargetData = !!(pMsg->Readuint8()); if( bUseTargetData ) { hTargetObj = pMsg->ReadObject(); vTargetPos = pMsg->ReadCompPos(); } } break; default: return; } // If we got here we don't yet have this special FX so we have to start it running CLIENTFX_CREATESTRUCT fxcs(sName, dwFxFlags, vPos, rRot); fxcs.m_hParent = hObject; fxcs.m_bUseTargetData = bUseTargetData; fxcs.m_hTarget = hTargetObj; fxcs.m_vTargetPos = vTargetPos; CLIENTFX_INSTANCE *pNewInst = CreateClientFX(fxcs, bStartInst); if (!pNewInst) return; }