109 lines
3.4 KiB
C++
109 lines
3.4 KiB
C++
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Implements the interface class for all paint power users.
|
|
//
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "paint_power_user_interface.h"
|
|
#include "paintable_entity.h"
|
|
|
|
#ifdef GAME_DLL
|
|
#include "world.h"
|
|
#else
|
|
#include "c_world.h"
|
|
#endif
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
ConVar sv_enable_paint_power_user_debug("sv_enable_paint_power_user_debug", "0", FCVAR_REPLICATED | FCVAR_CHEAT,"Enable debug spew for paint power users.");
|
|
extern ConVar sv_debug_draw_contacts;
|
|
|
|
IPaintPowerUser::~IPaintPowerUser()
|
|
{}
|
|
|
|
|
|
void MapSurfaceToPower( PaintPowerInfo_t& info )
|
|
{
|
|
IHandleEntity* pEntityHandle = info.m_HandleToOther.Get();
|
|
CBaseEntity* pEnt = pEntityHandle != NULL ? EntityFromEntityHandle( pEntityHandle ) : NULL;
|
|
|
|
// If the power hasn't been set to anything elsewhere, and the entity is valid
|
|
if ( info.m_PaintPowerType == NO_POWER && pEnt != NULL )
|
|
{
|
|
// Treat portalsimulator_collisionentity as the world
|
|
if( FClassnameIs( pEnt, "portalsimulator_collisionentity" ) )
|
|
{
|
|
#ifdef GAME_DLL
|
|
pEnt = GetWorldEntity();
|
|
#else
|
|
pEnt = GetClientWorldEntity();
|
|
#endif
|
|
}
|
|
|
|
// If this is a world entity
|
|
if( pEnt->IsBSPModel() )
|
|
{
|
|
Vector vStart = info.m_ContactPoint + info.m_SurfaceNormal;
|
|
Vector vEnd = vStart - 10.f * info.m_SurfaceNormal;
|
|
Ray_t ray;
|
|
ray.Init( vStart, vEnd );
|
|
trace_t tr;
|
|
UTIL_TraceRay( ray, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
|
|
|
|
// Trace into the paint map to find the power if the surface is paintable
|
|
if ( UTIL_IsPaintableSurface( tr.surface ) )
|
|
{
|
|
Vector contactPoint = info.m_ContactPoint + 0.1f * info.m_SurfaceNormal;
|
|
info.m_PaintPowerType = UTIL_Paint_TracePower( pEnt, contactPoint, info.m_SurfaceNormal );
|
|
}
|
|
else
|
|
{
|
|
info.m_PaintPowerType = NO_POWER;
|
|
}
|
|
}
|
|
else if( !pEnt->IsPlayer() )
|
|
{
|
|
// The dynamic_cast here shouldn't be any more of a performance concern than the
|
|
// dynamic_cast that would be necessary when this PaintPowerInfo_t was added in the first place.
|
|
const IPaintableEntity* pPaintableEnt = dynamic_cast< const IPaintableEntity* >( pEnt );
|
|
if( pPaintableEnt )
|
|
{
|
|
info.m_PaintPowerType = pPaintableEnt->GetPaintPowerAtPoint( info.m_ContactPoint );
|
|
}
|
|
else
|
|
{
|
|
//Use the render color of the owner if this entity is a bone follower
|
|
if( FClassnameIs( pEnt, "phys_bone_follower" ) )
|
|
{
|
|
CBaseEntity *pBoneOwner = pEnt->GetOwnerEntity();
|
|
|
|
if( pBoneOwner )
|
|
{
|
|
info.m_PaintPowerType = MapColorToPower( pBoneOwner->GetRenderColor() );
|
|
}
|
|
}
|
|
else //Use the render color of this entity
|
|
{
|
|
info.m_PaintPowerType = MapColorToPower( pEnt->GetRenderColor() );
|
|
}
|
|
|
|
if( sv_enable_paint_power_user_debug.GetBool() )
|
|
{
|
|
Warning( "Non-world, non-player entity, %s, doesn't implement IPaintableEntity. See the global version of MapSurfacesToPowers() in paint_power_user_interface.cpp.\n", pEnt->GetClassname() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( sv_debug_draw_contacts.GetInt() == 2 )
|
|
{
|
|
Color color = MapPowerToVisualColor( info.m_PaintPowerType );
|
|
NDebugOverlay::Sphere( info.m_ContactPoint, 5.0f, color.r(), color.g(), color.b(), true, 0 );
|
|
NDebugOverlay::Line( info.m_ContactPoint, info.m_ContactPoint + 20.0f * info.m_SurfaceNormal, color.r(), color.g(), color.b(), true, 0 );
|
|
}
|
|
}
|
|
|