📄 corpse.cpp
字号:
//
// DESCRIPTION :
//
// RETURN TYPE : int
//
// ----------------------------------------------------------------------- //
int CCorpse::CalculateHitLimb(DVector vDir, DVector vPos)
{
int nNode = -1;
DFLOAT fNodeDist = 0.0f, fDist = 999.0f, fTemp = 0.0f;
DVector vShot, vNewShot, vTemp, vObjDims, vNodePos, vZ;
DFLOAT fX, fY, ft;
DBOOL bStatus = DFALSE;
DRotation rRot;
g_pServerDE->GetModelAnimUserDims(m_hObject, &vObjDims, g_pServerDE->GetModelAnimation(m_hObject));
vTemp.x = (float)fabs(vDir.x);
vTemp.y = (float)fabs(vDir.y);
vTemp.z = (float)fabs(vDir.z);
if(vTemp.x > vTemp.y && vTemp.x > vTemp.z)
{
fTemp = vObjDims.x / vTemp.x;
}
else if(vTemp.y > vTemp.x && vTemp.y > vTemp.z)
{
fTemp = vObjDims.y / vTemp.y;
}
else if(vTemp.z > vTemp.x && vTemp.z > vTemp.y)
{
fTemp = vObjDims.z / vTemp.z;
}
VEC_MULSCALAR(vNewShot,vDir,fTemp);
VEC_ADD(vShot,vPos,vNewShot);
DVector vC;
VEC_SUB(vC,vShot,vPos);
fX = 1 / VEC_DOT(vC,vC);
fY = fX * -(VEC_DOT(vC,vPos));
for(int i = 0; i < NUM_STD_NODES; i++)
{
g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[i], &bStatus);
if(!bStatus)
{
DBOOL bRet = g_pServerDE->GetModelNodeTransform(m_hObject, szNodes[i], &vNodePos, &rRot);
ft = VEC_DOT(vC,vNodePos) * fX + fY;
if(ft >= 0.0f && ft <= 1.0f)
{
VEC_ADDSCALED(vZ,vPos,vC, ft);
fNodeDist = VEC_DIST(vNodePos, vZ);
if(fNodeDist < fDist && fNodeDist <= m_fHitSpheres[i])
{
fDist = fNodeDist;
nNode = i;
}
}
}
}
//Do we leave a pass through mark behind us?
if(nNode != -1)
{
// CWeapon weap(WEAP_BERETTA);
// VEC_MULSCALAR(vTemp,vDir,-1.0f);
// weap.AddSparks(vPos, vTemp, m_fHitPoints, m_hObject, SURFTYPE_FLESH);
// weap.AddBloodSpurt(vPos, vTemp, m_fHitPoints, m_hObject, SURFTYPE_FLESH);
// vTemp.x *= -1.0f;
// vTemp.z *= -1.0f;
// weap.AddBloodSpurt(vPos, vTemp, m_fHitPoints, m_hObject, SURFTYPE_FLESH);
}
return nNode;
}
// ----------------------------------------------------------------------- //
// ROUTINE : CCorpse::SetProperNode
// DESCRIPTION : Set the hit node to the parent node of the limb
// RETURN TYPE : int
// PARAMS : int nNode
// ----------------------------------------------------------------------- //
int CCorpse::SetProperNode(int nNode)
{
switch(nNode)
{
case 0: return NODE_NECK;
case 1: return NODE_NECK;
case 2: return NODE_TORSO;
case 3: return NODE_TORSO;
case 4: return NODE_RARM;
case 5: return NODE_RARM;
case 6: return NODE_RARM;
case 7: return NODE_LARM;
case 8: return NODE_LARM;
case 9: return NODE_LARM;
case 10: return NODE_LLEG;
case 11: return NODE_LLEG;
case 12: return NODE_LLEG;
case 13: return NODE_LLEG;
case 14: return NODE_RLEG;
case 15: return NODE_RLEG;
case 16: return NODE_RLEG;
case 17: return NODE_RLEG;
default: return -1;
}
return -1;
}
void CCorpse::GenerateHitSpheres()
{
DVector vNodePos[NUM_STD_NODES];
DRotation rRot;
for(int i = 0; i < NUM_STD_NODES; i++)
{
g_pServerDE->GetModelNodeTransform(m_hObject, szNodes[i], &vNodePos[i], &rRot);
}
//HEAD/NECK
m_fHitSpheres[0] = VEC_DIST(vNodePos[0],vNodePos[1]) * 0.66f;
m_fHitSpheres[1] = m_fHitSpheres[0];
//TORSO/PELVIS
m_fHitSpheres[2] = VEC_DIST(vNodePos[2],vNodePos[3]) * 0.66f;
m_fHitSpheres[3] = m_fHitSpheres[2];
//R_ARM
m_fHitSpheres[4] = VEC_DIST(vNodePos[4],vNodePos[5]) * 0.66f;
m_fHitSpheres[5] = VEC_DIST(vNodePos[5],vNodePos[6]) * 0.66f;
m_fHitSpheres[6] = m_fHitSpheres[5];
//L_ARM
m_fHitSpheres[7] = VEC_DIST(vNodePos[7],vNodePos[8]) * 0.66f;
m_fHitSpheres[8] = VEC_DIST(vNodePos[8],vNodePos[9]) * 0.66f;
m_fHitSpheres[9] = m_fHitSpheres[8];
//L_LEG
m_fHitSpheres[10] = VEC_DIST(vNodePos[10],vNodePos[11]) * 0.66f;
m_fHitSpheres[11] = VEC_DIST(vNodePos[11],vNodePos[12]) * 0.66f;
m_fHitSpheres[12] = VEC_DIST(vNodePos[12],vNodePos[13]) * 0.66f;
m_fHitSpheres[13] = m_fHitSpheres[12];
//R_LEG
m_fHitSpheres[14] = VEC_DIST(vNodePos[14],vNodePos[15]) * 0.66f;
m_fHitSpheres[15] = VEC_DIST(vNodePos[15],vNodePos[16]) * 0.66f;
m_fHitSpheres[16] = VEC_DIST(vNodePos[16],vNodePos[17]) * 0.66f;
m_fHitSpheres[17] = m_fHitSpheres[16];
return;
}
// ----------------------------------------------------------------------- //
// ROUTINE : CCorpse::CreateGibs
// DESCRIPTION : create some nastiness
// RETURN TYPE : void
// ----------------------------------------------------------------------- //
DBOOL CCorpse::CreateGibs(DVector vDir, int nNumGibs, int nType, DFLOAT fDamage)
{
// HCLASS hClass = g_pServerDE->GetClass( "CClientGibFX" );
// if( !hClass )
// return DFALSE;
DFLOAT fVel = 50.0f + fDamage;
vDir.y -= 1.0f;
VEC_NORM(vDir);
VEC_MULSCALAR(vDir, vDir, fVel);
// ObjectCreateStruct ocStruct;
// INIT_OBJECTCREATESTRUCT(ocStruct);
DVector vPos;
g_pServerDE->GetObjectPos(m_hObject, &vPos);
// VEC_COPY(ocStruct.m_Pos, vPos);
// g_pServerDE->GetObjectRotation(m_hObject, &ocStruct.m_Rotation);
// CClientGibFX* pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct);
DVector vDims;
g_pServerDE->GetObjectDims(m_hObject, &vDims);
/* if(nType & DAMAGE_TYPE_EXPLODE)
pGib->Setup(&vPos, &vDir, &vDims, (SURFTYPE_FLESH/10) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, nNumGibs);
else
pGib->Setup(&vPos, &vDir, &vDims, (SURFTYPE_FLESH/10) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, nNumGibs);
*/
SetupClientGibFX(&vPos, &vDir, &vDims, (SURFTYPE_FLESH/10) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, nNumGibs);
// Create body parts
if(m_bLimbLoss)
{
// 100 % create a head..
DBOOL bNodeStatus;
if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_NECK], &bNodeStatus) == DE_OK)
{
if (!bNodeStatus) // not hidden
AIShared.CreateLimb(m_hObject, NODE_NECK, vDir);
}
if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_RARM], &bNodeStatus) == DE_OK)
{
if (!bNodeStatus && IsRandomChance(80))
AIShared.CreateLimb(m_hObject, NODE_RARM, vDir);
}
if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_LARM], &bNodeStatus) == DE_OK)
{
if (!bNodeStatus && IsRandomChance(80))
AIShared.CreateLimb(m_hObject, NODE_LARM, vDir);
}
if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_RLEG], &bNodeStatus) == DE_OK)
{
if (!bNodeStatus && IsRandomChance(60))
AIShared.CreateLimb(m_hObject, NODE_RLEG, vDir);
}
if (g_pServerDE->GetModelNodeHideStatus(m_hObject, szNodes[NODE_LLEG], &bNodeStatus) == DE_OK)
{
if (!bNodeStatus && IsRandomChance(60))
AIShared.CreateLimb(m_hObject, NODE_LLEG, vDir);
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CCorpse::Save
//
// PURPOSE: Save the object
//
// ----------------------------------------------------------------------- //
void CCorpse::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hWrite) return;
for (int i=0; i < NUM_STD_NODES; i++)
pServerDE->WriteToMessageFloat(hWrite, m_fHitSpheres[i]);
pServerDE->WriteToMessageFloat(hWrite, m_fMass);
pServerDE->WriteToMessageFloat(hWrite, m_fHitPoints);
pServerDE->WriteToMessageString(hWrite, m_szSoundDir);
pServerDE->WriteToMessageByte(hWrite, m_bLimbLoss);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CCorpse::Load
//
// PURPOSE: Load the object
//
// ----------------------------------------------------------------------- //
void CCorpse::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hRead) return;
for (int i=0; i < NUM_STD_NODES; i++)
m_fHitSpheres[i] = pServerDE->ReadFromMessageFloat(hRead);
m_fMass = pServerDE->ReadFromMessageFloat(hRead);
m_fHitPoints = pServerDE->ReadFromMessageFloat(hRead);
_mbscpy((unsigned char*)m_szSoundDir, (const unsigned char*)pServerDE->ReadFromMessageString(hRead));
m_bLimbLoss = pServerDE->ReadFromMessageByte(hRead);
}
// ----------------------------------------------------------------------- //
// ROUTINE : CCorpse::OnStringKey
// DESCRIPTION : read and parse string keys
// RETURN TYPE : void
// PARAMS : ArgList* pArgList
// ----------------------------------------------------------------------- //
void CCorpse::OnStringKey(ArgList* pArgList)
{
if (!g_pServerDE || !pArgList || !pArgList->argv || pArgList->argc == 0) return;
char* pKey = pArgList->argv[0];
if (!pKey) return;
char szTemp[32];
szTemp[0] = '\0';
if (m_szSoundDir[0] != '\0' && Sparam_Get(szTemp,pKey,"play_sound"))
{
char szSound[256];
char szTmp[32];
szSound[0] = '\0';
szTmp[0] = '\0';
if(Sparam_Get(szTmp,pKey,"sound_random"))
{
int nMax = atoi(szTmp);
int nNum = g_pServerDE->IntRandom(1,NRES(nMax));
sprintf(szSound, "%s\\%s%d.wav", m_szSoundDir, szTemp, nNum);
}
else
{
sprintf(szSound, "%s\\%s.wav", m_szSoundDir, szTemp);
}
DFLOAT fRadius = 1000.0f;
if(Sparam_Get(szTmp,pKey,"sound_radius"))
{
fRadius = (DFLOAT)atof(szTmp);
}
int nVol = 100;
if(Sparam_Get(szTmp,pKey,"sound_volume"))
{
nVol = atoi(szTmp);
}
PlayAISound(szSound, fRadius, 0, nVol);
}
return;
}
// ----------------------------------------------------------------------- //
// ROUTINE : CCorpse::PlayAISound
// DESCRIPTION :
// RETURN TYPE : DBOOL
// PARAMS : char* szSound
// PARAMS : DFLOAT fRadius
// ----------------------------------------------------------------------- //
DBOOL CCorpse::PlayAISound(char* szSound, DFLOAT fRadius, DDWORD dwFlags, int nVol)
{
if (m_hCurSound)
{
DBOOL bIsSoundDone;
if( !( dwFlags & PLAY_INTERRUPT))
return DFALSE;
if( ((dwFlags & PLAY_WAIT) && g_pServerDE->IsSoundDone(m_hCurSound, &bIsSoundDone) == LT_OK && !bIsSoundDone))
return DFALSE;
g_pServerDE->KillSound( m_hCurSound );
m_hCurSound = DNULL;
}
PlaySoundInfo playSoundInfo;
PLAYSOUNDINFO_INIT( playSoundInfo );
playSoundInfo.m_dwFlags = PLAYSOUND_3D | PLAYSOUND_ATTACHED | PLAYSOUND_REVERB;
// playSoundInfo.m_dwFlags |= PLAYSOUND_LOOP;
// playSoundInfo.m_dwFlags |= PLAYSOUND_GETHANDLE;
// playSoundInfo.m_dwFlags |= PLAYSOUND_FILESTREAM;
// playSoundInfo.m_dwFlags |= PLAYSOUND_TIME;
if(nVol < 100)
playSoundInfo.m_dwFlags |= PLAYSOUND_CTRL_VOL;
_mbsncpy((unsigned char*)playSoundInfo.m_szSoundName, (const unsigned char*)szSound, _MAX_PATH );
playSoundInfo.m_hObject = m_hObject;
playSoundInfo.m_nPriority = SOUNDPRIORITY_AI_MEDIUM;
playSoundInfo.m_fOuterRadius = fRadius;
playSoundInfo.m_fInnerRadius = fRadius * 0.1f;
playSoundInfo.m_nVolume = nVol;
g_pServerDE->PlaySound( &playSoundInfo );
m_hCurSound = playSoundInfo.m_hSound;
return DTRUE;
}
// ----------------------------------------------------------------------- //
// ROUTINE : CCorpse::CreateBloodPool
// DESCRIPTION :
// RETURN TYPE : void
// PARAMS : none
// ----------------------------------------------------------------------- //
void CCorpse::CreateBloodPool()
{
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
IntersectQuery iq;
IntersectInfo ii;
g_pServerDE->GetObjectPos(m_hObject, &iq.m_From);
VEC_COPY(iq.m_To, iq.m_From);
iq.m_To.y -= 40.0f;
iq.m_Flags = IGNORE_NONSOLID;
iq.m_FilterFn = NULL;
iq.m_pUserData = NULL;
if (g_pServerDE->IntersectSegment(&iq, &ii))
{
// Only care if we hit the world
if (ii.m_hObject == g_pServerDE->GetWorldObject())
{
HCLASS hClass = g_pServerDE->GetClass("CClientSplatFX");
ii.m_Point.y += 0.1f;
CClientSplatFX *pSplat = DNULL;
if (hClass)
{
VEC_COPY(ocStruct.m_Pos, ii.m_Point);
pSplat = (CClientSplatFX *)g_pServerDE->CreateObject(hClass, &ocStruct);
}
if (pSplat)
{
pSplat->Setup( &ii.m_Point, &ii.m_Plane.m_Normal, 0.10f, 0.02f);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -