📄 gib.cpp
字号:
// Gib.cpp: implementation of the CGib class.
//
//////////////////////////////////////////////////////////////////////
#define GIB_REMOVETIME 20.0f
#include <stdio.h>
#include "Gib.h"
#include "ClientSmokeTrail.h"
#include "ObjectUtilities.h"
#include "clientbloodtrail.h"
#include "clientmarksfx.h"
#include "BloodServerShell.h"
#include "ClientWeaponSFX.h"
#include "SfxMsgIDs.h"
#include <mbstring.h>
#include "SoundTypes.h"
//FLESH
char *szFleshGibs[NUM_FLESH_GIBS] =
{
"models\\gibs\\giblarge2.abc",
"models\\gibs\\giblarge2.abc",
"models\\gibs\\giblarge3.abc"
};
char *szFleshSkins[NUM_FLESH_GIBS] =
{
"skins\\gibs\\giblarge2.dtx",
"skins\\gibs\\giblarge2.dtx",
"skins\\gibs\\giblarge3.dtx"
};
//METAL
char *szMetalGibs[NUM_METAL_GIBS] =
{
"models\\gibs\\gibmetal1.abc",
"models\\gibs\\gibmetal2.abc",
};
char *szMetalSkins[NUM_METAL_GIBS] =
{
"skins\\gibs\\gibmetal1.dtx",
"skins\\gibs\\gibmetal2.dtx",
};
//FLESH
char *szStoneGibs[NUM_STONE_GIBS] =
{
"models\\gibs\\giblarge2.abc",
"models\\gibs\\giblarge3.abc"
};
char *szStoneSkins[NUM_STONE_GIBS] =
{
"skins\\gibs\\giblarge2.dtx",
"skins\\gibs\\giblarge3.dtx"
};
//WOOD
char *szWoodGibs[NUM_WOOD_GIBS] =
{
"models\\gibs\\debriswood1.abc",
"models\\gibs\\debriswood2.abc",
"models\\gibs\\debriswood3.abc"
};
char *szWoodSkins[NUM_WOOD_GIBS] =
{
"skins\\gibs\\debriswood1.dtx",
"skins\\gibs\\debriswood2.dtx",
"skins\\gibs\\debriswood3.dtx"
};
//GLASS
char *szGlassGibs[NUM_GLASS_GIBS] =
{
"models\\gibs\\gibglass1.abc",
"models\\gibs\\gibglass2.abc",
};
char *szGlassSkins[NUM_GLASS_GIBS] =
{
"skins\\gibs\\gibglass1.dtx",
"skins\\gibs\\gibglass2.dtx",
};
BEGIN_CLASS(CGib)
ADD_DESTRUCTABLE_AGGREGATE()
ADD_STRINGPROP(InitFilename, "")
ADD_STRINGPROP(InitSkin, "")
ADD_LONGINTPROP(InitFlags, (FLAG_VISIBLE | FLAG_RAYHIT | FLAG_GRAVITY | FLAG_SHADOW))
ADD_STRINGPROP(InitAnim,"")
ADD_REALPROP(HitPoints, 20.0f)
ADD_REALPROP(ObjectMass, 10.0f)
ADD_BOOLPROP(Kickable, DTRUE)
END_CLASS_DEFAULT(CGib, B2BaseClass, NULL, NULL)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGib::CGib() : B2BaseClass(OT_MODEL)
{
CServerDE* pServerDE = GetServerDE();
AddAggregate(&m_damage);
m_szInitAnim[0] = '\0';
m_fMass = 3.0f;
m_fHitPoints = 10.0f;
m_dwGibType = 0;
m_bGibbed = DFALSE;
m_fPitchVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
m_fYawVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
m_fRollVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE) / 3.0f;
m_fPitch = 0.0;
m_fYaw = 0.0;
m_fRoll = 0.0;
m_fLastTime = 0.0;
m_hSmokeTrail = DNULL;
m_hBloodTrail = DNULL;
m_bAddSmokeTrail = DFALSE;
m_bAddBloodTrail = DFALSE;
m_bPlaySplat = DFALSE;
VEC_INIT(m_vLastPos);
m_hCorpseClass = DNULL;
m_dwSurfType = SURFTYPE_FLESH; // Default surface type
m_nBounceCount = 0;
m_bKickable = DTRUE;
m_nAxisAlign = 0;
m_bFirstUpdate = DTRUE;
m_fRemoveTime = 0;
m_fRotateTime = 0;
m_bAddBloodSpurt = DFALSE;
}
CGib::~CGib()
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return;
if (m_hSmokeTrail)
pServerDE->RemoveObject(m_hSmokeTrail);
if (m_hBloodTrail)
pServerDE->RemoveObject(m_hBloodTrail);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CGib::EngineMessageFn()
//
// PURPOSE: Handler for engine messages
//
// --------------------------------------------------------------------------- //
DDWORD CGib::EngineMessageFn(DDWORD messageID, void *pData, float fData)
{
switch(messageID)
{
case MID_PRECREATE:
{
DDWORD dwRet = B2BaseClass::EngineMessageFn(messageID, pData, fData);
if (fData == 1.0f)
ReadProp((ObjectCreateStruct*)pData);
PostPropRead((ObjectCreateStruct*)pData);
return dwRet;
}
case MID_INITIALUPDATE:
{
InitialUpdate((DVector *)pData);
break;
}
case MID_UPDATE:
{
if(m_dwGibType & GIB_SMALL || m_damage.IsDead())
g_pServerDE->RemoveObject( m_hObject );
else
if (!Update())
g_pServerDE->RemoveObject( m_hObject );
break;
}
case MID_TOUCHNOTIFY:
{
HandleTouch((HOBJECT)pData, fData);
break;
}
}
return B2BaseClass::EngineMessageFn(messageID, pData, fData);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CGib::ObjectMessageFn
//
// PURPOSE: Handle object-to-object messages
//
// ----------------------------------------------------------------------- //
DDWORD CGib::ObjectMessageFn( HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead )
{
CServerDE* g_pServerDE = GetServerDE();
if (!g_pServerDE) return 0;
switch(messageID)
{
case MID_DAMAGE:
{
DVector vDir;
g_pServerDE->ReadFromMessageVector(hRead, &vDir);
g_pServerDE->ResetRead(hRead); // reset since I'm not reading all items.
// Let Destructable aggregate do its job first...
DDWORD ret = B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
Damage(vDir);
return ret;
}
default : break;
}
return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}
// --------------------------------------------------------------------------- //
//
// ROUTINE: CGib::ReadProp()
//
// PURPOSE: Reads properties
//
// --------------------------------------------------------------------------- //
DBOOL CGib::ReadProp(ObjectCreateStruct *pStruct)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !pStruct) return DFALSE;
char buf[MAX_CS_FILENAME_LEN];
GenericProp genProp;
if (pServerDE->GetPropGeneric("Kickable", &genProp) == DE_OK)
{
m_bKickable = genProp.m_Bool;
}
pServerDE->GetPropReal("HitPoints", &m_fHitPoints);
pServerDE->GetPropReal("ObjectMass", &m_fMass);
// Read in the destroyed object props.
buf[0] = '\0';
pServerDE->GetPropString("InitFilename", buf, MAX_CS_FILENAME_LEN);
if (buf[0])
{
_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)buf);
m_dwSurfType = SURFTYPE_PLASTIC;
}
buf[0] = '\0';
pServerDE->GetPropString("InitSkin", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) _mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)buf);
long nLongVal;
if (pServerDE->GetPropLongInt("InitFlags", &nLongVal) == DE_OK)
pStruct->m_Flags = (DDWORD)nLongVal;
buf[0] = '\0';
pServerDE->GetPropString("InitAnim", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) _mbscpy((unsigned char*)m_szInitAnim, (const unsigned char*)buf);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: PostPropRead()
//
// PURPOSE: Update properties
//
// ----------------------------------------------------------------------- //
void CGib::PostPropRead(ObjectCreateStruct *pStruct)
{
if (!pStruct) return;
pStruct->m_Flags = FLAG_VISIBLE | FLAG_RAYHIT | FLAG_GRAVITY | FLAG_TOUCH_NOTIFY;
m_dwGibType = pStruct->m_UserData;
if(pStruct->m_UserData & GIB_CORPSE)
{
m_dwSurfType = SURFTYPE_FLESH;
m_fMass = 10.0f;
m_fHitPoints = 50.0f;
}
else if(pStruct->m_UserData & GIB_HEAD || pStruct->m_UserData & GIB_ARM || pStruct->m_UserData & GIB_LEG)
{
m_fMass = 3.0f;
m_fHitPoints = 10.0f;
}
else
{
if(pStruct->m_UserData & GIB_METAL)
{
m_dwSurfType = SURFTYPE_METAL;
int nModel = (int)g_pServerDE->Random(0,NUM_METAL_GIBS - 1);
if(pStruct->m_Filename[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szMetalGibs[nModel]);
if(pStruct->m_SkinName[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szMetalSkins[nModel]);
}
else if(pStruct->m_UserData & GIB_GLASS)
{
m_dwSurfType = SURFTYPE_GLASS;
int nModel = (int)g_pServerDE->Random(0,NUM_GLASS_GIBS - 1);
if(pStruct->m_Filename[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szGlassGibs[nModel]);
if(pStruct->m_SkinName[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szGlassSkins[nModel]);
}
else if(pStruct->m_UserData & GIB_WOOD)
{
m_dwSurfType = SURFTYPE_WOOD;
int nModel = (int)g_pServerDE->Random(0,NUM_WOOD_GIBS - 1);
if(pStruct->m_Filename[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szWoodGibs[nModel]);
if(pStruct->m_SkinName[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szWoodSkins[nModel]);
}
else if(pStruct->m_UserData & GIB_STONE)
{
m_dwSurfType = SURFTYPE_STONE;
int nModel = (int)g_pServerDE->Random(0,NUM_STONE_GIBS - 1);
if(pStruct->m_Filename[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szStoneGibs[nModel]);
if(pStruct->m_SkinName[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szStoneSkins[nModel]);
}
else if(pStruct->m_UserData & GIB_FLESH)
{
m_dwSurfType = SURFTYPE_FLESH;
int nModel = (int)g_pServerDE->Random(0,NUM_FLESH_GIBS - 1);
if(pStruct->m_Filename[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_Filename, (const unsigned char*)szFleshGibs[nModel]);
if(pStruct->m_SkinName[0] == DNULL)
_mbscpy( (unsigned char*)pStruct->m_SkinName, (const unsigned char*)szFleshSkins[nModel]);
}
m_fMass = 3.0f;
m_fHitPoints = 10.0f;
}
// Is it smoking?
if (pStruct->m_UserData & GIB_SMOKETRAIL)
{
m_bAddSmokeTrail = DTRUE;
}
if(pStruct->m_UserData & (GIB_BLOODTRAIL | GIB_FLESH))
{
m_bAddBloodTrail = DTRUE;
}
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CGib::InitialUpdate()
//
// PURPOSE: Handle initial update
//
// ----------------------------------------------------------------------- //
void CGib::InitialUpdate(DVector *pMovement)
{
CServerDE* pServerDE = GetServerDE();
m_damage.Init( m_hObject );
// Setup damage stats...
m_damage.SetMass( m_fMass );
m_damage.SetHitPoints( m_fHitPoints );
m_damage.SetMaxHitPoints( m_fHitPoints );
m_damage.SetArmorPoints( 0.0f );
m_damage.SetMaxArmorPoints( 0.0f );
m_damage.SetApplyDamagePhysics(DTRUE);
pServerDE->SetForceIgnoreLimit(m_hObject, 0.1f);
if(m_szInitAnim[0]) //SCHLEGZ 3/6/98 12:30:43 PM: allow for setting corpses
{
pServerDE->SetModelAnimation(m_hObject,pServerDE->GetAnimIndex(m_hObject,m_szInitAnim));
}
pServerDE->SetModelLooping(m_hObject, DFALSE);
if (m_bKickable)
{
DVector vDims;
pServerDE->GetModelAnimUserDims(m_hObject, &vDims, pServerDE->GetModelAnimation(m_hObject));
DFLOAT fMax = vDims.x;
if (vDims.y > fMax) fMax = vDims.y;
if (vDims.z > fMax) fMax = vDims.z;
VEC_SET(vDims, fMax, fMax, fMax);
pServerDE->SetObjectDims(m_hObject, &vDims);
}
if (m_bAddSmokeTrail)
{
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
pServerDE->GetObjectPos(m_hObject, &theStruct.m_Pos);
HCLASS hClass = pServerDE->GetClass("CClientSmokeTrail");
CClientSmokeTrail* pTrail = DNULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -