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