//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "order_heal.h" #include "tf_team.h" #include "tf_playerclass.h" #include "order_helpers.h" #define MAX_HEAL_DIST 1500 IMPLEMENT_SERVERCLASS_ST( COrderHeal, DT_OrderHeal ) END_SEND_TABLE() bool IsValidFn_Heal( void *pUserData, int a ) { // Can't heal dead players. CSortBase *p = (CSortBase*)pUserData; CBasePlayer *pPlayer = p->m_pPlayer->GetTeam()->GetPlayer( a ); // Can't heal yourself... if (p->m_pPlayer == pPlayer) return false; // Don't heal players that are too far away... const Vector &vPlayer = p->m_pPlayer->GetAbsOrigin(); if (vPlayer.DistToSqr(pPlayer->GetAbsOrigin()) > MAX_HEAL_DIST * MAX_HEAL_DIST ) return false; return pPlayer->IsAlive() && pPlayer->m_iHealth < pPlayer->m_iMaxHealth; } int SortFn_Heal( void *pUserData, int a, int b ) { CSortBase *p = (CSortBase*)pUserData; const Vector &vPlayer = p->m_pPlayer->GetAbsOrigin(); const Vector &va = p->m_pPlayer->GetTeam()->GetPlayer( a )->GetAbsOrigin(); const Vector &vb = p->m_pPlayer->GetTeam()->GetPlayer( b )->GetAbsOrigin(); return vPlayer.DistToSqr( va ) < vPlayer.DistToSqr( vb ); } bool COrderHeal::CreateOrder( CPlayerClass *pClass ) { CTFTeam *pTeam = pClass->GetTeam(); CSortBase info; info.m_pPlayer = pClass->GetPlayer(); int sorted[MAX_PLAYERS]; int nSorted = BuildSortedActiveList( sorted, MAX_PLAYERS, SortFn_Heal, IsValidFn_Heal, &info, pTeam->GetNumPlayers() ); if ( nSorted ) { COrderHeal *pOrder = new COrderHeal; pClass->GetTeam()->AddOrder( ORDER_HEAL, pTeam->GetPlayer( sorted[0] ), pClass->GetPlayer(), 1e24, 60, pOrder ); return true; } else { return false; } } bool COrderHeal::Update() { CBaseEntity *pTarget = GetTargetEntity(); if ( !pTarget || pTarget->m_iHealth >= pTarget->m_iMaxHealth ) return true; return false; } bool COrderHeal::UpdateOnEvent( COrderEvent_Base *pEvent ) { if ( pEvent->GetType() == ORDER_EVENT_PLAYER_KILLED ) { COrderEvent_PlayerKilled *pKilled = (COrderEvent_PlayerKilled*)pEvent; if ( pKilled->m_pPlayer == GetTargetEntity() ) return true; } return BaseClass::UpdateOnEvent( pEvent ); }