1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
//========= Copyright Valve Corporation, All rights reserved. ============//
// tf_tactical_mission.cpp
// Team Fortress specific missions
// Michael Booth, June 2009
#include "cbase.h"
#include "nav_pathfind.h"
#include "nav_mesh/tf_nav_mesh.h"
#include "tf_player.h"
#include "tf_tactical_mission.h"
extern ConVar tf_bot_max_point_defend_range;
/*
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
class CCollectPointDefenseAreas : public ISearchSurroundingAreasFunctor
{
public:
CCollectPointDefenseAreas( CTFNavArea *pointArea, bool isKingOfTheHill, CUtlVector< CNavArea * > *areaVector )
{
m_pointArea = pointArea;
m_isKingOfTheHill = isKingOfTheHill;
// don't select areas that are beyond the point
m_incursionFlowLimit = pointArea->GetIncursionDistance( TF_TEAM_RED ) + 250.0f;
m_areaVector = areaVector;
m_areaVector->RemoveAll();
}
virtual bool operator() ( CNavArea *baseArea, CNavArea *priorArea, float travelDistanceSoFar )
{
CTFNavArea *area = (CTFNavArea *)baseArea;
if ( !m_isKingOfTheHill )
{
// don't select areas that are beyond the point
if ( area->GetIncursionDistance( TF_TEAM_RED ) > m_incursionFlowLimit )
return true;
}
if ( area->IsPotentiallyVisible( m_pointArea ) )
{
// a bit of a hack here to avoid bots choosing to defend in bottom of ravine at stage 3 of dustbowl
const float tooLow = 220.0f;
if ( m_pointArea->GetCenter().z - area->GetCenter().z < tooLow )
{
// valid defense position
area->SetAttributeTF( TF_NAV_DEFEND_POINT );
m_areaVector->AddToTail( area );
}
}
return true;
}
virtual bool ShouldSearch( CNavArea *adjArea, CNavArea *currentArea, float travelDistanceSoFar )
{
if ( adjArea->IsBlocked( m_isKingOfTheHill ? TEAM_ANY : TF_TEAM_RED ) )
{
return false;
}
if ( travelDistanceSoFar > tf_bot_max_point_defend_range.GetFloat() )
{
// too far away
return false;
}
const float maxHeightChange = 65.0f;
float deltaZ = currentArea->ComputeAdjacentConnectionHeightChange( adjArea );
return ( fabs( deltaZ ) < maxHeightChange );
}
CTFNavArea *m_pointArea;
CUtlVector< CNavArea * > *m_areaVector;
float m_incursionFlowLimit;
bool m_isKingOfTheHill;
};
/ **
* Create a zone of areas that are good defensive places for the given point
* /
CTFDefendPointZone::CTFDefendPointZone( CTeamControlPoint *point )
{
CTFNavArea *pointArea = static_cast< CTFNavArea * >( TheNavMesh->GetNearestNavArea( point->GetAbsOrigin() ) );
if ( pointArea )
{
bool isKingOfTheHill = false;
CTeamControlPointMaster *master = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
if ( master )
{
isKingOfTheHill = ( master->GetNumPoints() == 1 );
}
// search outwards from the point along walkable areas (not drop downs) to make sure we can get back to the point quickly
CCollectPointDefenseAreas collector( pointArea, isKingOfTheHill, &m_areaVector );
SearchSurroundingAreas( pointArea, collector );
}
}
*/
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
/**
* Create a zone of areas that are good sniper spots to defend the given point
*/
CTFDefendPointSniperZone::CTFDefendPointSniperZone( CTeamControlPoint *point )
{
}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
CTFDefendPointMission::CTFDefendPointMission( CTeamControlPoint *point )
{
// m_defenseZone = new CTFDefendPointZone( point );
m_sniperZone = new CTFDefendPointSniperZone( point );
m_name.sprintf( "DefendPoint%d", point->GetPointIndex() );
}
//-----------------------------------------------------------------------------------------------------
CTFDefendPointMission::~CTFDefendPointMission( void )
{
// delete m_defenseZone;
delete m_sniperZone;
}
//-----------------------------------------------------------------------------------------------------
// where give player should be during this mission
const CTacticalMissionZone *CTFDefendPointMission::GetDeployZone( CBasePlayer *baseWho ) const
{
// CTFPlayer *who = ToTFPlayer( baseWho );
// if ( who->IsPlayerClass( TF_CLASS_SNIPER ) )
// return m_sniperZone;
return m_defenseZone;
}
//-----------------------------------------------------------------------------------------------------
// control points, setup gates, sections of cart path, etc.
const CTacticalMissionZone *CTFDefendPointMission::GetObjectiveZone( void ) const
{
return NULL;
}
//-----------------------------------------------------------------------------------------------------
// where we expect enemies to be during this mission
const CTacticalMissionZone *CTFDefendPointMission::GetEnemyZone( void ) const
{
return NULL;
}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
/**
* Invoked when server loads a new map, after everything has been created/spawned
*/
void CTFTacticalMissionManager::OnServerActivate( void )
{
}
//-----------------------------------------------------------------------------------------------------
/**
* Invoked when a game round restarts
*/
void CTFTacticalMissionManager::OnRoundRestart( void )
{
// for now, delete and rebuild all the missions
// @todo only delete/rebuild generated missions
FOR_EACH_VEC( m_missionVector, it )
{
delete m_missionVector[ it ];
}
m_missionVector.RemoveAll();
// generate a defensive mission for each control point
CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
if ( pMaster )
{
for( int i=0; i<pMaster->GetNumPoints(); ++i )
{
CTeamControlPoint *point = pMaster->GetControlPoint( i );
if ( point && pMaster->IsInRound( point ) )
{
CTFNavArea *pointArea = (CTFNavArea *)TheNavMesh->GetNearestNavArea( point->WorldSpaceCenter() );
if ( pointArea && pointArea->IsReachableByTeam( TF_TEAM_BLUE ) )
{
CTacticalMission *defendPointMission = new CTFDefendPointMission( point );
TheTacticalMissions().Register( defendPointMission );
}
}
}
}
}
|