|
|
|
//========= 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|