source-engine/game/shared/portal2/paint_saverestore.cpp
tupoy-ya e4f6f07185
chore(Paint): Added paint files that don't work.
refatcor(env_portal_laser): More source accurate lasers, doesn't work now.
2023-09-23 16:15:28 +05:00

214 lines
4.9 KiB
C++

//========= Copyright © Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//==========================================================================//
#include "cbase.h"
#include "isaverestore.h"
#include "paint_stream_manager.h"
//#define SAVE_PAINT_BRIDGE
#ifdef GAME_DLL
#include "projectedwallentity.h"
#include "paint_database.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class CPaintSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
{
virtual const char *GetBlockName() { return "PaintDatabase"; };
virtual void PreSave( CSaveRestoreData * ) {}
virtual void Save( ISave *pSave )
{
if ( !engine->HasPaintmap() )
{
return;
}
#ifdef GAME_DLL
// save paintmap data
PaintDatabase.SavePaintmapData( pSave );
#ifdef SAVE_PAINT_BRIDGE
// save painted projected walls
const ProjectedWallVector_t* pProjectedWalls = PaintDatabase.GetPaintedProjectedWalls();
if ( pProjectedWalls )
{
int count = pProjectedWalls->Count();
pSave->WriteInt( &count );
for ( int i=0; i<count; ++i )
{
CProjectedWallEntity* pWall = pProjectedWalls->Element( i );
if ( pWall )
{
pSave->StartBlock();
{
// save the source wall or source portal of the wall to make each wall unique
bool bHasSourcePortal = !!pWall->GetSourcePortal();
pSave->WriteBool( &bHasSourcePortal );
if ( bHasSourcePortal )
{
EHANDLE hPortal = pWall->GetSourcePortal();
pSave->WriteEHandle( &hPortal );
}
else
{
EHANDLE hProjectedWall = pWall;
pSave->WriteEHandle( &hProjectedWall );
}
int nSegments = pWall->GetNumSegments();
int nPaintedSegments = 0;
for ( int s=0; s<nSegments; ++s )
{
PaintPowerType type = pWall->GetPaintPowerAtSegment( s );
if ( type != NO_POWER )
{
nPaintedSegments++;
}
}
pSave->WriteInt( &nPaintedSegments );
float flSegmentLength = pWall->GetSegmentLength();
Vector vDirection = pWall->GetEndPoint() - pWall->GetStartPoint();
vDirection.NormalizeInPlace();
for ( int s=0; s<nSegments; ++s )
{
int type = (int)pWall->GetPaintPowerAtSegment( s );
if ( type != NO_POWER )
{
Vector vSegmentCenter = pWall->GetStartPoint() + ( ( 0.5f + s ) * flSegmentLength ) * vDirection;
pSave->WriteInt( &type );
pSave->WriteVector( vSegmentCenter );
}
}
}
pSave->EndBlock();
}
}
} // pProjectedWalls
#endif
#endif
}
virtual void WriteSaveHeaders( ISave * ) {}
virtual void PostSave() {}
virtual void PreRestore()
{
if ( !engine->HasPaintmap() )
{
return;
}
#ifdef GAME_DLL
PaintDatabase.RemoveAllPaint();
#endif
}
virtual void ReadRestoreHeaders( IRestore * ) {}
virtual void Restore( IRestore *pRestore, bool fCreatePlayers )
{
if ( !engine->HasPaintmap() )
{
return;
}
#ifdef GAME_DLL
// restore paintmap data
PaintDatabase.RestorePaintmapData( pRestore );
#ifdef SAVE_PAINT_BRIDGE
// find all projected walls in the world
ProjectedWallVector_t projectedWalls;
CBaseEntity* pEnt = NULL;
while ( ( pEnt = gEntList.FindEntityByClassname( pEnt, "projected_wall_entity" ) ) != NULL )
{
projectedWalls.AddToTail( dynamic_cast< CProjectedWallEntity* >( pEnt ) );
}
int nWalls = projectedWalls.Count();
// restore painted projected wall
int paintedWallCount = pRestore->ReadInt();
for ( int i=0; i<paintedWallCount; ++i )
{
pRestore->StartBlock();
{
bool bHasSourcePortal;
pRestore->ReadBool( &bHasSourcePortal );
// find which wall to paint
CProjectedWallEntity* pPaintedWall = NULL;
if ( bHasSourcePortal )
{
EHANDLE hPortal;
pRestore->ReadEHandle( &hPortal );
CPortal_Base2D* pSourcePortal = dynamic_cast< CPortal_Base2D* >( hPortal.Get() );
if ( pSourcePortal )
{
for ( int w=0; w<nWalls; ++w )
{
if ( projectedWalls[ w ]->GetSourcePortal() == pSourcePortal )
{
pPaintedWall = projectedWalls[ w ];
break;
}
}
}
}
else
{
EHANDLE hWall;
pRestore->ReadEHandle( &hWall );
pPaintedWall = dynamic_cast< CProjectedWallEntity* >( hWall.Get() );
}
Assert( pPaintedWall );
int nPaintedSegments = pRestore->ReadInt();
PaintPowerType type = NO_POWER;
trace_t tr;
tr.m_pEnt = pPaintedWall;
for ( int s=0; s<nPaintedSegments; ++s )
{
type = (PaintPowerType)pRestore->ReadInt();
pRestore->ReadVector( &tr.endpos, 1 );
PaintDatabase.AddPaint( tr, type );
}
}
pRestore->EndBlock();
}
projectedWalls.Purge();
#endif
#endif
}
virtual void PostRestore()
{
}
};
CPaintSaveRestoreBlockHandler g_PaintSaveRestoreBlockHandler;
ISaveRestoreBlockHandler *GetPaintSaveRestoreBlockHandler()
{
return &g_PaintSaveRestoreBlockHandler;
}