File: game\p_trail.c

    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 }
  147