source-engine/game/server/tf2/order_repair.cpp
2021-10-23 14:41:59 +03:00

158 lines
3.3 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "order_repair.h"
#include "tf_team.h"
#include "tf_class_defender.h"
#include "order_helpers.h"
#include "tf_obj.h"
IMPLEMENT_SERVERCLASS_ST( COrderRepair, DT_OrderRepair )
END_SEND_TABLE()
static int SortFn_Defender( void *pUserData, int a, int b )
{
CSortBase *p = (CSortBase*)pUserData;
const Vector &vOrigin1 = p->m_pPlayer->GetTFTeam()->GetObject( a )->GetAbsOrigin();
const Vector &vOrigin2 = p->m_pPlayer->GetTFTeam()->GetObject( b )->GetAbsOrigin();
return p->m_pPlayer->GetAbsOrigin().DistTo( vOrigin1 ) < p->m_pPlayer->GetAbsOrigin().DistTo( vOrigin2 );
}
static bool IsValidFn_RepairFriendlyObjects( void *pUserData, int a )
{
// Only pick objects that are damaged.
CSortBase *p = (CSortBase*)pUserData;
CBaseObject *pObj = p->m_pPlayer->GetTFTeam()->GetObject( a );
// Skip objects under construction
if ( pObj->IsBuilding() )
return false;
return ( pObj->m_iHealth < pObj->m_iMaxHealth );
}
static bool IsValidFn_RepairOwnObjects( void *pUserData, int a )
{
// Only pick objects that are damaged.
CSortBase *pSortBase = (CSortBase*)pUserData;
CBaseObject *pObj = pSortBase->m_pPlayer->GetObject(a);
// Skip objects under construction
if ( !pObj || pObj->IsBuilding() )
return false;
return pObj->m_iHealth < pObj->m_iMaxHealth;
}
bool COrderRepair::CreateOrder_RepairFriendlyObjects( CPlayerClassDefender *pClass )
{
if( !pClass->CanBuildSentryGun() )
return false;
CBaseTFPlayer *pPlayer = pClass->GetPlayer();
CTFTeam *pTeam = pClass->GetTeam();
// Sort the list and filter out fully healed objects..
CSortBase info;
info.m_pPlayer = pPlayer;
int sorted[MAX_TEAM_OBJECTS];
int nSorted = BuildSortedActiveList(
sorted,
MAX_TEAM_OBJECTS,
SortFn_Defender,
IsValidFn_RepairFriendlyObjects,
&info,
pTeam->GetNumObjects() );
// If the player is close enough to the closest damaged object, issue an order.
if( nSorted )
{
CBaseObject *pObjToHeal = pTeam->GetObject( sorted[0] );
static float flClosestDist = 1024;
if( pPlayer->GetAbsOrigin().DistTo( pObjToHeal->GetAbsOrigin() ) < flClosestDist )
{
COrder *pOrder = new COrderRepair;
pTeam->AddOrder(
ORDER_REPAIR,
pObjToHeal,
pPlayer,
1e24,
60,
pOrder
);
return true;
}
}
return false;
}
bool COrderRepair::CreateOrder_RepairOwnObjects( CPlayerClass *pClass )
{
CSortBase info;
info.m_pPlayer = pClass->GetPlayer();
int sorted[16];
int nSorted = BuildSortedActiveList(
sorted,
sizeof( sorted ) / sizeof( sorted[0] ),
SortFn_PlayerObjectsByDistance,
IsValidFn_RepairOwnObjects,
&info,
info.m_pPlayer->GetObjectCount() );
if( nSorted )
{
// Make an order to repair the closest damaged object.
CBaseObject *pObj = info.m_pPlayer->GetObject( sorted[0] );
if (!pObj)
return false;
COrderRepair *pOrder = new COrderRepair;
info.m_pPlayer->GetTFTeam()->AddOrder(
ORDER_REPAIR,
pObj,
info.m_pPlayer,
1e24,
60,
pOrder
);
return true;
}
else
{
return false;
}
}
bool COrderRepair::Update()
{
CBaseEntity *pEnt = GetTargetEntity();
if( !pEnt )
return true;
// Kill the order when the object is repaired.
return pEnt->m_iHealth >= pEnt->m_iMaxHealth;
}