📄 tf_func_resource.cpp
字号:
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Resource collection area
//=============================================================================
#include "cbase.h"
#include "EntityOutput.h"
#include "EntityList.h"
#include "tf_player.h"
#include "tf_func_resource.h"
#include "tf_team.h"
#include "tf_basecombatweapon.h"
#include "gamerules.h"
#include "ammodef.h"
#include "tf_obj.h"
#include "resource_chunk.h"
#include "vstdlib/random.h"
#include "engine/IEngineSound.h"
#include "team_messages.h"
#include "tf_stats.h"
LINK_ENTITY_TO_CLASS( trigger_resourcezone, CResourceZone);
BEGIN_DATADESC( CResourceZone )
// keys
DEFINE_KEYFIELD_NOT_SAVED( CResourceZone, m_nResourcesLeft, FIELD_INTEGER, "ResourceAmount" ),
DEFINE_KEYFIELD_NOT_SAVED( CResourceZone, m_iMaxChunks, FIELD_INTEGER, "ResourceChunks" ),
DEFINE_KEYFIELD_NOT_SAVED( CResourceZone, m_flResourceRate, FIELD_FLOAT, "ResourceRate" ),
DEFINE_KEYFIELD_NOT_SAVED( CResourceZone, m_flChunkValueMin, FIELD_FLOAT, "ChunkValueMin" ),
DEFINE_KEYFIELD_NOT_SAVED( CResourceZone, m_flChunkValueMax, FIELD_FLOAT, "ChunkValueMax" ),
// inputs
DEFINE_INPUTFUNC( CResourceZone, FIELD_INTEGER, "SetAmount", InputSetAmount ),
DEFINE_INPUTFUNC( CResourceZone, FIELD_VOID, "ResetAmount", InputResetAmount ),
DEFINE_INPUTFUNC( CResourceZone, FIELD_VOID, "SetActive", InputSetActive ),
DEFINE_INPUTFUNC( CResourceZone, FIELD_VOID, "SetInactive", InputSetInactive ),
DEFINE_INPUTFUNC( CResourceZone, FIELD_VOID, "ToggleActive", InputToggleActive ),
// outputs
DEFINE_OUTPUT( CResourceZone, m_OnEmpty, "OnEmpty" ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST(CResourceZone, DT_ResourceZone)
SendPropFloat( SENDINFO( m_flClientResources ), 8, SPROP_UNSIGNED, 0.0f, 1.0f ),
SendPropInt( SENDINFO( m_nResourcesLeft ), 20, SPROP_UNSIGNED ),
END_SEND_TABLE();
PRECACHE_REGISTER( trigger_resourcezone );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CResourceZone::CResourceZone()
{
#ifdef _DEBUG
m_vecGatherPoint.Init();
m_angGatherPoint.Init();
#endif
NetworkStateManualMode( true );
}
//-----------------------------------------------------------------------------
// Purpose: Initializes the resource zone
//-----------------------------------------------------------------------------
void CResourceZone::Spawn( void )
{
SetSolid( SOLID_BSP );
AddSolidFlags( FSOLID_TRIGGER );
SetMoveType( MOVETYPE_NONE );
m_fEffects |= EF_NODRAW;
SetModel( STRING( GetModelName() ) );
if ( !m_nResourcesLeft )
{
m_nResourcesLeft = 10000;
}
m_nMaxResources = m_nResourcesLeft;
m_flClientResources = 1;
SetActive( false );
m_vecGatherPoint = WorldSpaceCenter();
m_angGatherPoint = vec3_angle;
m_iTeamGathering = -1;
m_aSpawners.Purge();
m_hResourcePump = NULL;
if ( !m_iMaxChunks )
m_iMaxChunks = 5;
if ( !m_flChunkValueMin )
m_flChunkValueMin = 20;
if ( !m_flChunkValueMax )
m_flChunkValueMax = 60;
m_flBaseResourceRate = m_flResourceRate;
m_flRespawnTimeModifier = 1.0f;
m_flTestTime = 0;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::Precache( void )
{
}
//-----------------------------------------------------------------------------
// Purpose: See if we've got a gather point specified
//-----------------------------------------------------------------------------
void CResourceZone::Activate( void )
{
BaseClass::Activate();
if (m_target != NULL_STRING)
{
CBaseEntity *pEnt = gEntList.FindEntityByName( NULL, m_target, NULL );
if ( pEnt )
{
m_vecGatherPoint = pEnt->GetLocalOrigin();
m_angGatherPoint = pEnt->GetLocalAngles();
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::InputSetAmount( inputdata_t &inputdata )
{
m_nMaxResources = m_nResourcesLeft = inputdata.value.Int();
RecomputeClientResources();
// We may have just been reactivated
if ( m_nResourcesLeft )
{
SetActive( true );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::InputResetAmount( inputdata_t &inputdata )
{
m_nResourcesLeft = m_nMaxResources;
m_flClientResources = 1;
// We may have just been reactivated
if ( m_nResourcesLeft )
{
SetActive( true );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::InputSetActive( inputdata_t &inputdata )
{
SetActive( true );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::InputSetInactive( inputdata_t &inputdata )
{
SetActive( false );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::InputToggleActive( inputdata_t &inputdata )
{
if ( GetActive() )
{
SetActive( false );
}
else
{
SetActive( true );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::SetActive( bool bActive )
{
// Going active?
if ( !m_bActive && bActive )
{
// Start our ambient sound
//EmitAmbientSound( this, Center(), "ResourceZone.AmbientActiveSound" );
}
else if ( m_bActive && !bActive )
{
// Going inactive
// Stop our sound loop
//StopSound( "ResourceZone.AmbientActiveSound" );
}
m_bActive = bActive;
// Tell all my spawners
for ( int i = 0; i < m_aSpawners.Size(); i++ )
{
m_aSpawners[i]->SetActive( bActive );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CResourceZone::GetActive() const
{
return m_bActive;
}
//-----------------------------------------------------------------------------
// Zone increasing....
//-----------------------------------------------------------------------------
void CResourceZone::AddZoneIncreaser( float rate )
{
Assert( rate != 0.0f );
m_flRespawnTimeModifier *= rate;
m_flResourceRate = m_flBaseResourceRate / m_flRespawnTimeModifier;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CResourceZone::RemoveZoneIncreaser( float rate )
{
Assert( rate != 0.0f );
m_flRespawnTimeModifier /= rate;
m_flResourceRate = m_flBaseResourceRate / m_flRespawnTimeModifier;
}
//-----------------------------------------------------------------------------
// Purpose: Removes resources from the zone, and returns true if it's now empty
//-----------------------------------------------------------------------------
bool CResourceZone::RemoveResources( int nResourcesRemoved )
{
if ( IsEmpty() )
return true;
m_nResourcesLeft = max(0, m_nResourcesLeft - nResourcesRemoved);
RecomputeClientResources();
// If I'm out of resources, destroy my resource spawners
if ( IsEmpty() )
{
// Tell all existing chunks to stay forever
int i;
for ( i = 0; i < m_aChunks.Size(); i++ )
{
// Clear them removal think
m_aChunks[i]->SetThink( NULL );
}
SetActive( false );
// Tell teams about it
for ( i = 1; i <= GetNumberOfTeams(); i++ )
{
CTFTeam *pTeam = GetGlobalTFTeam( i );
pTeam->PostMessage( TEAMMSG_RESOURCE_ZONE_EMPTIED );
}
// Fire my output
m_OnEmpty.FireOutput( NULL,this );
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Return true if this zone is empty
//-----------------------------------------------------------------------------
bool CResourceZone::IsEmpty( void )
{
// Inactive zones pretend to be empty, so nothing tries to do anything with them
if ( !GetActive() )
return true;
return (m_nResourcesLeft <= 0);
}
//-----------------------------------------------------------------------------
// Purpose: Return true if the specified point is within this zone
//-----------------------------------------------------------------------------
bool CResourceZone::PointIsWithin( const Vector &vecPoint )
{
return ( ( vecPoint.x > GetAbsMins().x && vecPoint.x < GetAbsMaxs().x ) &&
( vecPoint.y > GetAbsMins().y && vecPoint.y < GetAbsMaxs().y ) &&
( vecPoint.z > GetAbsMins().z && vecPoint.z < GetAbsMaxs().z ) );
}
//-----------------------------------------------------------------------------
// Purpose: Resource zones have 1 build point
//-----------------------------------------------------------------------------
int CResourceZone::GetNumBuildPoints( void ) const
{
return 1;
}
//-----------------------------------------------------------------------------
// Purpose: Return true if the specified object type can be built on this point
//-----------------------------------------------------------------------------
bool CResourceZone::CanBuildObjectOnBuildPoint( int iPoint, int iObjectType )
{
ASSERT( iPoint <= GetNumBuildPoints() );
// Don't allow more than one pump
if ( m_hResourcePump.Get() )
return false;
// Only pumps can be built on zones
return ( iObjectType == OBJ_RESOURCEPUMP );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CResourceZone::GetBuildPoint( int iPoint, Vector &vecOrigin, QAngle &vecAngles )
{
ASSERT( iPoint <= GetNumBuildPoints() );
// If we have a gather point, return it
if ( m_vecGatherPoint != WorldSpaceCenter() )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -