p_trail.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright (c) ZeniMax Media Inc.
  2. // Licensed under the GNU General Public License 2.0.
  3. #include "g_local.h"
  4. /*
  5. ==============================================================================
  6. PLAYER TRAIL
  7. ==============================================================================
  8. This is a circular list containing the a list of points of where
  9. the player has been recently. It is used by monsters for pursuit.
  10. .origin the spot
  11. .owner forward link
  12. .aiment backward link
  13. */
  14. #define TRAIL_LENGTH 8
  15. edict_t *trail[TRAIL_LENGTH];
  16. int trail_head;
  17. qboolean trail_active = false;
  18. #define NEXT(n) (((n) + 1) & (TRAIL_LENGTH - 1))
  19. #define PREV(n) (((n) - 1) & (TRAIL_LENGTH - 1))
  20. void PlayerTrail_Init (void)
  21. {
  22. int n;
  23. if (deathmatch->value /* FIXME || coop */)
  24. return;
  25. for (n = 0; n < TRAIL_LENGTH; n++)
  26. {
  27. trail[n] = G_Spawn();
  28. trail[n]->classname = "player_trail";
  29. }
  30. trail_head = 0;
  31. trail_active = true;
  32. }
  33. void PlayerTrail_Add (vec3_t spot)
  34. {
  35. vec3_t temp;
  36. if (!trail_active)
  37. return;
  38. VectorCopy (spot, trail[trail_head]->s.origin);
  39. trail[trail_head]->timestamp = level.time;
  40. VectorSubtract (spot, trail[PREV(trail_head)]->s.origin, temp);
  41. trail[trail_head]->s.angles[1] = vectoyaw (temp);
  42. trail_head = NEXT(trail_head);
  43. }
  44. void PlayerTrail_New (vec3_t spot)
  45. {
  46. if (!trail_active)
  47. return;
  48. PlayerTrail_Init ();
  49. PlayerTrail_Add (spot);
  50. }
  51. edict_t *PlayerTrail_PickFirst (edict_t *self)
  52. {
  53. int marker;
  54. int n;
  55. if (!trail_active)
  56. return NULL;
  57. for (marker = trail_head, n = TRAIL_LENGTH; n; n--)
  58. {
  59. if(trail[marker]->timestamp <= self->monsterinfo.trail_time)
  60. marker = NEXT(marker);
  61. else
  62. break;
  63. }
  64. if (visible(self, trail[marker]))
  65. {
  66. return trail[marker];
  67. }
  68. if (visible(self, trail[PREV(marker)]))
  69. {
  70. return trail[PREV(marker)];
  71. }
  72. return trail[marker];
  73. }
  74. edict_t *PlayerTrail_PickNext (edict_t *self)
  75. {
  76. int marker;
  77. int n;
  78. if (!trail_active)
  79. return NULL;
  80. for (marker = trail_head, n = TRAIL_LENGTH; n; n--)
  81. {
  82. if(trail[marker]->timestamp <= self->monsterinfo.trail_time)
  83. marker = NEXT(marker);
  84. else
  85. break;
  86. }
  87. return trail[marker];
  88. }
  89. edict_t *PlayerTrail_LastSpot (void)
  90. {
  91. return trail[PREV(trail_head)];
  92. }