be_aas_entity.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. /*****************************************************************************
  19. * name: be_aas_entity.c
  20. *
  21. * desc: AAS entities
  22. *
  23. * $Archive: /MissionPack/code/botlib/be_aas_entity.c $
  24. *
  25. *****************************************************************************/
  26. #include "../game/q_shared.h"
  27. #include "l_memory.h"
  28. #include "l_script.h"
  29. #include "l_precomp.h"
  30. #include "l_struct.h"
  31. #include "l_utils.h"
  32. #include "l_log.h"
  33. #include "aasfile.h"
  34. #include "../game/botlib.h"
  35. #include "../game/be_aas.h"
  36. #include "be_aas_funcs.h"
  37. #include "be_interface.h"
  38. #include "be_aas_def.h"
  39. #define MASK_SOLID CONTENTS_PLAYERCLIP
  40. //FIXME: these might change
  41. enum {
  42. ET_GENERAL,
  43. ET_PLAYER,
  44. ET_ITEM,
  45. ET_MISSILE,
  46. ET_MOVER
  47. };
  48. //===========================================================================
  49. //
  50. // Parameter: -
  51. // Returns: -
  52. // Changes Globals: -
  53. //===========================================================================
  54. int AAS_UpdateEntity(int entnum, bot_entitystate_t *state)
  55. {
  56. int relink;
  57. aas_entity_t *ent;
  58. vec3_t absmins, absmaxs;
  59. if (!aasworld.loaded)
  60. {
  61. botimport.Print(PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n");
  62. return BLERR_NOAASFILE;
  63. } //end if
  64. ent = &aasworld.entities[entnum];
  65. if (!state) {
  66. //unlink the entity
  67. AAS_UnlinkFromAreas(ent->areas);
  68. //unlink the entity from the BSP leaves
  69. AAS_UnlinkFromBSPLeaves(ent->leaves);
  70. //
  71. ent->areas = NULL;
  72. //
  73. ent->leaves = NULL;
  74. return BLERR_NOERROR;
  75. }
  76. ent->i.update_time = AAS_Time() - ent->i.ltime;
  77. ent->i.type = state->type;
  78. ent->i.flags = state->flags;
  79. ent->i.ltime = AAS_Time();
  80. VectorCopy(ent->i.origin, ent->i.lastvisorigin);
  81. VectorCopy(state->old_origin, ent->i.old_origin);
  82. ent->i.solid = state->solid;
  83. ent->i.groundent = state->groundent;
  84. ent->i.modelindex = state->modelindex;
  85. ent->i.modelindex2 = state->modelindex2;
  86. ent->i.frame = state->frame;
  87. ent->i.event = state->event;
  88. ent->i.eventParm = state->eventParm;
  89. ent->i.powerups = state->powerups;
  90. ent->i.weapon = state->weapon;
  91. ent->i.legsAnim = state->legsAnim;
  92. ent->i.torsoAnim = state->torsoAnim;
  93. //number of the entity
  94. ent->i.number = entnum;
  95. //updated so set valid flag
  96. ent->i.valid = qtrue;
  97. //link everything the first frame
  98. if (aasworld.numframes == 1) relink = qtrue;
  99. else relink = qfalse;
  100. //
  101. if (ent->i.solid == SOLID_BSP)
  102. {
  103. //if the angles of the model changed
  104. if (!VectorCompare(state->angles, ent->i.angles))
  105. {
  106. VectorCopy(state->angles, ent->i.angles);
  107. relink = qtrue;
  108. } //end if
  109. //get the mins and maxs of the model
  110. //FIXME: rotate mins and maxs
  111. AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
  112. } //end if
  113. else if (ent->i.solid == SOLID_BBOX)
  114. {
  115. //if the bounding box size changed
  116. if (!VectorCompare(state->mins, ent->i.mins) ||
  117. !VectorCompare(state->maxs, ent->i.maxs))
  118. {
  119. VectorCopy(state->mins, ent->i.mins);
  120. VectorCopy(state->maxs, ent->i.maxs);
  121. relink = qtrue;
  122. } //end if
  123. VectorCopy(state->angles, ent->i.angles);
  124. } //end if
  125. //if the origin changed
  126. if (!VectorCompare(state->origin, ent->i.origin))
  127. {
  128. VectorCopy(state->origin, ent->i.origin);
  129. relink = qtrue;
  130. } //end if
  131. //if the entity should be relinked
  132. if (relink)
  133. {
  134. //don't link the world model
  135. if (entnum != ENTITYNUM_WORLD)
  136. {
  137. //absolute mins and maxs
  138. VectorAdd(ent->i.mins, ent->i.origin, absmins);
  139. VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
  140. //unlink the entity
  141. AAS_UnlinkFromAreas(ent->areas);
  142. //relink the entity to the AAS areas (use the larges bbox)
  143. ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
  144. //unlink the entity from the BSP leaves
  145. AAS_UnlinkFromBSPLeaves(ent->leaves);
  146. //link the entity to the world BSP tree
  147. ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
  148. } //end if
  149. } //end if
  150. return BLERR_NOERROR;
  151. } //end of the function AAS_UpdateEntity
  152. //===========================================================================
  153. //
  154. // Parameter: -
  155. // Returns: -
  156. // Changes Globals: -
  157. //===========================================================================
  158. void AAS_EntityInfo(int entnum, aas_entityinfo_t *info)
  159. {
  160. if (!aasworld.initialized)
  161. {
  162. botimport.Print(PRT_FATAL, "AAS_EntityInfo: aasworld not initialized\n");
  163. Com_Memset(info, 0, sizeof(aas_entityinfo_t));
  164. return;
  165. } //end if
  166. if (entnum < 0 || entnum >= aasworld.maxentities)
  167. {
  168. botimport.Print(PRT_FATAL, "AAS_EntityInfo: entnum %d out of range\n", entnum);
  169. Com_Memset(info, 0, sizeof(aas_entityinfo_t));
  170. return;
  171. } //end if
  172. Com_Memcpy(info, &aasworld.entities[entnum].i, sizeof(aas_entityinfo_t));
  173. } //end of the function AAS_EntityInfo
  174. //===========================================================================
  175. //
  176. // Parameter: -
  177. // Returns: -
  178. // Changes Globals: -
  179. //===========================================================================
  180. void AAS_EntityOrigin(int entnum, vec3_t origin)
  181. {
  182. if (entnum < 0 || entnum >= aasworld.maxentities)
  183. {
  184. botimport.Print(PRT_FATAL, "AAS_EntityOrigin: entnum %d out of range\n", entnum);
  185. VectorClear(origin);
  186. return;
  187. } //end if
  188. VectorCopy(aasworld.entities[entnum].i.origin, origin);
  189. } //end of the function AAS_EntityOrigin
  190. //===========================================================================
  191. //
  192. // Parameter: -
  193. // Returns: -
  194. // Changes Globals: -
  195. //===========================================================================
  196. int AAS_EntityModelindex(int entnum)
  197. {
  198. if (entnum < 0 || entnum >= aasworld.maxentities)
  199. {
  200. botimport.Print(PRT_FATAL, "AAS_EntityModelindex: entnum %d out of range\n", entnum);
  201. return 0;
  202. } //end if
  203. return aasworld.entities[entnum].i.modelindex;
  204. } //end of the function AAS_EntityModelindex
  205. //===========================================================================
  206. //
  207. // Parameter: -
  208. // Returns: -
  209. // Changes Globals: -
  210. //===========================================================================
  211. int AAS_EntityType(int entnum)
  212. {
  213. if (!aasworld.initialized) return 0;
  214. if (entnum < 0 || entnum >= aasworld.maxentities)
  215. {
  216. botimport.Print(PRT_FATAL, "AAS_EntityType: entnum %d out of range\n", entnum);
  217. return 0;
  218. } //end if
  219. return aasworld.entities[entnum].i.type;
  220. } //end of the AAS_EntityType
  221. //===========================================================================
  222. //
  223. // Parameter: -
  224. // Returns: -
  225. // Changes Globals: -
  226. //===========================================================================
  227. int AAS_EntityModelNum(int entnum)
  228. {
  229. if (!aasworld.initialized) return 0;
  230. if (entnum < 0 || entnum >= aasworld.maxentities)
  231. {
  232. botimport.Print(PRT_FATAL, "AAS_EntityModelNum: entnum %d out of range\n", entnum);
  233. return 0;
  234. } //end if
  235. return aasworld.entities[entnum].i.modelindex;
  236. } //end of the function AAS_EntityModelNum
  237. //===========================================================================
  238. //
  239. // Parameter: -
  240. // Returns: -
  241. // Changes Globals: -
  242. //===========================================================================
  243. int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin)
  244. {
  245. int i;
  246. aas_entity_t *ent;
  247. for (i = 0; i < aasworld.maxentities; i++)
  248. {
  249. ent = &aasworld.entities[i];
  250. if (ent->i.type == ET_MOVER)
  251. {
  252. if (ent->i.modelindex == modelnum)
  253. {
  254. VectorCopy(ent->i.origin, origin);
  255. return qtrue;
  256. } //end if
  257. } //end if
  258. } //end for
  259. return qfalse;
  260. } //end of the function AAS_OriginOfMoverWithModelNum
  261. //===========================================================================
  262. //
  263. // Parameter: -
  264. // Returns: -
  265. // Changes Globals: -
  266. //===========================================================================
  267. void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs)
  268. {
  269. aas_entity_t *ent;
  270. if (!aasworld.initialized) return;
  271. if (entnum < 0 || entnum >= aasworld.maxentities)
  272. {
  273. botimport.Print(PRT_FATAL, "AAS_EntitySize: entnum %d out of range\n", entnum);
  274. return;
  275. } //end if
  276. ent = &aasworld.entities[entnum];
  277. VectorCopy(ent->i.mins, mins);
  278. VectorCopy(ent->i.maxs, maxs);
  279. } //end of the function AAS_EntitySize
  280. //===========================================================================
  281. //
  282. // Parameter: -
  283. // Returns: -
  284. // Changes Globals: -
  285. //===========================================================================
  286. void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata)
  287. {
  288. aas_entity_t *ent;
  289. ent = &aasworld.entities[entnum];
  290. VectorCopy(ent->i.origin, entdata->origin);
  291. VectorCopy(ent->i.angles, entdata->angles);
  292. VectorAdd(ent->i.origin, ent->i.mins, entdata->absmins);
  293. VectorAdd(ent->i.origin, ent->i.maxs, entdata->absmaxs);
  294. entdata->solid = ent->i.solid;
  295. entdata->modelnum = ent->i.modelindex - 1;
  296. } //end of the function AAS_EntityBSPData
  297. //===========================================================================
  298. //
  299. // Parameter: -
  300. // Returns: -
  301. // Changes Globals: -
  302. //===========================================================================
  303. void AAS_ResetEntityLinks(void)
  304. {
  305. int i;
  306. for (i = 0; i < aasworld.maxentities; i++)
  307. {
  308. aasworld.entities[i].areas = NULL;
  309. aasworld.entities[i].leaves = NULL;
  310. } //end for
  311. } //end of the function AAS_ResetEntityLinks
  312. //===========================================================================
  313. //
  314. // Parameter: -
  315. // Returns: -
  316. // Changes Globals: -
  317. //===========================================================================
  318. void AAS_InvalidateEntities(void)
  319. {
  320. int i;
  321. for (i = 0; i < aasworld.maxentities; i++)
  322. {
  323. aasworld.entities[i].i.valid = qfalse;
  324. aasworld.entities[i].i.number = i;
  325. } //end for
  326. } //end of the function AAS_InvalidateEntities
  327. //===========================================================================
  328. //
  329. // Parameter: -
  330. // Returns: -
  331. // Changes Globals: -
  332. //===========================================================================
  333. void AAS_UnlinkInvalidEntities(void)
  334. {
  335. int i;
  336. aas_entity_t *ent;
  337. for (i = 0; i < aasworld.maxentities; i++)
  338. {
  339. ent = &aasworld.entities[i];
  340. if (!ent->i.valid)
  341. {
  342. AAS_UnlinkFromAreas( ent->areas );
  343. ent->areas = NULL;
  344. AAS_UnlinkFromBSPLeaves( ent->leaves );
  345. ent->leaves = NULL;
  346. } //end for
  347. } //end for
  348. } //end of the function AAS_UnlinkInvalidEntities
  349. //===========================================================================
  350. //
  351. // Parameter: -
  352. // Returns: -
  353. // Changes Globals: -
  354. //===========================================================================
  355. int AAS_NearestEntity(vec3_t origin, int modelindex)
  356. {
  357. int i, bestentnum;
  358. float dist, bestdist;
  359. aas_entity_t *ent;
  360. vec3_t dir;
  361. bestentnum = 0;
  362. bestdist = 99999;
  363. for (i = 0; i < aasworld.maxentities; i++)
  364. {
  365. ent = &aasworld.entities[i];
  366. if (ent->i.modelindex != modelindex) continue;
  367. VectorSubtract(ent->i.origin, origin, dir);
  368. if (abs(dir[0]) < 40)
  369. {
  370. if (abs(dir[1]) < 40)
  371. {
  372. dist = VectorLength(dir);
  373. if (dist < bestdist)
  374. {
  375. bestdist = dist;
  376. bestentnum = i;
  377. } //end if
  378. } //end if
  379. } //end if
  380. } //end for
  381. return bestentnum;
  382. } //end of the function AAS_NearestEntity
  383. //===========================================================================
  384. //
  385. // Parameter: -
  386. // Returns: -
  387. // Changes Globals: -
  388. //===========================================================================
  389. int AAS_BestReachableEntityArea(int entnum)
  390. {
  391. aas_entity_t *ent;
  392. ent = &aasworld.entities[entnum];
  393. return AAS_BestReachableLinkArea(ent->areas);
  394. } //end of the function AAS_BestReachableEntityArea
  395. //===========================================================================
  396. //
  397. // Parameter: -
  398. // Returns: -
  399. // Changes Globals: -
  400. //===========================================================================
  401. int AAS_NextEntity(int entnum)
  402. {
  403. if (!aasworld.loaded) return 0;
  404. if (entnum < 0) entnum = -1;
  405. while(++entnum < aasworld.maxentities)
  406. {
  407. if (aasworld.entities[entnum].i.valid) return entnum;
  408. } //end while
  409. return 0;
  410. } //end of the function AAS_NextEntity