705 lines
19 KiB
C++
705 lines
19 KiB
C++
#include "stdafx.h"
|
|
#include "Entity.h"
|
|
#include "EntitySystem.h"
|
|
#include <stream.h>
|
|
#include <IScriptSystem.h>
|
|
#include <ITimer.h>
|
|
#include <ILog.h>
|
|
#include "StreamData.h" // CStreamData_WorldPos
|
|
|
|
#ifdef _DEBUG
|
|
static char THIS_FILE[] = __FILE__;
|
|
#define DEBUG_CLIENTBLOCK new( _NORMAL_BLOCK, THIS_FILE, __LINE__)
|
|
#define new DEBUG_CLIENTBLOCK
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
//PHYSIC or POS if change the pos
|
|
//ANGLES if change
|
|
//CONTAINER stuff
|
|
//
|
|
//
|
|
bool CEntity::Write(CStream& stm,EntityCloneState *cs)
|
|
{
|
|
static CFrameProfiler profiler_EntityNetworkTraffic(GetISystem(),"Entity",PROFILE_NETWORK_TRAFFIC );
|
|
static CFrameProfiler profiler_ContainerNetworkTraffic(GetISystem(),"Container",PROFILE_NETWORK_TRAFFIC );
|
|
static CFrameProfiler profiler_PhysicsNetworkTraffic(GetISystem(),"Physics",PROFILE_NETWORK_TRAFFIC );
|
|
|
|
int nSavedBytes = 0;
|
|
int nStartBytes = stm.GetSize();
|
|
CCustomProfilerSection netTrafficEntity(&profiler_EntityNetworkTraffic,&nSavedBytes);
|
|
static CStream stmPhys;
|
|
|
|
//////////////////////////////////////
|
|
//PHYSIC OR POS
|
|
//////////////////////////////////////
|
|
bool bNeedAngles=true;
|
|
bool bAngles=false;
|
|
bool bSyncYAngle=true;
|
|
|
|
WRITE_COOKIE_NO(stm,0x55);
|
|
|
|
if (m_bIsBound)
|
|
{
|
|
stm.Write(true); // bound
|
|
|
|
stm.Write(m_idBoundTo);
|
|
stm.Write(m_cBind);
|
|
|
|
//[kirill] need to sync angles of bound entities - they can rotate around parents
|
|
Vec3d v3Angles=GetAngles( 1 );
|
|
bAngles=true;
|
|
if(cs)
|
|
{
|
|
bSyncYAngle=cs->m_bSyncYAngle;
|
|
bAngles=cs->m_bSyncAngles;
|
|
if(bAngles)
|
|
{
|
|
// if(!IsEquivalent(cs->m_v3Angles,v3Angles))
|
|
cs->m_v3Angles=v3Angles;
|
|
// else
|
|
// bAngles=false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bAngles=true;
|
|
}
|
|
////////////////////////////////////
|
|
if(bAngles)
|
|
{
|
|
_VERIFY(stm.Write(true));
|
|
// x
|
|
stm.Write((unsigned short)((v3Angles.x*0xFFFF)*(1.f/360.f)));
|
|
// y
|
|
stm.Write(bSyncYAngle);
|
|
if(bSyncYAngle)
|
|
stm.Write((unsigned short)((v3Angles.y*0xFFFF)*(1.f/360.f))); // this component can be skipped for players
|
|
// z
|
|
stm.Write((unsigned short)((v3Angles.z*0xFFFF)*(1.f/360.f)));
|
|
}
|
|
else
|
|
{
|
|
//_VERIFY(stm.Write(false));
|
|
if (!stm.Write(false))
|
|
{
|
|
CryError("ENTITY %s (Type=%d)",GetName()?GetName():"UNNAMEDENTITY",(int)GetClassId());
|
|
}
|
|
}
|
|
}
|
|
else // not bound
|
|
{
|
|
stm.Write(false); // not bound
|
|
|
|
bool bSyncPosition=true;
|
|
|
|
if(cs)
|
|
bSyncPosition=cs->m_bSyncPosition;
|
|
|
|
bool bPhysics = HavePhysics()
|
|
&& m_physicEnabled
|
|
&& GetPhysics()->GetType()!=PE_STATIC
|
|
// [kirill] to enable DeadBodys saving - bug 429
|
|
// && GetPhysics()->GetType()!=PE_ARTICULATED
|
|
&& !IsBound();
|
|
|
|
if (bPhysics && GetPhysics()->GetType()==PE_LIVING)
|
|
{
|
|
pe_player_dynamics pd;
|
|
GetPhysics()->GetParams(&pd);
|
|
if (!pd.bActive)
|
|
{
|
|
bPhysics = false;
|
|
bSyncPosition = false;
|
|
}
|
|
}
|
|
|
|
_VERIFY(stm.Write(bPhysics));
|
|
if (bPhysics)
|
|
{
|
|
CDefaultStreamAllocator sa;
|
|
CStream stmPhys(1024, &sa);
|
|
int nSavedPhysicsBytes = 0;
|
|
int nStartPhysicsBytes = stm.GetSize();
|
|
CCustomProfilerSection netTrafficPhysics(&profiler_PhysicsNetworkTraffic,&nSavedPhysicsBytes);
|
|
|
|
float fStepBack=0.0f;
|
|
//all physical entities except the LIVING ENTITY(players) store
|
|
//the angles into the physical snapshot
|
|
if(GetPhysics()->GetType()!=PE_LIVING)
|
|
{
|
|
bNeedAngles=false;
|
|
}
|
|
|
|
if(cs && cs->m_bLocalplayer)
|
|
{
|
|
stm.Write(true);
|
|
fStepBack=cs->m_fWriteStepBack;
|
|
}
|
|
else
|
|
stm.Write(false);
|
|
|
|
stmPhys.Reset();
|
|
int nSize;
|
|
if (GetPhysics()->GetStateSnapshot(stmPhys,fStepBack,!cs || cs->m_bOffSync ? 0:ssf_checksum_only))
|
|
{
|
|
nSize = stmPhys.GetSize();
|
|
stm.WritePkd(nSize);
|
|
stm.Write(stmPhys);
|
|
}
|
|
else
|
|
stm.WritePkd(0);
|
|
|
|
//int a = stm.GetSize();
|
|
//TRACE("PHYSICS WRITE SIZE=%d %s", stm.GetSize()-a, GetName());
|
|
#ifdef DEBUG_BONES_SYNC
|
|
if (m_pCryCharInstance[0] && m_pCryCharInstance[0]->GetCharacterPhysics())
|
|
m_pCryCharInstance[0]->GetCharacterPhysics()->GetStateSnapshot(stm,0,0);
|
|
#endif
|
|
|
|
nSavedPhysicsBytes = stm.GetSize() - nStartPhysicsBytes;
|
|
}
|
|
else
|
|
{
|
|
stm.Write(bSyncPosition);
|
|
if (bSyncPosition)
|
|
{
|
|
Vec3d vPos = GetPos( false );
|
|
_VERIFY(stm.WritePkd(CStreamData_WorldPos(vPos)));
|
|
}
|
|
}
|
|
|
|
// if the entity has no physics, character might still have physics that needs to be saved (read: ropes)
|
|
if (!GetPhysics())
|
|
{
|
|
IPhysicalEntity *pCharEnt;
|
|
for (int iSlot=0; iSlot<m_nMaxCharNum; iSlot++) if (m_pCryCharInstance[iSlot])
|
|
for(int iAuxPhys=0; pCharEnt=m_pCryCharInstance[iSlot]->GetCharacterPhysics(iAuxPhys); iAuxPhys++)
|
|
pCharEnt->GetStateSnapshot(stm);
|
|
}
|
|
//////////////////////////////////////
|
|
//ANGLES
|
|
//////////////////////////////////////
|
|
WRITE_COOKIE_NO(stm,0x21);
|
|
Vec3d v3Angles=GetAngles( 1 );
|
|
|
|
if(bNeedAngles)
|
|
{
|
|
bAngles=true;
|
|
if(cs)
|
|
{
|
|
bSyncYAngle=cs->m_bSyncYAngle;
|
|
bAngles=cs->m_bSyncAngles;
|
|
|
|
if(bAngles)
|
|
{
|
|
// if(!IsEquivalent(cs->m_v3Angles,v3Angles))
|
|
cs->m_v3Angles=v3Angles;
|
|
// else
|
|
// bAngles=false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bAngles=true;
|
|
}
|
|
}
|
|
////////////////////////////////////
|
|
if(bAngles)
|
|
{
|
|
_VERIFY(stm.Write(true)); // angles on
|
|
|
|
// x
|
|
stm.Write((unsigned short)((v3Angles.x*0xFFFF)*(1.f/360.f)));
|
|
// y
|
|
stm.Write(bSyncYAngle);
|
|
if(bSyncYAngle)
|
|
stm.Write((unsigned short)((v3Angles.y*0xFFFF)*(1.f/360.f))); // this component can be skipped for players
|
|
// z
|
|
stm.Write((unsigned short)((v3Angles.z*0xFFFF)*(1.f/360.f)));
|
|
}
|
|
else
|
|
{
|
|
_VERIFY(stm.Write(false)); // angles off
|
|
}
|
|
}
|
|
WRITE_COOKIE_NO(stm,0x90);
|
|
|
|
//////////////////////////////////////
|
|
//CONTAINER
|
|
//////////////////////////////////////
|
|
bool bContainer=false;
|
|
if (m_pContainer && m_pContainer->IsSaveable())
|
|
bContainer=true;
|
|
|
|
_VERIFY(stm.Write(bContainer));
|
|
|
|
if (bContainer)
|
|
{
|
|
int nSavedContainerBytes = 0;
|
|
int nStartContainerBytes = stm.GetSize();
|
|
CCustomProfilerSection netTrafficContainer(&profiler_ContainerNetworkTraffic,&nSavedContainerBytes);
|
|
_VERIFY(m_pContainer->Write(stm,cs));
|
|
nSavedContainerBytes = stm.GetSize() - nStartContainerBytes;
|
|
}
|
|
WRITE_COOKIE_NO(stm,0x91);
|
|
|
|
nSavedBytes = stm.GetSize() - nStartBytes;
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
bool CEntity::Read(CStream& stm,bool bNoUpdate)
|
|
{
|
|
bool bPhysics, bContainer,bBound,bSyncPosition;
|
|
// pe_type pt;
|
|
IPhysicalEntity *pPE=NULL;
|
|
IEntity *pEntBound;
|
|
//////////////////////////////////////
|
|
//PHYSIC OR POS
|
|
//////////////////////////////////////
|
|
VERIFY_ENTITY_COOKIE_NO(stm,0x55)
|
|
|
|
stm.Read(bBound);
|
|
if (bBound)
|
|
{
|
|
EntityId idBoundTo;
|
|
unsigned char cBind;
|
|
|
|
stm.Read(idBoundTo);
|
|
stm.Read(cBind);
|
|
|
|
if (!bNoUpdate)
|
|
{
|
|
if (m_bIsBound && m_idBoundTo!=idBoundTo)
|
|
{
|
|
pEntBound = m_pEntitySystem->GetEntity(m_idBoundTo);
|
|
if (pEntBound)
|
|
pEntBound->Unbind(GetId(),m_cBind);
|
|
}
|
|
if (!m_bIsBound)
|
|
{
|
|
/*
|
|
pEntBound = m_pEntitySystem->GetEntity(idBoundTo);
|
|
if (pEntBound)
|
|
{
|
|
Vec3 pos = GetPos();
|
|
// need to set position before OnBind is called (it can set some other position)
|
|
pEntBound->Bind(GetId(),cBind, false, true);
|
|
//[kirill] this is not needed - when we load bound people, relative positions will be set in OnBind
|
|
// SetPos( pos, false );
|
|
}
|
|
else
|
|
//[kirill] if parent not spown yet - do bind on PostLoad
|
|
*/
|
|
//[kirill] let's do all the bindings on PostLoad
|
|
{
|
|
m_idBoundTo = idBoundTo;
|
|
m_cBind = cBind;
|
|
}
|
|
}
|
|
}
|
|
//[kirill] read angles for bound entity
|
|
//////////////////////////////////////
|
|
//ANGLES
|
|
//////////////////////////////////////
|
|
bool bAngles;
|
|
stm.Read(bAngles);
|
|
if(bAngles)
|
|
{
|
|
Vec3d vec;
|
|
//_VERIFY(stm.Read(vec));
|
|
bool bSyncYAngle;
|
|
unsigned short x;
|
|
unsigned short y=0;
|
|
unsigned short z;
|
|
stm.Read(x);
|
|
stm.Read(bSyncYAngle);
|
|
if(bSyncYAngle)
|
|
{
|
|
stm.Read(y);
|
|
}
|
|
stm.Read(z);
|
|
vec.x=((float)x*360)*(1.f/0xFFFF);
|
|
vec.y=((float)y*360)*(1.f/0xFFFF); // this component can be skipped for players
|
|
vec.z=((float)z*360)*(1.f/0xFFFF);
|
|
// My player entity should not accept angles from network.
|
|
if (!bNoUpdate)
|
|
SetAngles(vec, false,(pPE?(pPE->GetType()==PE_LIVING?false:true):false) );
|
|
}
|
|
VERIFY_ENTITY_COOKIE_NO(stm,0x90)
|
|
}
|
|
else
|
|
{
|
|
if (m_bIsBound && !bNoUpdate)
|
|
{
|
|
pEntBound = m_pEntitySystem->GetEntity(m_idBoundTo);
|
|
if (pEntBound)
|
|
pEntBound->Unbind(GetId(),m_cBind);
|
|
}
|
|
|
|
stm.Read(bPhysics);
|
|
if (bPhysics)
|
|
{
|
|
// [anton] removed setting m_physicsEnabled, since static entities don't save physics, but they
|
|
// still have physics enabled; plus, just setting m_physicsEnabled to true or false will not actually enable/disable physics
|
|
//m_physicEnabled = true;
|
|
int nRet=0,nSize;
|
|
long nPos;
|
|
///int a = stm.GetSize();
|
|
pPE=GetPhysics();
|
|
/*if(!pPE)
|
|
{
|
|
m_pISystem->GetILog()->LogError("ENTITY %s (Type=%d) was saved with physics state, but it doesnt have one",
|
|
GetName() ? GetName():"UNNAMEDENTITY", (int)GetClassId());
|
|
if (!m_pISystem->GetIGame()->IsMultiplayer())
|
|
{
|
|
CryError("Error: ENTITY %s (Type=%d) was saved with physics state, but it doesnt have one",GetName()?GetName():"UNNAMEDENTITY",(int)GetClassId());
|
|
}
|
|
return false;
|
|
}*/
|
|
bool bHostEntity;
|
|
stm.Read(bHostEntity);
|
|
|
|
stm.ReadPkd(nSize);
|
|
nPos = stm.GetReadPos()+nSize;
|
|
if (nSize && pPE)
|
|
nRet = pPE->SetStateFromSnapshot(stm,(bHostEntity ? ssf_compensate_time_diff:0) | (bNoUpdate ? ssf_no_update:0));
|
|
stm.Seek(nPos);
|
|
|
|
if (bHostEntity && !bNoUpdate)
|
|
{
|
|
pe_params_flags pf;
|
|
pf.flagsAND = ~pef_update;
|
|
pPE->SetParams(&pf);
|
|
}
|
|
|
|
if (!nRet)
|
|
{
|
|
m_pISystem->GetILog()->LogWarning("ENTITY %s (Type=%d) has incorrect physical entity", GetName() ? GetName():"UNNAMEDENTITY", (int)GetClassId());
|
|
/*if (!m_pISystem->GetIGame()->IsMultiplayer())
|
|
{
|
|
CryError("ENTITY %s (Type=%d) has incorrect physical entity", GetName() ? GetName():"UNNAMEDENTITY", GetType());
|
|
}
|
|
return false;*/
|
|
}
|
|
|
|
#ifdef DEBUG_BONES_SYNC
|
|
if (m_pCryCharInstance[0] && m_pCryCharInstance[0]->GetCharacterPhysics())
|
|
{
|
|
pe_params_articulated_body pab;
|
|
pab.pHost = 0;
|
|
m_pCryCharInstance[0]->GetCharacterPhysics()->SetParams(&pab);
|
|
m_pCryCharInstance[0]->GetCharacterPhysics()->SetStateFromSnapshot(stm,bNoUpdate ? ssf_no_update:0);
|
|
}
|
|
#endif
|
|
|
|
//TRACE("PHYSICS READ SIZE=%d %s", stm.GetSize()-a, GetName());
|
|
}
|
|
else
|
|
{
|
|
//m_physicEnabled = false;
|
|
stm.Read(bSyncPosition);
|
|
if (bSyncPosition)
|
|
{
|
|
Vec3d vPos;
|
|
// _VERIFY(stm.Read(vPos));
|
|
#if defined(LINUX)
|
|
_VERIFY(stm.ReadPkd(*(IStreamData*)(&CStreamData_WorldPos(vPos))));
|
|
#else
|
|
_VERIFY(stm.ReadPkd(CStreamData_WorldPos(vPos)));
|
|
#endif
|
|
if (!bNoUpdate)
|
|
SetPos(vPos, false);
|
|
}
|
|
}
|
|
|
|
// if the entity has no physics, character might still have physics that needs to be saved (read: ropes)
|
|
if (!GetPhysics())
|
|
{
|
|
IPhysicalEntity *pCharEnt;
|
|
for (int iSlot=0; iSlot<m_nMaxCharNum; iSlot++) if (m_pCryCharInstance[iSlot])
|
|
for(int iAuxPhys=0; pCharEnt=m_pCryCharInstance[iSlot]->GetCharacterPhysics(iAuxPhys); iAuxPhys++)
|
|
pCharEnt->SetStateFromSnapshot(stm,bNoUpdate ? ssf_no_update:0);
|
|
}
|
|
//////////////////////////////////////
|
|
//ANGLES
|
|
//////////////////////////////////////
|
|
VERIFY_ENTITY_COOKIE_NO(stm,0x21)
|
|
bool bAngles;
|
|
stm.Read(bAngles);
|
|
if(bAngles)
|
|
{
|
|
Vec3d vec;
|
|
//_VERIFY(stm.Read(vec));
|
|
bool bSyncYAngle;
|
|
unsigned short x;
|
|
unsigned short y=0;
|
|
unsigned short z;
|
|
stm.Read(x);
|
|
stm.Read(bSyncYAngle);
|
|
if(bSyncYAngle)
|
|
{
|
|
stm.Read(y);
|
|
}
|
|
stm.Read(z);
|
|
vec.x=((float)x*360)*(1.f/0xFFFF);
|
|
vec.y=((float)y*360)*(1.f/0xFFFF); // this component can be skipped for players
|
|
vec.z=((float)z*360)*(1.f/0xFFFF);
|
|
// My player entity should not accept angles from network.
|
|
if (!bNoUpdate)
|
|
SetAngles(vec, false,(pPE?(pPE->GetType()==PE_LIVING?false:true):false) );
|
|
VERIFY_ENTITY_COOKIE_NO(stm,0x90)
|
|
}
|
|
else
|
|
{
|
|
VERIFY_ENTITY_COOKIE_NO(stm,0x90)
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////
|
|
//CONTAINER
|
|
//////////////////////////////////////
|
|
_VERIFY(stm.Read(bContainer));
|
|
if (bContainer)
|
|
{
|
|
if (!m_pContainer)
|
|
{
|
|
// since there is no check at all for errors during saving/loading,
|
|
// at least print some information if it crashes
|
|
m_pISystem->GetILog()->LogError("NO CONTAINER FOR ENTITY %s (Type=%d)",GetName()?GetName():"UNNAMEDENTITY",(int)GetClassId());
|
|
if (!m_pISystem->GetIGame()->GetModuleState(EGameMultiplayer))
|
|
{
|
|
CryError("ERROR, NO CONTAINER FOR ENTITY %s (Type=%d)",GetName()?GetName():"UNNAMEDENTITY",(int)GetClassId());
|
|
}
|
|
return false;
|
|
}
|
|
_VERIFY(m_pContainer);
|
|
_VERIFY(m_pContainer->Read(stm));
|
|
}
|
|
|
|
VERIFY_ENTITY_COOKIE_NO(stm,0x91)
|
|
|
|
for (int iSlot=0; iSlot<m_nMaxCharNum; iSlot++) if (m_pCryCharInstance[iSlot])
|
|
m_pCryCharInstance[iSlot]->ForceReskin();
|
|
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
bool CEntity::Save(CStream& stream , IScriptObject *pStream)
|
|
{
|
|
if (!Write(stream))
|
|
return false;
|
|
|
|
/*[marco] must be done before, to be consistent
|
|
with loadlevel!
|
|
|
|
Vec3d vPos;
|
|
Vec3d vAng;
|
|
if( IsBound() ) // save relative position if bound
|
|
{
|
|
vPos = GetPos(false);
|
|
vAng = GetAngles(1);
|
|
}
|
|
else
|
|
{
|
|
vPos = GetPos();
|
|
vAng = GetAngles();
|
|
}
|
|
_VERIFY(stream.Write(vPos));
|
|
_VERIFY(stream.Write(vAng));
|
|
*/
|
|
|
|
|
|
//<<add here>> for other C++ stuff to save(see what is already in Write)
|
|
|
|
//Timur[2/1/2002] Both OnSave and OnLoad must be implemented.
|
|
if (pStream && m_pSaveFunc && m_pLoadFunc)
|
|
{
|
|
m_pScriptSystem->BeginCall( m_pSaveFunc );
|
|
m_pScriptSystem->PushFuncParam(m_pScriptObject);
|
|
m_pScriptSystem->PushFuncParam(pStream);
|
|
m_pScriptSystem->EndCall();
|
|
}
|
|
|
|
// [marco] save/load state after loading/saving custom entity props from
|
|
// onload and onsave
|
|
int nState=GetStateIdx();
|
|
_VERIFY(stream.Write(nState));
|
|
|
|
return (true);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
bool CEntity::Load(CStream& stream , IScriptObject *pStream)
|
|
{
|
|
if (!Read(stream))
|
|
return false;
|
|
|
|
/* [marco] must be done before spawnetity, to be consistent
|
|
with loadlevel!
|
|
Vec3d vPos;
|
|
SetPos(Vec3d(0,0,0));
|
|
_VERIFY(stream.Read(vPos));
|
|
SetPos(vPos);
|
|
SetAngles(Vec3d(0,0,0));
|
|
_VERIFY(stream.Read(vPos));
|
|
SetAngles(vPos);
|
|
*/
|
|
|
|
//<<add here>> for other C++ stuff to save(see what is already in Read)
|
|
|
|
|
|
//Timur[2/1/2002] Both OnSave and OnLoad must be implemented.
|
|
if (pStream && m_pSaveFunc && m_pLoadFunc)
|
|
{
|
|
m_pScriptSystem->BeginCall( m_pLoadFunc );
|
|
m_pScriptSystem->PushFuncParam(m_pScriptObject);
|
|
m_pScriptSystem->PushFuncParam(pStream);
|
|
m_pScriptSystem->EndCall();
|
|
}
|
|
|
|
// [marco] save/load state after loading/saving custom entity props from
|
|
// onload and onsave
|
|
int nState;
|
|
_VERIFY(stream.Read(nState));
|
|
GotoState(nState);
|
|
m_awakeCounter = 4; // give entity a chance to fetch the updated physics state
|
|
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
bool CEntity::LoadPATCH1(CStream& stream , IScriptObject *pStream)
|
|
{
|
|
if (!Read(stream))
|
|
return false;
|
|
|
|
/* [marco] must be done before spawnetity, to be consistent
|
|
with loadlevel!
|
|
Vec3d vPos;
|
|
SetPos(Vec3d(0,0,0));
|
|
_VERIFY(stream.Read(vPos));
|
|
SetPos(vPos);
|
|
SetAngles(Vec3d(0,0,0));
|
|
_VERIFY(stream.Read(vPos));
|
|
SetAngles(vPos);
|
|
*/
|
|
|
|
//<<add here>> for other C++ stuff to save(see what is already in Read)
|
|
|
|
|
|
//Timur[2/1/2002] Both OnSave and OnLoad must be implemented.
|
|
if (pStream && m_pSaveFunc && m_pLoadFunc)
|
|
{
|
|
//[kirill] we need to support prev version saves
|
|
//[kirill] we need to support prev version saves
|
|
if(m_pLoadPATCH1Func)
|
|
m_pScriptSystem->BeginCall( m_pLoadPATCH1Func );
|
|
else if(m_pLoadRELEASEFunc)
|
|
m_pScriptSystem->BeginCall( m_pLoadRELEASEFunc );
|
|
else
|
|
m_pScriptSystem->BeginCall( m_pLoadFunc );
|
|
m_pScriptSystem->PushFuncParam(m_pScriptObject);
|
|
m_pScriptSystem->PushFuncParam(pStream);
|
|
m_pScriptSystem->EndCall();
|
|
}
|
|
|
|
// [marco] save/load state after loading/saving custom entity props from
|
|
// onload and onsave
|
|
int nState;
|
|
_VERIFY(stream.Read(nState));
|
|
GotoState(nState);
|
|
m_awakeCounter = 4; // give entity a chance to fetch the updated physics state
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
bool CEntity::LoadRELEASE(CStream& stream , IScriptObject *pStream)
|
|
{
|
|
if (!Read(stream))
|
|
return false;
|
|
|
|
/* [marco] must be done before spawnetity, to be consistent
|
|
with loadlevel!
|
|
Vec3d vPos;
|
|
SetPos(Vec3d(0,0,0));
|
|
_VERIFY(stream.Read(vPos));
|
|
SetPos(vPos);
|
|
SetAngles(Vec3d(0,0,0));
|
|
_VERIFY(stream.Read(vPos));
|
|
SetAngles(vPos);
|
|
*/
|
|
|
|
//<<add here>> for other C++ stuff to save(see what is already in Read)
|
|
|
|
|
|
//Timur[2/1/2002] Both OnSave and OnLoad must be implemented.
|
|
if (pStream && m_pSaveFunc && m_pLoadFunc)
|
|
{
|
|
//[kirill] we need to support prev version saves
|
|
if(m_pLoadRELEASEFunc)
|
|
m_pScriptSystem->BeginCall( m_pLoadRELEASEFunc );
|
|
else
|
|
m_pScriptSystem->BeginCall( m_pLoadFunc );
|
|
m_pScriptSystem->PushFuncParam(m_pScriptObject);
|
|
m_pScriptSystem->PushFuncParam(pStream);
|
|
m_pScriptSystem->EndCall();
|
|
}
|
|
|
|
// [marco] save/load state after loading/saving custom entity props from
|
|
// onload and onsave
|
|
int nState;
|
|
_VERIFY(stream.Read(nState));
|
|
GotoState(nState);
|
|
m_awakeCounter = 4; // give entity a chance to fetch the updated physics state
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
bool CEntity::PostLoad()
|
|
{
|
|
//[kirill] bind it all now
|
|
if (!m_bIsBound && m_idBoundTo!=0)
|
|
{
|
|
IEntity *pEntBound;
|
|
pEntBound = m_pEntitySystem->GetEntity(m_idBoundTo);
|
|
if (pEntBound)
|
|
{
|
|
Vec3 pos = GetPos();
|
|
pEntBound->Bind( GetId(), m_cBind, false, true);
|
|
// SetPos( pos, false );
|
|
}
|
|
}
|
|
if (m_physic)
|
|
m_physic->PostSetStateFromSnapshot();
|
|
|
|
return true;
|
|
}
|