📄 objectutilities.cpp
字号:
if(pLink == DNULL)
return;
while(pLink != &AI_Mgr::m_CabalHead)
{
hObject = pServerDE->ObjectToHandle((BaseClass*)pLink->m_pData);
if (!hObject)
break;
if(hObject != hSender)
{
pServerDE->GetObjectPos(hObject,&vAIPos);
if(VEC_DISTSQR(vPos,vAIPos) <= fRadius)
{
sprintf(szTemp, "%s %d %.1f %.1f %.1f;", TRIGGER_SOUND, nId, vPos.x, vPos.y, vPos.z);
LPBASECLASS lpClass = pServerDE->HandleToObject( hSender );
HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject( lpClass, hObject, MID_TRIGGER );
HSTRING hString = pServerDE->CreateString( szTemp );
pServerDE->WriteToMessageHString( hMessage, hString );
pServerDE->FreeString( hString );
pServerDE->EndMessage( hMessage );
}
}
pLink = pLink->m_pNext;
}
pLink = AI_Mgr::m_MonsterHead.m_pNext;
if(pLink == DNULL)
return;
while(pLink != &AI_Mgr::m_MonsterHead)
{
hObject = pServerDE->ObjectToHandle((BaseClass*)pLink->m_pData);
if (!hObject)
break;
if(hObject != hSender)
{
pServerDE->GetObjectPos(hObject,&vAIPos);
if(VEC_DISTSQR(vPos,vAIPos) <= fRadius)
{
sprintf(szTemp, "%s %d %.1f %.1f %.1f;", TRIGGER_SOUND, nId, vPos.x, vPos.y, vPos.z);
LPBASECLASS lpClass = pServerDE->HandleToObject(hSender);
HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject(lpClass, hObject, MID_TRIGGER);
HSTRING hString = pServerDE->CreateString(szTemp);
pServerDE->WriteToMessageHString(hMessage, hString );
pServerDE->FreeString( hString );
pServerDE->EndMessage(hMessage);
}
}
pLink = pLink->m_pNext;
}
return;
}
//-------------------------------------------------------------------------------------------
//
// ROUTINE: MoveObjectToGround
//
// PURPOSE: Move this object down so that it rests on the object or world below it.
//
//-------------------------------------------------------------------------------------------
DBOOL MoveObjectToGround(HOBJECT hObject)
{
if (!hObject || !g_pServerDE) return DFALSE;
// Cast a ray to see what's below us
IntersectQuery iq;
IntersectInfo ii;
DVector vPos;
g_pServerDE->GetObjectPos(hObject, &vPos);
VEC_COPY(iq.m_From, vPos);
VEC_SET(iq.m_Direction, 0.0f, -1.0f, 0.0f);
iq.m_Flags = IGNORE_NONSOLID | INTERSECT_OBJECTS;
iq.m_FilterFn = NULL;
iq.m_pUserData = NULL;
if (g_pServerDE->CastRay(&iq, &ii)) // Hit
{
DVector vDims;
if(g_pServerDE->IsKindOf(g_pServerDE->GetObjectClass(hObject), g_pServerDE->GetClass("CBaseCharacter")))
{
if(g_pServerDE->GetModelAnimUserDims(hObject, &vDims, 0) == DE_INVALIDPARAMS)
g_pServerDE->DebugOut("MoveObjectToGround() fucked up\r\n");
}
else
g_pServerDE->GetObjectDims(hObject, &vDims);
DFLOAT fDist = vPos.y - ii.m_Point.y + 0.1f;
if (fDist > vDims.y)
{
vPos.y = vPos.y - fDist + (vDims.y + 0.1f);
g_pServerDE->MoveObject(hObject, &vPos);
return DTRUE;
}
}
return DFALSE;
}
DBOOL GlobalFilterFn(HOBJECT hObj, void *pUserData)
{
DDWORD dwObject;
GlobalFilterFnData *pGlobalFilterFnData;
if (!hObj || !g_pServerDE) return DFALSE;
if( !pUserData )
return DTRUE;
pGlobalFilterFnData = ( GlobalFilterFnData * )pUserData;
if( pGlobalFilterFnData->m_nIgnoreObjects && pGlobalFilterFnData->m_hIgnoreObjects )
{
for( dwObject = 0; dwObject < pGlobalFilterFnData->m_nIgnoreObjects; dwObject++ )
{
if( pGlobalFilterFnData->m_hIgnoreObjects[dwObject] == hObj )
return DFALSE;
}
}
HCLASS hObjClass = g_pServerDE->GetObjectClass(hObj);
BaseClass* pObj = (BaseClass*)g_pServerDE->HandleToObject(hObj);
if( pGlobalFilterFnData->m_dwFlags & IGNORE_CHARACTER)
{
HCLASS hCharacter = g_pServerDE->GetClass("CBaseCharacter");
if(g_pServerDE->IsKindOf(hObjClass, hCharacter))
return DFALSE;
}
if( pGlobalFilterFnData->m_dwFlags & IGNORE_LIQUID)
{
HCLASS hLiquid = g_pServerDE->GetClass("VolumeBrush");
if(g_pServerDE->IsKindOf(hObjClass, hLiquid))
return DFALSE;
}
if( pGlobalFilterFnData->m_dwFlags & IGNORE_DESTRUCTABLE)
{
HCLASS hDestruct = g_pServerDE->GetClass("CDestructableModel");
if(g_pServerDE->IsKindOf(hObjClass, hDestruct))
{
CDestructableModel* pModel = (CDestructableModel*)g_pServerDE->HandleToObject(hObj);
if(pModel->IsDestructable())
return DFALSE;
}
}
if( pGlobalFilterFnData->m_dwFlags & IGNORE_GLASS)
{
HCLASS hBrush = g_pServerDE->GetClass("CDestructableBrush");
if(g_pServerDE->IsKindOf(hObjClass, hBrush))
{
CDestructableBrush* pBrush = (CDestructableBrush*)g_pServerDE->HandleToObject(hObj);
if(pBrush->GetSurfaceType() == SURFTYPE_GLASS && pBrush->IsDestructable())
return DFALSE;
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: DamageObject()
//
// PURPOSE: Damage the specified object
//
// PARAMETERS:
//
// hResponsible - Handle to the object responsible for the damage
// (may or may not be the same as pDamager->m_hObject)
// pDamager - Pointer to the object that is doing the damage.
// hDamagee - Handle to the object taking the damage
// fDamage - The amount of damage being inflicted
// vDir - The direction the damage is coming from
// nDamageType - The type of damage being inflicted.
//
// ----------------------------------------------------------------------- //
void DamageObject(HOBJECT hResponsible, LPBASECLASS pDamager,
HOBJECT hDamagee, DFLOAT fDamage, DVector vDir, DVector vPos,DBYTE nDamageType)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !pDamager || !hDamagee) return;
// Damage object...
HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject(pDamager, hDamagee, MID_DAMAGE);
pServerDE->WriteToMessageVector(hMessage, &vDir);
pServerDE->WriteToMessageFloat(hMessage, fDamage);
pServerDE->WriteToMessageByte(hMessage, nDamageType);
pServerDE->WriteToMessageObject(hMessage, hResponsible);
pServerDE->WriteToMessageVector(hMessage, &vPos);
pServerDE->EndMessage(hMessage);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: DamageObjectsInRadius()
//
// PURPOSE: Damage objects within a certain radius
//
// PARAMETERS:
//
// hResponsible - Handle to the object responsible for the damage
// (may or may not be the same as pDamager->m_hObject)
// pDamager - Pointer to the object that is doing the damage.
// vOrigin - Center of the damage sphere
// fRadius - The radius of the damage sphere
// fDamage - The amount of damage inflicted.
// eType - The type of damage being inflicted.
//
// ----------------------------------------------------------------------- //
void DamageObjectsInRadius(HOBJECT hResponsible, LPBASECLASS pDamager,
DVector vOrigin, DFLOAT fRadius,
DFLOAT fDamage, DBYTE nDamageType)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || fRadius <= 0.0f) return;
// Set area of effect damage type flag, for those who care
nDamageType |= DAMAGE_FLAG_AREAEFFECT;
DLink* pLink = CDestructable::m_DestructableHead.m_pNext;
if(!pLink)
return;
// small optimization..
// Work with the squares of the distances so as to not have to get a square root.
DFLOAT fRadiusSquared = fRadius * fRadius;
DFLOAT fHalfRadiusSquared = fRadiusSquared/2;
HOBJECT hObj;
while(pLink != &CDestructable::m_DestructableHead)
{
hObj = ((CDestructable*)pLink->m_pData)->GetObject();
if (!hObj)
{
pLink = pLink->m_pNext;
continue;
}
DVector vDir, vObjPos, vObjDims;
pServerDE->GetObjectPos(hObj, &vObjPos);
// Get the average of the objects dims
pServerDE->GetObjectDims(hObj, &vObjDims);
DFLOAT fAvgDim = (vObjDims.x + vObjDims.y + vObjDims.z) / 3.0f;
fAvgDim = fAvgDim * fAvgDim;
VEC_SUB(vDir, vObjPos, vOrigin);
DFLOAT fDistanceSquared = VEC_MAGSQR(vDir) - fAvgDim;
// Apply full damage to 50% point, then reduce it
if (fDistanceSquared < fHalfRadiusSquared)
{
DamageObject(hResponsible, pDamager, hObj, fDamage, vDir, vOrigin, nDamageType);
}
else if (fDistanceSquared <= fRadiusSquared)
{
DFLOAT fAdjDamage = fDamage - (fDistanceSquared - fHalfRadiusSquared) / fHalfRadiusSquared * fDamage;
DamageObject(hResponsible, pDamager, hObj, fAdjDamage, vDir, vOrigin, nDamageType);
}
pLink = pLink->m_pNext;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -