DBOOL CBaseParticleSystemFX::CreateObject(CClientDE *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE; DVector vPos; DRotation rRot; ROT_INIT(rRot); // Use server object position if a position wasn't specified... if (m_vPos.x == 0.0f && m_vPos.y == 0.0f && m_vPos.z == 0.0f) { if (m_hServerObject) { pClientDE->GetObjectPos(m_hServerObject, &vPos); } } else { VEC_COPY(vPos, m_vPos); } // Use the specified rotation if applicable if (m_rRot.m_Vec.x != 0.0f || m_rRot.m_Vec.y != 0.0f || m_rRot.m_Vec.z != 0.0f || m_rRot.m_Spin != 1.0f) { ROT_COPY(rRot, m_rRot); } // Setup the ParticleSystem... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_PARTICLESYSTEM; createStruct.m_Flags = FLAG_VISIBLE | FLAG_UPDATEUNSEEN; VEC_COPY(createStruct.m_Pos, vPos); ROT_COPY(createStruct.m_Rotation, rRot); m_hObject = m_pClientDE->CreateObject(&createStruct); m_pClientDE->SetupParticleSystem(m_hObject, m_pTextureName, m_fGravity, m_dwFlags, m_fRadius / 640.0f); VEC_SET(m_vColorRange, m_vColor2.x - m_vColor1.x, m_vColor2.y - m_vColor1.y, m_vColor2.z - m_vColor1.z); if (m_vColorRange.x < 0.0f) m_vColorRange.x = 0.0f; if (m_vColorRange.y < 0.0f) m_vColorRange.y = 0.0f; if (m_vColorRange.z < 0.0f) m_vColorRange.z = 0.0f; return DTRUE; }
void CMovement::DebugDrawPath() { CServerDE* pServerDE = BaseClass::GetServerDE(); if (!pServerDE) return; HCLASS hClass = pServerDE->GetClass( "CClientDebugLine" ); if( !hClass ) return; ObjectCreateStruct ocStruct; INIT_OBJECTCREATESTRUCT(ocStruct); VEC_COPY(ocStruct.m_Pos, m_vPos); ROT_COPY(ocStruct.m_Rotation, m_rRot); DLink* pLink1 = m_PathList.m_Head.m_pNext; DLink* pLink2 = pLink1->m_pNext; while(pLink1->m_pData && pLink2->m_pData) { CClientDebugLine* pDebugline = (CClientDebugLine*)pServerDE->CreateObject(hClass, &ocStruct); pDebugline->Setup((DVector*)pLink1->m_pData, (DVector*)pLink2->m_pData); pLink1 = pLink1->m_pNext; pLink2 = pLink2->m_pNext; } return; }
void Explosion::AddShockwave(DVector *pvPoint) { if (!g_pServerDE) return; ObjectCreateStruct ocStruct; INIT_OBJECTCREATESTRUCT(ocStruct); DRotation rRot; ROT_INIT(rRot); g_pServerDE->SetupEuler(&rRot, MATH_HALFPI, 0.0f, 0.0f); ROT_COPY(ocStruct.m_Rotation, rRot); VEC_COPY(ocStruct.m_Pos, *pvPoint); ocStruct.m_Flags = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE; CImpact* pShockwave = CreateImpact(ocStruct, m_hstrShockwaveSprite); if (!pShockwave) return; if (pShockwave) { DVector vNormal; VEC_SET(vNormal, 0.0f, 1.0f, 0.0f); pShockwave->Setup(vNormal, m_vShockwaveScaleMin, m_vShockwaveScaleMax, DNULL, 0, m_fShockwaveDuration, DTRUE, DFALSE); m_hShockwave = g_pServerDE->ObjectToHandle(pShockwave); g_pServerDE->CreateInterObjectLink(m_hObject, m_hShockwave); } }
DBOOL CShellCasingFX::CreateObject(CClientDE *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE; char* pModelName = DNULL; char* pSkinName = DNULL; if (!GetFileNames(&pModelName, &pSkinName)) return DFALSE; if (!pModelName || !pSkinName) return DFALSE; // Setup the shell... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_MODEL; createStruct.m_Flags = 0; _mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)pModelName); _mbscpy((unsigned char*)createStruct.m_SkinName, (const unsigned char*)pSkinName); VEC_COPY(createStruct.m_Pos, m_vStartPos); ROT_COPY(createStruct.m_Rotation, m_rRot); m_hObject = pClientDE->CreateObject(&createStruct); if (!m_hObject) return DFALSE; m_pClientDE->SetObjectScale(m_hObject, &m_vScale); DVector vU, vR, vF; pClientDE->GetRotationVectors(&m_rRot, &vU, &vR, &vF); DVector vVel; if(m_bLeftHanded) VEC_NEGATE(vR, vR); DFLOAT fUpVel = GetRandom(60.0f, 90.0f); VEC_MULSCALAR(vU, vU, fUpVel); DFLOAT fRightVel = GetRandom(50.0f, 70.0f); VEC_MULSCALAR(vR, vR, fRightVel); DFLOAT fForwardVel = GetRandom(10.0f, 25.0f); VEC_MULSCALAR(vF, vF, fForwardVel); VEC_ADD(vVel, vU, vR); VEC_ADD(vVel, vVel, vF); InitMovingObject(&m_movingObj, &m_vStartPos, &vVel);; m_movingObj.m_PhysicsFlags |= MO_HALFGRAVITY; m_fExpireTime = 20.0f + m_pClientDE->GetTime(); // Set the pitch velocity m_fPitchVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2); m_fYawVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2); m_fPitch = m_fYaw = 0.0f; return DTRUE; }
DBOOL CBaseLineSystemFX::CreateObject(CClientDE *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE; DVector vPos; VEC_COPY(vPos, m_vPos); if (m_vPos.x == 0.0f && m_vPos.y == 0.0f && m_vPos.z == 0.0f) { if (m_hServerObject) { pClientDE->GetObjectPos(m_hServerObject, &vPos); } } DRotation rRot; ROT_COPY(rRot, m_rRot); if (m_rRot.m_Spin == 0.0f) { if (m_hServerObject) { pClientDE->GetObjectRotation(m_hServerObject, &rRot); } } // Setup the LineSystem... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_LINESYSTEM; createStruct.m_Flags = FLAG_VISIBLE; VEC_COPY(createStruct.m_Pos, vPos); ROT_COPY(createStruct.m_Rotation, rRot); m_hObject = m_pClientDE->CreateObject(&createStruct); return DTRUE; }
void VolumeBrush::CreateSurface() { CServerDE* pServerDE = GetServerDE(); if (!pServerDE) return; ObjectCreateStruct theStruct; INIT_OBJECTCREATESTRUCT(theStruct); DVector vPos, vDims, vScale; VEC_INIT(vScale); pServerDE->GetObjectDims(m_hObject, &vDims); pServerDE->GetObjectPos(m_hObject, &vPos); DRotation rRot; pServerDE->GetObjectRotation(m_hObject, &rRot); VEC_COPY(m_vLastPos, vPos); vPos.y += vDims.y - (m_fSurfaceHeight/2.0f); VEC_COPY(theStruct.m_Pos, vPos); ROT_COPY(theStruct.m_Rotation, rRot); HCLASS hClass = pServerDE->GetClass("PolyGrid"); PolyGrid* pSurface = DNULL; if (hClass) { pSurface = (PolyGrid *)pServerDE->CreateObject(hClass, &theStruct); } if (pSurface) { m_hSurfaceObj = pSurface->m_hObject; vDims.y = m_fSurfaceHeight; DFLOAT fXPan = 1.0f + (m_vCurrent.x * 0.01f); DFLOAT fYPan = 1.0f + (m_vCurrent.y * 0.01f); pSurface->Setup(&vDims, &m_vSurfaceColor1, &m_vSurfaceColor2, m_hstrSurfaceSprite, m_fXScaleMin, m_fXScaleMax, m_fYScaleMin, m_fYScaleMax, m_fXScaleDuration, m_fYScaleDuration, fXPan, fYPan, m_fSurfaceAlpha, m_dwNumSurfacePolies); // pServerDE->SetObjectColor(m_hSurfaceObj,1.0f,0,0,0.1f); } }
DBOOL CShellCasingFX::Init(SFXCREATESTRUCT* psfxCreateStruct) { if (!psfxCreateStruct) return DFALSE; CSpecialFX::Init(psfxCreateStruct); SHELLCREATESTRUCT* pShell = (SHELLCREATESTRUCT*)psfxCreateStruct; ROT_COPY(m_rRot, pShell->rRot); VEC_COPY(m_vStartPos, pShell->vStartPos); m_nAmmoType = pShell->nAmmoType; m_bLeftHanded = pShell->bLeftHanded; if(m_nAmmoType == AMMO_SHELL) { VEC_SET(m_vScale, 2.25f, 2.25f, 2.25f); } else { VEC_SET(m_vScale, 1.5f, 1.5f, 1.5f); } return DTRUE; }
DBOOL CMarkSFX::Init(SFXCREATESTRUCT* psfxCreateStruct) { if (!psfxCreateStruct) return DFALSE; CSpecialFX::Init(psfxCreateStruct); MARKCREATESTRUCT* pMark = (MARKCREATESTRUCT*)psfxCreateStruct; if (pMark->m_bServerObj && pMark->hServerObj) g_pClientDE->GetObjectPos(pMark->hServerObj, &m_Pos); else VEC_COPY( m_Pos, pMark->m_Pos ); ROT_COPY( m_Rotation, pMark->m_Rotation ); VEC_SET( m_vScale, pMark->m_fScale, pMark->m_fScale, pMark->m_fScale ); if( m_hstrSprite ) g_pClientDE->FreeString( m_hstrSprite ); m_hstrSprite = g_pClientDE->CopyString( pMark->m_hstrSprite ); m_bServerObj = pMark->m_bServerObj; return DTRUE; }
DBOOL CFlashlightFX::CreateObject(CClientDE *pClientDE) { DBOOL bRet = CSpecialFX::CreateObject(pClientDE); if (!bRet) return bRet; // Setup the light... DVector vPos; pClientDE->GetObjectPos(m_hServerObject, &vPos); DRotation rRot; pClientDE->GetObjectRotation(m_hServerObject, &rRot); ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_LIGHT; createStruct.m_Flags = 0; VEC_COPY(createStruct.m_Pos, vPos); ROT_COPY(createStruct.m_Rotation, rRot); m_hObject = m_pClientDE->CreateObject(&createStruct); return DTRUE; }
// ----------------------------------------------------------------------- // // // ROUTINE: CameraObj::DisplayRay // // PURPOSE: Display a Ray from the Camera // // ----------------------------------------------------------------------- // DBOOL CameraObj::DisplayRay() { if (!g_pServerDE) return DFALSE; // Cast a Ray Forward From the camera (DebugOnly) if (m_hRay) g_pServerDE->RemoveObject(m_hRay); ObjectCreateStruct theStruct; INIT_OBJECTCREATESTRUCT(theStruct); DVector vPos; DRotation rRot; g_pServerDE->GetObjectPos(m_hObject, &vPos); g_pServerDE->GetObjectRotation(m_hObject, &rRot); VEC_COPY(theStruct.m_Pos, vPos); ROT_COPY(theStruct.m_Rotation,rRot); HCLASS hClass = g_pServerDE->GetClass("CClientCastLineSFX"); CClientCastLineSFX* pLine = DNULL; if (hClass) { pLine = (CClientCastLineSFX*)g_pServerDE->CreateObject(hClass, &theStruct); if (!pLine) return DFALSE; } DVector vColor; VEC_SET(vColor, 0.0f, 1.0f, 0.0f); // Green Line pLine->Setup(vColor, vColor, 1.0f, 1.0f); m_hRay = pLine->m_hObject; return DTRUE; }
HOBJECT SpawnWeaponPickup(DDWORD dwWeapType, HOBJECT hOwner, DVector *pvPos, DRotation *prRot, DBOOL bIncludeAmmo) { HCLASS hClass = NULL; HOBJECT hObject = NULL; switch (dwWeapType) { case WEAP_BERETTA: hClass = g_pServerDE->GetClass("BerettaPU"); break; case WEAP_SHOTGUN: hClass = g_pServerDE->GetClass("ShotgunPU"); break; case WEAP_SNIPERRIFLE: hClass = g_pServerDE->GetClass("SniperRiflePU"); break; case WEAP_ASSAULTRIFLE: hClass = g_pServerDE->GetClass("AssaultRiflePU"); break; case WEAP_SUBMACHINEGUN: hClass = g_pServerDE->GetClass("SubMachineGunPU"); break; case WEAP_FLAREGUN: hClass = g_pServerDE->GetClass("FlareGunPU"); break; case WEAP_HOWITZER: hClass = g_pServerDE->GetClass("HowitzerPU"); break; case WEAP_BUGSPRAY: hClass = g_pServerDE->GetClass("BugSprayPU"); break; case WEAP_NAPALMCANNON: hClass = g_pServerDE->GetClass("NapalmCannonPU"); break; case WEAP_MINIGUN: hClass = g_pServerDE->GetClass("MiniGunPU"); break; case WEAP_VOODOO: hClass = g_pServerDE->GetClass("VoodooDollPU"); break; case WEAP_ORB: hClass = g_pServerDE->GetClass("OrbPU"); break; case WEAP_DEATHRAY: hClass = g_pServerDE->GetClass("DeathRayPU"); break; case WEAP_LIFELEECH: hClass = g_pServerDE->GetClass("LifeLeechPU"); break; case WEAP_TESLACANNON: hClass = g_pServerDE->GetClass("TeslaCannonPU"); break; case WEAP_SINGULARITY: hClass = g_pServerDE->GetClass("SingularityPU"); break; #ifdef _ADD_ON case WEAP_COMBATSHOTGUN: hClass = g_pServerDE->GetClass("CombatShotgunPU"); break; case WEAP_FLAYER: hClass = g_pServerDE->GetClass("FlayerPU"); break; #endif } if (hClass) { ObjectCreateStruct ocStruct; DVector vPos; DRotation rRot; if (pvPos && prRot) { VEC_COPY(vPos, *pvPos); ROT_COPY(rRot, *prRot); } else { g_pServerDE->GetObjectPos(hOwner, &vPos); g_pServerDE->GetObjectRotation(hOwner, &rRot); } INIT_OBJECTCREATESTRUCT(ocStruct); VEC_COPY(ocStruct.m_Pos, vPos) ROT_COPY(ocStruct.m_Rotation, rRot) ocStruct.m_Flags = (FLAG_VISIBLE | FLAG_TOUCH_NOTIFY /* | FLAG_SHADOW */ ); WeaponPickup* pObject = (WeaponPickup*)g_pServerDE->CreateObject(hClass, &ocStruct); hObject = g_pServerDE->ObjectToHandle(pObject); pObject->SetBounce( DFALSE ); pObject->SpawnItem(&vPos); if( !bIncludeAmmo ) pObject->SetValue( 0.0f ); } return hObject; }
DBOOL CMarkSFX::CreateObject(CClientDE *pClientDE) { if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE; CSFXMgr* psfxMgr = g_pBloodClientShell->GetSFXMgr(); if (!psfxMgr) return DFALSE; // Before we create a new buillet hole see if there is already another // bullet hole close by that we could use instead... CSpecialFXList* pList = psfxMgr->GetBulletHoleFXList(); if (!pList) return DFALSE; int nNumBulletHoles = pList->GetSize(); HOBJECT hMoveObj = DNULL; HOBJECT hObj = DNULL; DFLOAT fClosestMarkDist = REGION_DIAMETER; DBYTE nNumInRegion = 0; DVector vPos; for (int i=0; i < nNumBulletHoles; i++) { if ((*pList)[i]) { hObj = (*pList)[i]->GetObject(); if (hObj) { pClientDE->GetObjectPos(hObj, &vPos); DFLOAT fDist = VEC_DISTSQR(vPos, m_Pos); if (fDist < REGION_DIAMETER) { if (fDist < fClosestMarkDist) { fClosestMarkDist = fDist; hMoveObj = hObj; } if (++nNumInRegion > MAX_MARKS_IN_REGION) { // Just move this bullet-hole to the correct pos, and // remove thyself... pClientDE->SetObjectPos(hMoveObj, &m_Pos); return DFALSE; } } } } } // Setup the mark... ObjectCreateStruct createStruct; INIT_OBJECTCREATESTRUCT(createStruct); createStruct.m_ObjectType = OT_SPRITE; _mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)m_pClientDE->GetStringData( m_hstrSprite )); createStruct.m_Flags = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE; VEC_COPY(createStruct.m_Pos, m_Pos); ROT_COPY( createStruct.m_Rotation, m_Rotation ); m_hObject = pClientDE->CreateObject(&createStruct); m_pClientDE->SetObjectScale(m_hObject, &m_vScale); // See what it hit DVector vU, vR; pClientDE->GetRotationVectors(&m_Rotation, &vU, &vR, &m_vForward); ClientIntersectQuery iq; ClientIntersectInfo ii; iq.m_Flags = INTERSECT_OBJECTS | INTERSECT_HPOLY; VEC_COPY(iq.m_From, vPos); // Get start point at the last known position. VEC_MULSCALAR(iq.m_To, m_vForward, -1.0f); VEC_ADD(iq.m_To, iq.m_To, iq.m_From); // Get destination point slightly past where we should be // Hit something! try to clip against it. (since this is only being used for bullet marks, if (pClientDE->IntersectSegment(&iq, &ii)) { HPOLY hPoly = ii.m_hPoly; pClientDE->ClipSprite(m_hObject, hPoly); } m_pClientDE->SetObjectColor(m_hObject, 0.1f, 0.1f, 0.1f, 1.0f); return DTRUE; }
DDWORD bc_EngineMessageFn(LPBASECLASS pObject, DDWORD messageID, void *pData, float fData) { LPAGGREGATE pAggregate; ObjectCreateStruct *pStruct; GenericProp genProp; // Handle ReadProp. switch(messageID) { case MID_PRECREATE: { // Get the props. if( fData == 1.0f || fData == 2.0f ) { pStruct = (ObjectCreateStruct*)pData; if( g_pServerDE->GetPropGeneric( "Name", &genProp ) == DE_OK ) { SAFE_STRCPY(pStruct->m_Name, genProp.m_String); pStruct->m_Name[MAX_CS_FILENAME_LEN] = '\0'; } if( g_pServerDE->GetPropGeneric( "Pos", &genProp ) == DE_OK ) { VEC_COPY( pStruct->m_Pos, genProp.m_Vec ); } if( g_pServerDE->GetPropGeneric( "Rotation", &genProp ) == DE_OK ) { ROT_COPY( pStruct->m_Rotation, genProp.m_Rotation ); } if( g_pServerDE->GetPropGeneric( "Flags", &genProp ) == DE_OK ) { pStruct->m_Flags = genProp.m_Long; } if( g_pServerDE->GetPropGeneric( "Visible", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_VISIBLE; else pStruct->m_Flags &= ~FLAG_VISIBLE; } if( g_pServerDE->GetPropGeneric( "Shadow", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_SHADOW; else pStruct->m_Flags &= ~FLAG_SHADOW; } if( g_pServerDE->GetPropGeneric( "RotateableSprite", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_ROTATEABLESPRITE; else pStruct->m_Flags &= ~FLAG_ROTATEABLESPRITE; } if( g_pServerDE->GetPropGeneric( "Chromakey", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_SPRITECHROMAKEY; else pStruct->m_Flags &= ~FLAG_SPRITECHROMAKEY; } if( g_pServerDE->GetPropGeneric( "Solid", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_SOLID; else pStruct->m_Flags &= ~FLAG_SOLID; } if( g_pServerDE->GetPropGeneric( "Gravity", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_GRAVITY; else pStruct->m_Flags &= ~FLAG_GRAVITY; } if( g_pServerDE->GetPropGeneric( "TouchNotify", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_TOUCH_NOTIFY; else pStruct->m_Flags &= ~FLAG_TOUCH_NOTIFY; } if( g_pServerDE->GetPropGeneric( "Rayhit", &genProp ) == DE_OK ) { if( genProp.m_Bool ) pStruct->m_Flags |= FLAG_RAYHIT; else pStruct->m_Flags &= ~FLAG_RAYHIT; } if( g_pServerDE->GetPropGeneric( "Filename", &genProp ) == DE_OK ) { SAFE_STRCPY(pStruct->m_Filename, genProp.m_String); pStruct->m_Filename[MAX_CS_FILENAME_LEN] = '\0'; } if( g_pServerDE->GetPropGeneric( "Skin", &genProp ) == DE_OK ) { SAFE_STRCPY(pStruct->m_SkinName, genProp.m_String); pStruct->m_SkinName[MAX_CS_FILENAME_LEN] = '\0'; } break; } } } // Call the aggregates. pAggregate = pObject->m_pFirstAggregate; while(pAggregate) { pAggregate->m_EngineMessageFn(pObject, pAggregate, messageID, pData, fData); pAggregate = pAggregate->m_pNextAggregate; } // Default return is 1. return 1; }
DVector CPlayerCamera::FindOptimalCameraPosition() { DVector pos; VEC_INIT(pos); if (!m_pClientDE || !m_hTarget) return pos; DVector up, right, forward, dir; DFLOAT distToOptimal; DVector TargetPlusOffset; DVector vTargetPos; m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos); DRotation rRot; m_pClientDE->GetObjectRotation(m_hTarget, &rRot); if (Equal(vTargetPos, m_vLastTargetPos) && Equal(rRot, m_rLastTargetRot) && m_eCameraMode != DEATH) { return m_vLastOptPos; } else { VEC_COPY(m_vLastTargetPos, vTargetPos); ROT_COPY(m_rLastTargetRot, rRot); } DVector vTemp; if (m_eCameraMode == DEATH) { VEC_COPY(vTemp, m_TargetDeathOffset); } else { VEC_COPY(vTemp, m_TargetChaseOffset); } VEC_ADD(vTemp, vTargetPos, vTemp); VEC_COPY(TargetPlusOffset, vTemp); m_pClientDE->GetRotationVectors(&rRot, &up, &right, &forward); // pos = TargetPlusOffset + right*m_OptX + up*m_OptY + forward*m_OptZ; DVector vTemp1, vTemp2; if (m_eCameraMode == DEATH) { VEC_MULSCALAR(vTemp, right, m_DeathOptX); VEC_MULSCALAR(vTemp2, forward, m_DeathOptZ); } else { VEC_MULSCALAR(vTemp, right, m_OptX); VEC_MULSCALAR(vTemp2, forward, m_OptZ); } VEC_MULSCALAR(vTemp1, up, m_OptY); ClientIntersectQuery iQuery; ClientIntersectInfo iInfo; VEC_ADD(vTemp, vTemp, vTemp1); VEC_ADD(vTemp, vTemp, vTemp2); VEC_ADD(pos, TargetPlusOffset, vTemp); VEC_SUB(vTemp, TargetPlusOffset, pos); distToOptimal = VEC_MAG(vTemp); VEC_SUB(dir, pos, TargetPlusOffset); VEC_NORM(dir); VEC_COPY(iQuery.m_From, TargetPlusOffset); VEC_COPY(iQuery.m_To, pos); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vTemp, iInfo.m_Point, TargetPlusOffset); // If there was something in the way, move in front of that thing. if (VEC_MAG(vTemp) < distToOptimal) { VEC_ADD(pos, iInfo.m_Point, iInfo.m_Plane.m_Normal); } } #ifdef DOING_EXTRA_CHECKS // Make sure we aren't clipping into walls... DFLOAT fClipDistance = 100.0f; // 15.0f; DBOOL bClipRightIssues = DTRUE; DBOOL bClipUpIssues = DTRUE; // Check for walls to the right... VEC_MULSCALAR(vTemp, right, fClipDistance); VEC_ADD(vTemp, pos, vTemp); VEC_COPY(iQuery.m_From, pos); VEC_COPY(iQuery.m_To, vTemp); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vTemp, iInfo.m_Point, pos); DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp)); VEC_MULSCALAR(vTemp, right, -fDist) VEC_ADD(pos, pos, vTemp); } else { bClipRightIssues = DFALSE; } // If we didn't adjust for a wall to the right, check walls to the left... if (!bClipRightIssues) { VEC_MULSCALAR(vTemp, right, -fClipDistance); VEC_ADD(vTemp, pos, vTemp); VEC_COPY(iQuery.m_From, pos); VEC_COPY(iQuery.m_To, vTemp); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vTemp, iInfo.m_Point, pos); DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp)); VEC_MULSCALAR(vTemp, right, fDist) VEC_ADD(pos, pos, vTemp); } } // Check for ceilings... VEC_MULSCALAR(vTemp, up, fClipDistance); VEC_ADD(vTemp, pos, vTemp); VEC_COPY(iQuery.m_From, pos); VEC_COPY(iQuery.m_To, vTemp); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vTemp, iInfo.m_Point, pos); DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp)); VEC_MULSCALAR(vTemp, up, -fDist) VEC_ADD(pos, pos, vTemp); } else { bClipUpIssues = DFALSE; } // If we didn't hit any ceilings, check for floors... if (!bClipUpIssues) { VEC_MULSCALAR(vTemp, up, -fClipDistance); VEC_ADD(vTemp, pos, vTemp); VEC_COPY(iQuery.m_From, pos); VEC_COPY(iQuery.m_To, vTemp); if (m_pClientDE->IntersectSegment(&iQuery, &iInfo)) { VEC_SUB(vTemp, iInfo.m_Point, pos); DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp)); VEC_MULSCALAR(vTemp, up, fDist) VEC_ADD(pos, pos, vTemp); } } #endif // DOING_EXTRA_CHECKS VEC_COPY(m_vLastOptPos, pos); return pos; }