1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 //b_goal.cpp
24 #include "b_local.h"
25 #include "Q3_Interface.h"
26 #include "g_navigator.h"
27 
28 extern qboolean FlyingCreature( gentity_t *ent );
29 /*
30 SetGoal
31 */
32 
SetGoal(gentity_t * goal,float rating)33 void SetGoal( gentity_t *goal, float rating )
34 {
35 	NPCInfo->goalEntity = goal;
36 //	NPCInfo->goalEntityNeed = rating;
37 	NPCInfo->goalTime = level.time;
38 	if ( goal )
39 	{
40 //		Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_SetGoal: %s @ %s (%f)\n", goal->classname, vtos( goal->currentOrigin), rating );
41 	}
42 	else
43 	{
44 //		Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_SetGoal: NONE\n" );
45 	}
46 }
47 
48 
49 /*
50 NPC_SetGoal
51 */
52 
NPC_SetGoal(gentity_t * goal,float rating)53 void NPC_SetGoal( gentity_t *goal, float rating )
54 {
55 	if ( goal == NPCInfo->goalEntity )
56 	{
57 		return;
58 	}
59 
60 	if ( !goal )
61 	{
62 //		Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_ERROR, "NPC_SetGoal: NULL goal\n" );
63 		return;
64 	}
65 
66 	if ( goal->client )
67 	{
68 //		Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_ERROR, "NPC_SetGoal: goal is a client\n" );
69 		return;
70 	}
71 
72 	if ( NPCInfo->goalEntity )
73 	{
74 //		Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_SetGoal: push %s\n", NPCInfo->goalEntity->classname );
75 		NPCInfo->lastGoalEntity = NPCInfo->goalEntity;
76 //		NPCInfo->lastGoalEntityNeed = NPCInfo->goalEntityNeed;
77 	}
78 
79 	SetGoal( goal, rating );
80 }
81 
82 
83 /*
84 NPC_ClearGoal
85 */
86 
NPC_ClearGoal(void)87 void NPC_ClearGoal( void )
88 {
89 	gentity_t	*goal;
90 
91 	if ( !NPCInfo->lastGoalEntity )
92 	{
93 		SetGoal( NULL, 0.0 );
94 		return;
95 	}
96 
97 	goal = NPCInfo->lastGoalEntity;
98 	NPCInfo->lastGoalEntity = NULL;
99 	if ( goal->inuse && !(goal->s.eFlags & EF_NODRAW) )
100 	{
101 //		Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "NPC_ClearGoal: pop %s\n", goal->classname );
102 		SetGoal( goal, 0 );//, NPCInfo->lastGoalEntityNeed
103 		return;
104 	}
105 
106 	SetGoal( NULL, 0.0 );
107 }
108 
109 /*
110 -------------------------
111 G_BoundsOverlap
112 -------------------------
113 */
114 
G_BoundsOverlap(const vec3_t mins1,const vec3_t maxs1,const vec3_t mins2,const vec3_t maxs2)115 qboolean G_BoundsOverlap(const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2)
116 {//NOTE: flush up against counts as overlapping
117 	if(mins1[0]>maxs2[0])
118 		return qfalse;
119 
120 	if(mins1[1]>maxs2[1])
121 		return qfalse;
122 
123 	if(mins1[2]>maxs2[2])
124 		return qfalse;
125 
126 	if(maxs1[0]<mins2[0])
127 		return qfalse;
128 
129 	if(maxs1[1]<mins2[1])
130 		return qfalse;
131 
132 	if(maxs1[2]<mins2[2])
133 		return qfalse;
134 
135 	return qtrue;
136 }
137 
NPC_ReachedGoal(void)138 void NPC_ReachedGoal( void )
139 {
140 //	Debug_NPCPrintf( NPC, debugNPCAI, DEBUG_LEVEL_INFO, "UpdateGoal: reached goal entity\n" );
141 	NPC_ClearGoal();
142 	NPCInfo->goalTime = level.time;
143 
144 //MCG - Begin
145 	NPCInfo->aiFlags &= ~NPCAI_MOVING;
146 	ucmd.forwardmove = 0;
147 	//Return that the goal was reached
148 	Q3_TaskIDComplete( NPC, TID_MOVE_NAV );
149 //MCG - End
150 }
151 /*
152 ReachedGoal
153 
154 id removed checks against waypoints and is now checking surfaces
155 */
ReachedGoal(gentity_t * goal)156 qboolean ReachedGoal( gentity_t *goal )
157 {
158 
159 	if ( NPCInfo->aiFlags & NPCAI_TOUCHED_GOAL )
160 	{
161 		NPCInfo->aiFlags &= ~NPCAI_TOUCHED_GOAL;
162 		return qtrue;
163 	}
164 	return (qboolean)STEER::Reached(NPC, goal, NPCInfo->goalRadius, FlyingCreature(NPC) != qfalse);
165 }
166 
167 /*
168 static gentity_t *UpdateGoal( void )
169 
170 Id removed a lot of shit here... doesn't seem to handle waypoints independantly of goalentity
171 
172 In fact, doesn't seem to be any waypoint info on entities at all any more?
173 
174 MCG - Since goal is ALWAYS goalEntity, took out a lot of sending goal entity pointers around for no reason
175 */
176 
UpdateGoal(void)177 gentity_t *UpdateGoal( void )
178 {
179 	//FIXME: CREED should look at this
180 	//		this func doesn't seem to be working correctly for the sand creature
181 
182 	gentity_t	*goal;
183 
184 	if ( !NPCInfo->goalEntity )
185 	{
186 		return NULL;
187 	}
188 
189 	if ( !NPCInfo->goalEntity->inuse )
190 	{//Somehow freed it, but didn't clear it
191 		NPC_ClearGoal();
192 		return NULL;
193 	}
194 
195 	goal = NPCInfo->goalEntity;
196 
197 	if ( ReachedGoal( goal ) )
198 	{
199 		NPC_ReachedGoal();
200 		goal = NULL;//so they don't keep trying to move to it
201 	}//else if fail, need to tell script so?
202 
203 	return goal;
204 }
205 
206