p_trail.c (2852B)
1 /* 2 Copyright (C) 1997-2001 Id Software, Inc. 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 See the GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 */ 20 #include "g_local.h" 21 22 23 /* 24 ============================================================================== 25 26 PLAYER TRAIL 27 28 ============================================================================== 29 30 This is a circular list containing the a list of points of where 31 the player has been recently. It is used by monsters for pursuit. 32 33 .origin the spot 34 .owner forward link 35 .aiment backward link 36 */ 37 38 39 #define TRAIL_LENGTH 8 40 41 edict_t *trail[TRAIL_LENGTH]; 42 int trail_head; 43 qboolean trail_active = false; 44 45 #define NEXT(n) (((n) + 1) & (TRAIL_LENGTH - 1)) 46 #define PREV(n) (((n) - 1) & (TRAIL_LENGTH - 1)) 47 48 49 void PlayerTrail_Init (void) 50 { 51 int n; 52 53 if (deathmatch->value /* FIXME || coop */) 54 return; 55 56 for (n = 0; n < TRAIL_LENGTH; n++) 57 { 58 trail[n] = G_Spawn(); 59 trail[n]->classname = "player_trail"; 60 } 61 62 trail_head = 0; 63 trail_active = true; 64 } 65 66 67 void PlayerTrail_Add (vec3_t spot) 68 { 69 vec3_t temp; 70 71 if (!trail_active) 72 return; 73 74 VectorCopy (spot, trail[trail_head]->s.origin); 75 76 trail[trail_head]->timestamp = level.time; 77 78 VectorSubtract (spot, trail[PREV(trail_head)]->s.origin, temp); 79 trail[trail_head]->s.angles[1] = vectoyaw (temp); 80 81 trail_head = NEXT(trail_head); 82 } 83 84 85 void PlayerTrail_New (vec3_t spot) 86 { 87 if (!trail_active) 88 return; 89 90 PlayerTrail_Init (); 91 PlayerTrail_Add (spot); 92 } 93 94 95 edict_t *PlayerTrail_PickFirst (edict_t *self) 96 { 97 int marker; 98 int n; 99 100 if (!trail_active) 101 return NULL; 102 103 for (marker = trail_head, n = TRAIL_LENGTH; n; n--) 104 { 105 if(trail[marker]->timestamp <= self->monsterinfo.trail_time) 106 marker = NEXT(marker); 107 else 108 break; 109 } 110 111 if (visible(self, trail[marker])) 112 { 113 return trail[marker]; 114 } 115 116 if (visible(self, trail[PREV(marker)])) 117 { 118 return trail[PREV(marker)]; 119 } 120 121 return trail[marker]; 122 } 123 124 edict_t *PlayerTrail_PickNext (edict_t *self) 125 { 126 int marker; 127 int n; 128 129 if (!trail_active) 130 return NULL; 131 132 for (marker = trail_head, n = TRAIL_LENGTH; n; n--) 133 { 134 if(trail[marker]->timestamp <= self->monsterinfo.trail_time) 135 marker = NEXT(marker); 136 else 137 break; 138 } 139 140 return trail[marker]; 141 } 142 143 edict_t *PlayerTrail_LastSpot (void) 144 { 145 return trail[PREV(trail_head)]; 146 }