229 lines
6.6 KiB
C++
229 lines
6.6 KiB
C++
//=======================================================================
|
|
// Copyright (C) Shambler Team 2004
|
|
// baseinfo.cpp - point info entities.
|
|
// e.g. info_target
|
|
//=======================================================================
|
|
|
|
#include "extdll.h"
|
|
#include "utils.h"
|
|
#include "cbase.h"
|
|
#include "player.h"
|
|
|
|
//=======================================================================
|
|
// info_target (target entity)
|
|
//=======================================================================
|
|
|
|
class CInfoTarget : public CPointEntity
|
|
{
|
|
public:
|
|
void Spawn( void )
|
|
{
|
|
pev->solid = SOLID_NOT;
|
|
UTIL_SetModel(ENT(pev),"models/common/null.mdl");
|
|
UTIL_SetSize(pev, g_vecZero, g_vecZero);
|
|
SetBits( pev->flags, FL_POINTENTITY );
|
|
}
|
|
};
|
|
|
|
void CBaseDMStart::KeyValue( KeyValueData *pkvd )
|
|
{
|
|
if (FStrEq(pkvd->szKeyName, "master"))
|
|
{
|
|
pev->netname = ALLOC_STRING(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else
|
|
CPointEntity::KeyValue( pkvd );
|
|
}
|
|
|
|
STATE CBaseDMStart::GetState( CBaseEntity *pEntity )
|
|
{
|
|
if (UTIL_IsMasterTriggered( pev->netname, pEntity ))
|
|
return STATE_ON;
|
|
else return STATE_OFF;
|
|
}
|
|
|
|
//=========================================================
|
|
// static infodecal
|
|
//=========================================================
|
|
class CDecal : public CBaseEntity
|
|
{
|
|
public:
|
|
void KeyValue( KeyValueData *pkvd )
|
|
{
|
|
if (FStrEq(pkvd->szKeyName, "texture"))
|
|
{
|
|
pev->skin = DECAL_INDEX( pkvd->szValue );
|
|
if ( pev->skin >= 0 ) return;
|
|
Msg( "Can't find decal %s\n", pkvd->szValue );
|
|
}
|
|
}
|
|
void PostSpawn( void ) { if(FStringNull(pev->targetname))MakeDecal(); }
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { MakeDecal(); }
|
|
void MakeDecal( void )
|
|
{
|
|
if ( pev->skin < 0 ) { REMOVE_ENTITY(ENT(pev)); return; }
|
|
TraceResult trace;
|
|
int entityIndex, modelIndex;
|
|
UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace );
|
|
entityIndex = (short)ENTINDEX(trace.pHit);
|
|
if ( entityIndex ) modelIndex = (int)VARS(trace.pHit)->modelindex;
|
|
else modelIndex = 0;
|
|
|
|
if(FStringNull(pev->targetname)) g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );
|
|
else
|
|
{
|
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY);
|
|
WRITE_BYTE( TE_BSPDECAL );
|
|
WRITE_COORD( pev->origin.x );
|
|
WRITE_COORD( pev->origin.y );
|
|
WRITE_COORD( pev->origin.z );
|
|
WRITE_SHORT( (int)pev->skin );
|
|
WRITE_SHORT( entityIndex );
|
|
if(entityIndex) WRITE_SHORT( modelIndex );
|
|
MESSAGE_END();
|
|
}
|
|
|
|
SetThink( Remove );
|
|
SetNextThink( 0.3 );
|
|
}
|
|
};
|
|
|
|
//=========================================================
|
|
// Multiplayer intermission spots.
|
|
//=========================================================
|
|
class CInfoIntermission:public CPointEntity
|
|
{
|
|
void Spawn( void );
|
|
void Think( void );
|
|
void PostActivate( void );
|
|
CBaseEntity *pTarget;
|
|
};
|
|
|
|
void CInfoIntermission::Spawn( void )
|
|
{
|
|
pev->solid = SOLID_NOT;
|
|
pev->movetype = MOVETYPE_NOCLIP;
|
|
UTIL_SetOrigin( this, pev->origin );
|
|
UTIL_SetModel( ENT( pev ), "sprites/null.spr" );
|
|
|
|
SetNextThink( 1 );// let targets spawn!
|
|
}
|
|
|
|
void CInfoIntermission::PostActivate( void )
|
|
{
|
|
pTarget = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
|
|
if( !pev->speed ) pev->speed = 100;
|
|
}
|
|
|
|
void CInfoIntermission::Think ( void )
|
|
{
|
|
if( pTarget )
|
|
{
|
|
UTIL_WatchTarget( this, pTarget );
|
|
SetNextThink( 0 );
|
|
}
|
|
}
|
|
|
|
//====================================================================
|
|
// multisource
|
|
//====================================================================
|
|
|
|
TYPEDESCRIPTION CMultiSource::m_SaveData[] =
|
|
{
|
|
DEFINE_ARRAY( CMultiSource, m_rgEntities, FIELD_EHANDLE, MAX_MULTI_TARGETS ),
|
|
DEFINE_ARRAY( CMultiSource, m_rgTriggered, FIELD_INTEGER, MAX_MULTI_TARGETS ),
|
|
DEFINE_FIELD( CMultiSource, m_iTotal, FIELD_INTEGER ),
|
|
}; IMPLEMENT_SAVERESTORE( CMultiSource, CBaseLogic );
|
|
LINK_ENTITY_TO_CLASS( multisource, CMultiSource );
|
|
|
|
void CMultiSource::Spawn()
|
|
{
|
|
pev->solid = SOLID_NOT;
|
|
pev->movetype = MOVETYPE_NONE;
|
|
SetNextThink( 0.1 );
|
|
pev->spawnflags |= SF_START_ON;
|
|
SetThink( Register );
|
|
}
|
|
|
|
void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
|
{
|
|
int i = 0;
|
|
|
|
// Find the entity in our list
|
|
while (i < m_iTotal) if ( m_rgEntities[i++] == pCaller ) break;
|
|
|
|
// if we didn't find it, report error and leave
|
|
if (i > m_iTotal) return;
|
|
|
|
STATE s = GetState();
|
|
m_rgTriggered[i-1] ^= 1;
|
|
if ( s == GetState()) return;
|
|
|
|
if ( s == STATE_OFF )
|
|
{
|
|
USE_TYPE useType = USE_TOGGLE;
|
|
if ( m_globalstate ) useType = USE_ON;
|
|
UTIL_FireTargets( pev->target, NULL, this, useType, value );
|
|
UTIL_FireTargets( m_iszKillTarget, NULL, this, USE_REMOVE );
|
|
}
|
|
}
|
|
|
|
STATE CMultiSource::GetState( void )
|
|
{
|
|
// Is everything triggered?
|
|
int i = 0;
|
|
|
|
// Still initializing?
|
|
if ( pev->spawnflags & SF_START_ON ) return STATE_OFF;
|
|
|
|
while (i < m_iTotal)
|
|
{
|
|
if (m_rgTriggered[i] == 0) break;
|
|
i++;
|
|
}
|
|
|
|
if (i == m_iTotal)
|
|
{
|
|
if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON )
|
|
return STATE_ON;
|
|
}
|
|
return STATE_OFF;
|
|
}
|
|
|
|
void CMultiSource::Register(void)
|
|
{
|
|
m_iTotal = 0;
|
|
memset( m_rgEntities, 0, MAX_MULTI_TARGETS * sizeof(EHANDLE) );
|
|
|
|
SetThink(NULL);
|
|
|
|
// search for all entities which target this multisource (pev->targetname)
|
|
|
|
CBaseEntity *pTarget = UTIL_FindEntityByTarget( NULL, STRING(pev->targetname) );
|
|
while (pTarget && (m_iTotal < MAX_MULTI_TARGETS))
|
|
{
|
|
m_rgEntities[m_iTotal++] = pTarget;
|
|
pTarget = UTIL_FindEntityByTarget( pTarget, STRING(pev->targetname));
|
|
}
|
|
|
|
pTarget = UTIL_FindEntityByClassname(NULL, "multi_manager");
|
|
while (pTarget && (m_iTotal < MAX_MULTI_TARGETS))
|
|
{
|
|
if ( pTarget->HasTarget(pev->targetname) ) m_rgEntities[m_iTotal++] = pTarget;
|
|
pTarget = UTIL_FindEntityByClassname( pTarget, "multi_manager" );
|
|
}
|
|
pev->spawnflags &= ~SF_START_ON;
|
|
}
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS( infodecal, CDecal );
|
|
LINK_ENTITY_TO_CLASS( info_target, CInfoTarget );
|
|
LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
|
|
LINK_ENTITY_TO_CLASS( info_null, CNullEntity);
|
|
LINK_ENTITY_TO_CLASS( info_texlights, CNullEntity);
|
|
LINK_ENTITY_TO_CLASS( info_compile_parameters, CNullEntity);
|
|
LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission );
|
|
LINK_ENTITY_TO_CLASS( info_player_deathmatch, CBaseDMStart);
|
|
LINK_ENTITY_TO_CLASS( info_player_start, CPointEntity);
|
|
LINK_ENTITY_TO_CLASS( info_landmark, CPointEntity); |