static void CreateServerExitMark(const CLIENTWEAPONFX & theStruct) { SURFACE* pSurf = g_pSurfaceMgr->GetSurface((SurfaceType)theStruct.nSurfaceType); if (!pSurf || !pSurf->bCanShootThrough) return; int nMaxThickness = pSurf->nMaxShootThroughThickness; if (nMaxThickness < 1) return; // Determine if there is an "exit" surface... IntersectQuery qInfo; IntersectInfo iInfo; LTVector vDir = theStruct.vPos - theStruct.vFirePos; vDir.Norm(); qInfo.m_From = theStruct.vPos + (vDir * (LTFLOAT)(nMaxThickness + 1)); qInfo.m_To = theStruct.vPos; qInfo.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID | INTERSECT_HPOLY; SurfaceType eType = ST_UNKNOWN; if (g_pLTServer->IntersectSegment(&qInfo, &iInfo)) { eType = GetSurfaceType(iInfo); if (ShowsMark(eType)) { LTRotation rNormRot; g_pLTServer->AlignRotation(&rNormRot, &(iInfo.m_Plane.m_Normal), LTNULL); CLIENTWEAPONFX exitStruct = theStruct; exitStruct.vPos = iInfo.m_Point + vDir; exitStruct.vSurfaceNormal = iInfo.m_Plane.m_Normal; CreateServerMark(exitStruct); } } }
void CreateClientWeaponFX(CLIENTWEAPONFX & theStruct) { if (!g_pLTServer) return; // make sure the impact FX in valid ASSERT( ( 0 <= theStruct.eImpactType ) || ( IMPACT_TYPE_COUNT > theStruct.eImpactType ) ); // If this is a moveable object, set the flags of fx to ignore // marks and smoke... if (IsMoveable(theStruct.hObj)) { theStruct.wIgnoreFX |= WFX_MARK; // Create a server-side mark if applicable... if (CanMarkObject(theStruct.hObj)) { AMMO const *pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if (pAmmo) { if (pAmmo->pImpactFX) { if (WFX_MARK & pAmmo->pImpactFX->nFlags) { CreateServerMark((CLIENTWEAPONFX)theStruct); } } // Create an exit mark if applicable... if (pAmmo->pFireFX) { if (WFX_EXITMARK & pAmmo->pFireFX->nFlags) { CreateServerExitMark((const CLIENTWEAPONFX)theStruct); } } } } } // Do impact dings if applicable... if (!(IsMultiplayerGame() && IsCharacter(theStruct.hObj))) { theStruct.wIgnoreFX |= WFX_IMPACTDING; } // [KLS 2/28/02] - If the object hit is a character, re-evaluate the surface type. // We do this here because the process of applying damage to the character may have // changed the character's surface type (e.g., from Armor to Flesh). if (IsCharacter(theStruct.hObj)) { theStruct.nSurfaceType = GetSurfaceType(theStruct.hObj); } // Tell all the clients who can see this fx about the fx... CAutoMessage cMsg; cMsg.Writeuint8(SFX_WEAPON_ID); cMsg.WriteObject(theStruct.hObj); cMsg.WriteObject(theStruct.hFiredFrom); cMsg.Writeuint8(theStruct.nWeaponId); cMsg.Writeuint8(theStruct.nAmmoId); cMsg.Writeuint8(theStruct.nSurfaceType); cMsg.Writeuint16(theStruct.wIgnoreFX); cMsg.Writeuint8(theStruct.nShooterId); cMsg.WriteLTVector(theStruct.vFirePos); cMsg.WriteLTVector(theStruct.vPos); cMsg.WriteLTVector(theStruct.vSurfaceNormal); cMsg.Writeuint8(theStruct.eImpactType); g_pLTServer->SendSFXMessage(cMsg.Read(), theStruct.vPos, 0); }
void CreateClientWeaponFX(CLIENTWEAPONFX & theStruct) { if (!g_pLTServer) return; // If this is a moveable object, set the flags of fx to ignore // marks and smoke... if (IsMoveable(theStruct.hObj)) { theStruct.wIgnoreFX |= WFX_MARK; // Create a server-side mark if applicable... if (CanMarkObject(theStruct.hObj)) { AMMO* pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if (pAmmo) { if (pAmmo->pImpactFX) { if (WFX_MARK & pAmmo->pImpactFX->nFlags) { CreateServerMark((CLIENTWEAPONFX)theStruct); } } // Create an exit mark if applicable... if (pAmmo->pFireFX) { if (WFX_EXITMARK & pAmmo->pFireFX->nFlags) { CreateServerExitMark((const CLIENTWEAPONFX)theStruct); } } } } } // Do impact dings if applicable... if (!(IsMultiplayerGame() && IsCharacter(theStruct.hObj))) { theStruct.wIgnoreFX |= WFX_IMPACTDING; } // Tell all the clients who can see this fx about the fx... HMESSAGEWRITE hMessage = g_pLTServer->StartInstantSpecialEffectMessage(&(theStruct.vPos)); g_pLTServer->WriteToMessageByte(hMessage, SFX_WEAPON_ID); g_pLTServer->WriteToMessageObject(hMessage, theStruct.hFiredFrom); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nWeaponId); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nAmmoId); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nSurfaceType); g_pLTServer->WriteToMessageWord(hMessage, theStruct.wIgnoreFX); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nShooterId); g_pLTServer->WriteToMessageVector(hMessage, &(theStruct.vFirePos)); g_pLTServer->WriteToMessageVector(hMessage, &(theStruct.vPos)); g_pLTServer->WriteToMessageVector(hMessage, &(theStruct.vSurfaceNormal)); // This doesn't always work correctly... //g_pLTServer->WriteToMessageCompPosition(hMessage, &(theStruct.vFirePos)); //g_pLTServer->WriteToMessageCompPosition(hMessage, &(theStruct.vPos)); //g_pLTServer->WriteToMessageCompPosition(hMessage, &(theStruct.vSurfaceNormal)); g_pLTServer->EndMessage2(hMessage, MESSAGE_NAGGLEFAST); }