diff options
Diffstat (limited to 'game/server/tf2/order_repair.cpp')
| -rw-r--r-- | game/server/tf2/order_repair.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/game/server/tf2/order_repair.cpp b/game/server/tf2/order_repair.cpp new file mode 100644 index 0000000..a75f75d --- /dev/null +++ b/game/server/tf2/order_repair.cpp @@ -0,0 +1,157 @@ +//========= 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; +} + + |