bool WorldModel::CreateServerMark(CLIENTWEAPONFX & theStruct) { // See if we should create a mark, or simply move one of the GameBase's // marks. // If the GameBase has the max number of marks or this mark is very close // to a pre-existing mark, just move that mark to the new position. HOBJECT hMoveObj = LTNULL; HOBJECT hFarObj = LTNULL; uint32 nNumMarks = m_MarkList.size( ); LTFLOAT fClosestMarkDist = REGION_DIAMETER; LTFLOAT fFarthestMarkDist = 0.0f; uint8 nNumInRegion = 0; LTVector vPos; for( ObjRefNotifierList::iterator iter = m_MarkList.begin( ); iter != m_MarkList.end( ); iter++ ) { HOBJECT hObj = *iter; if( !hObj ) continue; HATTACHMENT hAttachment = NULL; if (LT_OK == g_pLTServer->FindAttachment( m_hObject, hObj, &hAttachment)) { LTransform transform; g_pCommonLT->GetAttachmentTransform(hAttachment, transform, LTTRUE); vPos = transform.m_Pos; } LTFLOAT fDist = VEC_DISTSQR(vPos, theStruct.vPos); if (fDist < REGION_DIAMETER) { if (fDist < fClosestMarkDist) { fClosestMarkDist = fDist; hMoveObj = hObj; } if (++nNumInRegion > MAX_MARKS_IN_REGION) { // Just move this mark to the correct pos... hMoveObj = hMoveObj ? hMoveObj : hObj; break; } } if (fDist > fFarthestMarkDist) { fFarthestMarkDist = fDist; hFarObj = hObj; } } // If we've got the max number of marks on this object, just move // the closest one to the new position... if (nNumMarks >= MAX_MARKS_PER_OBJECT) { if( !hMoveObj ) { if( hFarObj ) { hMoveObj = hFarObj; } else { HOBJECT hFirstMark = *m_MarkList.begin( ); hMoveObj = hFirstMark; } } } else { hMoveObj = LTNULL; // Need to create one... } // Re-setup the object to move it... if (hMoveObj && IsKindOf(hMoveObj, "CServerMark")) { CServerMark* pMoveMark = (CServerMark*) g_pLTServer->HandleToObject(hMoveObj); if (!pMoveMark) return false; // Since this mark is already attached to us, remove the attachment DetachObject( pMoveMark->m_hObject ); if( !AttachServerMark( *pMoveMark, (CLIENTWEAPONFX)theStruct)) { g_pLTServer->RemoveObject( pMoveMark->m_hObject ); RemoveMarkFromList( pMoveMark->m_hObject ); pMoveMark = NULL; return false; } return true; } // Okay, no luck, need to create a new mark... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); LTFLOAT fScaleAdjust = 1.0f; if (!GetImpactSprite((SurfaceType)theStruct.nSurfaceType, fScaleAdjust, theStruct.nAmmoId, createStruct.m_Filename, ARRAY_LEN(createStruct.m_Filename))) { return false; } createStruct.m_ObjectType = OT_SPRITE; createStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATEABLESPRITE; createStruct.m_Pos = theStruct.vPos; createStruct.m_Rotation = LTRotation(theStruct.vSurfaceNormal, LTVector(0.0f, 1.0f, 0.0f)); AMMO const *pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if( !pAmmo ) return false; static HCLASS hClass = g_pLTServer->GetClass("CServerMark"); CServerMark* pMark = (CServerMark*) g_pLTServer->CreateObject(hClass, &createStruct); if (!pMark) return false; // Randomly adjust the mark's scale to add a bit o spice... if (pAmmo->pImpactFX) { LTFLOAT fScale = fScaleAdjust * pAmmo->pImpactFX->fMarkScale; LTVector vScale(fScale, fScale, fScale); g_pLTServer->ScaleObject(pMark->m_hObject, &vScale); } if( !AttachServerMark( *pMark, (CLIENTWEAPONFX)theStruct)) { g_pLTServer->RemoveObject( pMark->m_hObject ); pMark = NULL; return false; } AddMarkToList( pMark->m_hObject ); return true; }
static void CreateServerMark(CLIENTWEAPONFX & theStruct) { AMMO* pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if (!pAmmo) return; // If this isn't a GameBase object, return... if (!IsGameBase(theStruct.hObj)) return; // See if we should create a mark, or simply move one of the GameBase's // marks. // If the GameBase has the max number of marks or this mark is very close // to a pre-existing mark, just move that mark to the new position. GameBase* pObj = (GameBase*) g_pLTServer->HandleToObject(theStruct.hObj); if (!pObj) return; HOBJECT hMoveObj = LTNULL; HOBJECT hFarObj = LTNULL; ObjectList* pMarkList = pObj->GetMarkList(); if (pMarkList) { uint8 nNumMarks = pMarkList->m_nInList; ObjectLink* pLink = pMarkList->m_pFirstLink; LTFLOAT fClosestMarkDist = REGION_DIAMETER; LTFLOAT fFarthestMarkDist = 0.0f; uint8 nNumInRegion = 0; LTVector vPos; for (int i=0; i < nNumMarks && pLink; i++) { if (pLink->m_hObject) { HATTACHMENT hAttachment; if (LT_OK == g_pLTServer->FindAttachment(theStruct.hObj, pLink->m_hObject, &hAttachment)) { LTransform transform; g_pLTServer->Common()->GetAttachmentTransform(hAttachment, transform, LTTRUE); vPos = transform.m_Pos; } LTFLOAT fDist = VEC_DISTSQR(vPos, theStruct.vPos); if (fDist < REGION_DIAMETER) { if (fDist < fClosestMarkDist) { fClosestMarkDist = fDist; hMoveObj = pLink->m_hObject; } if (++nNumInRegion > MAX_MARKS_IN_REGION) { // Just move this mark to the correct pos... hMoveObj = hMoveObj ? hMoveObj : pLink->m_hObject; break; } } if (fDist > fFarthestMarkDist) { fFarthestMarkDist = fDist; hFarObj = pLink->m_hObject; } } pLink = pLink->m_pNext; } // If we've got the max number of marks on this object, just move // the closest one to the new position... if (nNumMarks >= MAX_MARKS_PER_OBJECT) { hMoveObj = hMoveObj ? hMoveObj : (hFarObj ? hFarObj : pMarkList->m_pFirstLink->m_hObject); } else { hMoveObj = LTNULL; // Need to create one... } } // Re-setup the object to move it... if (hMoveObj && IsKindOf(hMoveObj, "CServerMark")) { CServerMark* pMoveMark = (CServerMark*) g_pLTServer->HandleToObject(hMoveObj); if (!pMoveMark) return; // Since this mark is already attached to pObj, remove the attachment // (since CServerMark::Setup() will re-attach it)... HATTACHMENT hAttachment; if (LT_OK == g_pLTServer->FindAttachment(theStruct.hObj, hMoveObj, &hAttachment)) { g_pLTServer->RemoveAttachment(hAttachment); } pMoveMark->Setup((CLIENTWEAPONFX)theStruct); return; } // Okay, no luck, need to create a new mark... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); LTFLOAT fScaleAdjust = 1.0f; if (!GetImpactSprite((SurfaceType)theStruct.nSurfaceType, fScaleAdjust, theStruct.nAmmoId, createStruct.m_Filename, ARRAY_LEN(createStruct.m_Filename))) { return; } createStruct.m_ObjectType = OT_SPRITE; createStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATEABLESPRITE; createStruct.m_Pos = theStruct.vPos; g_pLTServer->AlignRotation(&(createStruct.m_Rotation), &((LTVector)theStruct.vSurfaceNormal), LTNULL); HCLASS hClass = g_pLTServer->GetClass("CServerMark"); CServerMark* pMark = (CServerMark*) g_pLTServer->CreateObject(hClass, &createStruct); if (!pMark) return; // Add the mark to the object... pObj->AddMark(pMark->m_hObject); // Randomly adjust the mark's scale to add a bit o spice... if (pAmmo->pImpactFX) { LTFLOAT fScale = fScaleAdjust * pAmmo->pImpactFX->fMarkScale; LTVector vScale; VEC_SET(vScale, fScale, fScale, fScale); g_pLTServer->ScaleObject(pMark->m_hObject, &vScale); } pMark->Setup((CLIENTWEAPONFX)theStruct); }