You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.3 KiB
157 lines
3.3 KiB
//========= 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; |
|
} |
|
|
|
|
|
|