📄 sfxmgr.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : CSFXMgr.cpp
//
// PURPOSE : Special FX Mgr - Implementation
//
// CREATED : 10/24/97
//
// ----------------------------------------------------------------------- //
#include "SFXMgr.h"
#include "SpecialFX.h"
#include "PolyGridFX.h"
#include "SmokeTrailFX.h"
#include "ParticleSystemFX.h"
#include "SFXMsgIds.h"
#include "MarkSFX.h"
#include "CastLineFX.h"
#include "TracerFX.h"
#include "RainFX.h"
#include "SparksFX.h"
//#include "BulletImpactSFX.h"
#include "SmokeTrailSegmentFX.h"
#include "VolumeBrushFX.h"
#include "WeaponFX.h"
#include "bloodtrailfx.h"
#include "bloodtrailsegmentfx.h"
#include "SmokeFX.h"
#include "SmokePuffFX.h"
#include "SmokeImpactFX.h"
#include "SplashFX.h"
#include "RippleFX.h"
#include "SurfaceFragmentFX.h"
#include "ExplosionFX.h"
#include "CameraFX.h"
#include "LightFX.h"
#include "WeaponPowerupFX.h"
#include "ParticleStreamFX.h"
#include "ClientServerShared.h"
#include "bloodsplatfx.h"
#include "ParticleExplosionFX.h"
#include "LightningFX.h"
#include "LightningSegmentFX.h"
#include "LaserBeamFX.h"
#include "WarpGateFX.h"
#include "gibfx.h"
#include "debugline.h"
#include "ObjectFX.h"
#include "ShellCasingFX.h"
#include "PickupObjectFX.h"
#include "FlashlightFX.h"
#include "IKChainFX.h"
#include "BloodclientShell.h"
// ----------------------------------------------------------------------- //
//
// ROUTINE: CSFXMgr::Init()
//
// PURPOSE: Init the CSFXMgr
//
// ----------------------------------------------------------------------- //
DBOOL CSFXMgr::Init(CClientDE *pClientDE)
{
if (!pClientDE) return DFALSE;
m_pClientDE = pClientDE;
DBOOL bRet = DTRUE;
for (int i=0; i < DYN_ARRAY_SIZE; i++)
{
bRet = m_dynSFXLists[i].Create(GetDynArrayMaxNum(i));
if (!bRet) return DFALSE;
}
bRet = m_staticSFXList.Create(STATIC_LIST_SIZE);
bRet = m_cameraSFXList.Create(CAMERA_LIST_SIZE);
bRet = m_termSFXList.Create(STATIC_LIST_SIZE);
return bRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CSFXMgr::HandleSFXMsg()
//
// PURPOSE: Handle a special fx message
//
// ----------------------------------------------------------------------- //
void CSFXMgr::HandleSFXMsg(HLOCALOBJ hObj, HMESSAGEREAD hMessage, DBYTE nId)
{
if (!m_pClientDE) return;
D_WORD wColor;
switch(nId)
{
case SFX_POLYGRID_ID :
{
PGCREATESTRUCT pg;
pg.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(pg.vDims));
wColor = m_pClientDE->ReadFromMessageWord(hMessage);
Color255WordToVector(wColor, &(pg.vColor1));
wColor = m_pClientDE->ReadFromMessageWord(hMessage);
Color255WordToVector(wColor, &(pg.vColor2));
pg.fXScaleMin = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fXScaleMax = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fYScaleMin = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fYScaleMax = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fXScaleDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fYScaleDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fXPan = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fYPan = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.fAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
pg.hstrSurfaceSprite = m_pClientDE->ReadFromMessageHString(hMessage);
pg.dwNumPolies = (DDWORD)m_pClientDE->ReadFromMessageWord(hMessage);
pg.nPlasmaType = m_pClientDE->ReadFromMessageByte(hMessage);
pg.nRingRate[0] = m_pClientDE->ReadFromMessageByte(hMessage);
pg.nRingRate[1] = m_pClientDE->ReadFromMessageByte(hMessage);
pg.nRingRate[2] = m_pClientDE->ReadFromMessageByte(hMessage);
pg.nRingRate[3] = m_pClientDE->ReadFromMessageByte(hMessage);
CreateSFX(nId, &pg);
}
break;
case SFX_SMOKETRAIL_ID :
{
STCREATESTRUCT st;
st.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(st.vVel));
st.bSmall = (DBOOL) m_pClientDE->ReadFromMessageByte(hMessage);
CreateSFX(nId, &st);
}
break;
//SCHLEGZ 5/21/98 1:42:10 PM: new blood trail effect
case SFX_BLOODTRAIL_ID :
{
BTCREATESTRUCT bt;
bt.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(bt.vVel));
m_pClientDE->ReadFromMessageVector(hMessage, &(bt.vColor));
CreateSFX(nId, &bt);
}
break;
case SFX_BLOODSPLAT_ID:
{
BSCREATESTRUCT splat;
splat.hServerObj = hObj;
m_pClientDE->ReadFromMessageCompPosition(hMessage, &splat.m_Pos);
m_pClientDE->ReadFromMessageRotation(hMessage, &(splat.m_Rotation));
splat.m_fScale = m_pClientDE->ReadFromMessageFloat(hMessage);
splat.m_fGrowScale = m_pClientDE->ReadFromMessageFloat(hMessage);
splat.m_hstrSprite = DNULL;
CreateSFX(nId, &splat);
}
break;
case SFX_GIB_ID:
{
GIBCREATESTRUCT gib;
gib.hServerObj = hObj;
m_pClientDE->ReadFromMessageCompPosition(hMessage, &(gib.m_Pos));
m_pClientDE->ReadFromMessageCompVector(hMessage, &(gib.m_Dir));
m_pClientDE->ReadFromMessageCompVector(hMessage, &(gib.m_Dims));
gib.m_dwFlags = (DDWORD)m_pClientDE->ReadFromMessageWord( hMessage );
gib.m_fScale = m_pClientDE->ReadFromMessageFloat(hMessage);
DBYTE nCount = m_pClientDE->ReadFromMessageByte( hMessage );
if (gib.m_dwFlags & TYPEFLAG_CUSTOM) // Read extra stuff if it's custom.
{
gib.m_hstrModel = m_pClientDE->ReadFromMessageHString( hMessage );
gib.m_hstrSkin = m_pClientDE->ReadFromMessageHString( hMessage );
gib.m_hstrSound = m_pClientDE->ReadFromMessageHString( hMessage );
}
// Adjust count based on detail levels
DBYTE nVal = g_pBloodClientShell->GetGlobalDetail();
DDWORD nType = (gib.m_dwFlags & TYPE_MASK) * 10;
if (nVal == DETAIL_LOW)
{
nCount /= 2; // Smallest possible
}
else if (nVal == DETAIL_HIGH && nType == SURFTYPE_FLESH)
{
if (IsRandomChance(20)) // Occasionally make more.
nCount *= 2;
else
nCount *= (DBYTE)1.5; // a little extra..
}
for (int i=0; i < nCount; i++)
CreateSFX(nId, &gib);
}
break;
/*
case SFX_ROCKETFLARE_ID :
{
RFCREATESTRUCT rf;
rf.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(rf.vVel));
rf.bSmall = (DBOOL) m_pClientDE->ReadFromMessageByte(hMessage);
CreateSFX(nId, &rf);
}
break;
*/
case SFX_PARTICLESYSTEM_ID :
{
PSCREATESTRUCT ps;
ps.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(ps.vColor1));
m_pClientDE->ReadFromMessageVector(hMessage, &(ps.vColor2));
ps.dwFlags = (DDWORD) m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fBurstWait = m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fParticlesPerSecond = m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fEmissionRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fMinimumVelocity = m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fMaximumVelocity = m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fVelocityOffset = m_pClientDE->ReadFromMessageFloat(hMessage);
ps.fParticleLifetime = m_pClientDE->ReadFromMessageFloat(hMessage);
CreateSFX(nId, &ps);
}
break;
case SFX_MARK_ID :
{
MARKCREATESTRUCT mark;
mark.hServerObj = hObj;
// m_pClientDE->ReadFromMessageVector(hMessage, &(mark.m_Pos));
m_pClientDE->ReadFromMessageRotation(hMessage, &(mark.m_Rotation));
mark.m_fScale = m_pClientDE->ReadFromMessageFloat(hMessage);
mark.m_hstrSprite = m_pClientDE->ReadFromMessageHString( hMessage );
mark.m_bServerObj = m_pClientDE->ReadFromMessageByte( hMessage );
CreateSFX(nId, &mark);
g_pClientDE->FreeString( mark.m_hstrSprite );
}
break;
case SFX_WEAPON_ID :
{
WFXCREATESTRUCT w;
w.hServerObj = DNULL;
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vSourcePos));
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vDestPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vForward));
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vNormal));
w.nFXFlags = m_pClientDE->ReadFromMessageDWord(hMessage);
w.nExtraData = m_pClientDE->ReadFromMessageDWord(hMessage);
// Check to see if we should read any extras...
if(w.nExtraData & WFX_EXTRA_AMMOTYPE)
w.nAmmoType = m_pClientDE->ReadFromMessageByte(hMessage);
if(w.nExtraData & WFX_EXTRA_SURFACETYPE)
w.nSurfaceType = m_pClientDE->ReadFromMessageByte(hMessage);
if(w.nExtraData & WFX_EXTRA_EXPTYPE)
w.nExplosionType = m_pClientDE->ReadFromMessageByte(hMessage);
if(w.nExtraData & WFX_EXTRA_DAMAGE)
w.fDamage = m_pClientDE->ReadFromMessageFloat(hMessage);
if(w.nExtraData & WFX_EXTRA_DENSITY)
w.fDensity = m_pClientDE->ReadFromMessageFloat(hMessage);
if(w.nExtraData & WFX_EXTRA_COLOR1)
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vColor1));
if(w.nExtraData & WFX_EXTRA_COLOR2)
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vColor2));
if(w.nExtraData & WFX_EXTRA_LIGHTCOLOR1)
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vLightColor1));
if(w.nExtraData & WFX_EXTRA_LIGHTCOLOR2)
m_pClientDE->ReadFromMessageVector(hMessage, &(w.vLightColor2));
CreateSFX(nId, &w);
}
break;
case SFX_TRACER_ID :
{
TRACERCREATESTRUCT tracer;
TRACERCREATESTRUCT tr;
tracer.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(tracer.vVel));
m_pClientDE->ReadFromMessageVector(hMessage, &(tracer.vStartColor));
m_pClientDE->ReadFromMessageVector(hMessage, &(tracer.vEndColor));
m_pClientDE->ReadFromMessageVector(hMessage, &(tracer.vStartPos));
tracer.fStartAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
tracer.fEndAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
// tracer.hServerObj = hObj;
// m_pClientDE->ReadFromMessageVector(hMessage, &(tracer.vToPos));
// tracer.hGun = m_pClientDE->ReadFromMessageObject(hMessage);
CreateSFX(nId, &tracer);
}
break;
case SFX_DEBUGLINE_ID:
{
DEBUGLINECREATESTRUCT db;
db.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(db.vFromPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(db.vToPos));
CreateSFX(nId, &db, DTRUE);
}
break;
case SFX_RAIN_ID :
{
RAINCREATESTRUCT rain;
rain.hServerObj = hObj;
rain.dwFlags = (DDWORD) m_pClientDE->ReadFromMessageFloat(hMessage);
rain.fDensity = m_pClientDE->ReadFromMessageFloat(hMessage);
rain.fLifetime = m_pClientDE->ReadFromMessageFloat(hMessage);
rain.bGravity = (DBOOL) m_pClientDE->ReadFromMessageByte(hMessage);
rain.fParticleScale = m_pClientDE->ReadFromMessageFloat(hMessage);
rain.fSpread = m_pClientDE->ReadFromMessageFloat(hMessage);
m_pClientDE->ReadFromMessageVector(hMessage, &(rain.vDims));
m_pClientDE->ReadFromMessageVector(hMessage, &(rain.vDirection));
m_pClientDE->ReadFromMessageVector(hMessage, &(rain.vColor1));
m_pClientDE->ReadFromMessageVector(hMessage, &(rain.vColor2));
rain.fTimeLimit = m_pClientDE->ReadFromMessageFloat(hMessage);
rain.fPulse = m_pClientDE->ReadFromMessageFloat(hMessage);
CreateSFX(nId, &rain);
}
break;
case SFX_SPARKS_ID :
{
SCREATESTRUCT sp;
sp.hServerObj = hObj;
m_pClientDE->ReadFromMessageRotation(hMessage, &(sp.rRot));
m_pClientDE->ReadFromMessageVector(hMessage, &(sp.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(sp.vDir));
m_pClientDE->ReadFromMessageVector(hMessage, &(sp.vColor1));
m_pClientDE->ReadFromMessageVector(hMessage, &(sp.vColor2));
sp.hstrTexture = m_pClientDE->ReadFromMessageHString(hMessage);
sp.nSparks = m_pClientDE->ReadFromMessageByte(hMessage);
sp.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
sp.fEmissionRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
sp.fRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
sp.fGravity = m_pClientDE->ReadFromMessageFloat(hMessage);
CreateSFX(nId, &sp);
g_pClientDE->FreeString( sp.hstrTexture );
}
break;
case SFX_CASTLINE_ID :
{
CLCREATESTRUCT cl;
cl.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(cl.vStartColor));
m_pClientDE->ReadFromMessageVector(hMessage, &(cl.vEndColor));
cl.fStartAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
cl.fEndAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
cl.hCastTo = m_pClientDE->ReadFromMessageObject(hMessage);
CreateSFX(nId, &cl);
}
break;
case SFX_VOLUMEBRUSH_ID :
{
VBCREATESTRUCT vb;
vb.hServerObj = hObj;
vb.bFogEnable = m_pClientDE->ReadFromMessageByte(hMessage);
vb.fFogFarZ = m_pClientDE->ReadFromMessageFloat(hMessage);
vb.fFogNearZ = m_pClientDE->ReadFromMessageFloat(hMessage);
m_pClientDE->ReadFromMessageVector(hMessage, &vb.vFogColor);
CreateSFX(nId, &vb);
}
break;
case SFX_SPLASH_ID :
{
SPLASHCREATESTRUCT splcs;
RIPPLECREATESTRUCT ripcs;
DBOOL bRipple;
splcs.hServerObj = hObj;
ripcs.hServerObj = hObj;
m_pClientDE->ReadFromMessageVector(hMessage, &(splcs.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(splcs.vDir));
splcs.fRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.fPosRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.fHeight = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.fDensity = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.fSpread = m_pClientDE->ReadFromMessageFloat(hMessage);
m_pClientDE->ReadFromMessageVector(hMessage, &(splcs.vColor1));
m_pClientDE->ReadFromMessageVector(hMessage, &(splcs.vColor2));
/***** RIPPLE INFORMATION *****/
m_pClientDE->ReadFromMessageVector(hMessage, &(ripcs.vMinScale));
bRipple = m_pClientDE->ReadFromMessageByte(hMessage);
/******************************/
splcs.fSprayTime = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.fGravity = m_pClientDE->ReadFromMessageFloat(hMessage);
splcs.hstrTexture = m_pClientDE->ReadFromMessageHString(hMessage);
if(bRipple)
{
VEC_COPY(ripcs.vNormal, splcs.vDir);
VEC_COPY(ripcs.vPos, splcs.vPos);
ripcs.fDuration = 1.0f;
VEC_COPY(ripcs.vMaxScale, ripcs.vMinScale);
ripcs.fInitAlpha = 0.25f;
ripcs.bFade = 0;
CreateSFX(SFX_RIPPLE_ID, &ripcs);
}
CreateSFX(nId, &splcs);
}
break;
case SFX_EXPLOSION_ID :
{
EXPLOSIONMODELCS expCS;
expCS.hServerObj = 0;
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vNormal));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale1));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale2));
expCS.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.bWaveForm = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bFadeType = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bRandomRot = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.szModel = m_pClientDE->ReadFromMessageHString(hMessage);
expCS.szSkin = m_pClientDE->ReadFromMessageHString(hMessage);
CreateSFX(SFX_EXPLOSION_ID, &expCS);
}
break;
case SFX_EXPLOSIONSPRITE_ID :
{
EXPLOSIONSPRITECS expCS;
expCS.hServerObj = 0;
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vNormal));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale1));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale2));
expCS.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.bWaveForm = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bFadeType = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bAlign = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.szSprite = m_pClientDE->ReadFromMessageHString(hMessage);
CreateSFX(SFX_EXPLOSIONSPRITE_ID, &expCS);
}
break;
case SFX_EXPLOSIONRING_ID :
{
EXPLOSIONRINGCS expCS;
expCS.hServerObj = 0;
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vNormal));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vColor));
expCS.fRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fPosRadius = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fVelocity = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fGravity = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.nParticles = m_pClientDE->ReadFromMessageDWord(hMessage);
expCS.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fDelay = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.bFadeType = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bAlign = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.szParticle = m_pClientDE->ReadFromMessageHString(hMessage);
CreateSFX(SFX_EXPLOSIONRING_ID, &expCS);
}
break;
case SFX_EXPLOSIONWAVE_ID :
{
EXPLOSIONWAVECS expCS;
expCS.hServerObj = 0;
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vNormal));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale1));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale2));
expCS.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fAlpha = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fDelay = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.bWaveForm = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bFadeType = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.bAlign = m_pClientDE->ReadFromMessageByte(hMessage);
expCS.szWave = m_pClientDE->ReadFromMessageHString(hMessage);
CreateSFX(SFX_EXPLOSIONWAVE_ID, &expCS);
}
break;
case SFX_EXPLOSIONLIGHT_ID :
{
EXPLOSIONLIGHTCS expCS;
expCS.hServerObj = 0;
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vColor1));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vColor2));
expCS.fDuration = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fDelay = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fRadius1 = m_pClientDE->ReadFromMessageFloat(hMessage);
expCS.fRadius2 = m_pClientDE->ReadFromMessageFloat(hMessage);
CreateSFX(SFX_EXPLOSIONLIGHT_ID, &expCS);
}
break;
case SFX_EXPLOSIONFRAG_ID :
{
EXPLOSIONFRAGCS expCS;
expCS.hServerObj = 0;
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vPos));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vNormal));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vScale));
m_pClientDE->ReadFromMessageVector(hMessage, &(expCS.vRotateMax));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -