e_time.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "../../client.h"
00027 #include "../cl_localentity.h"
00028 #include "e_time.h"
00029 #include "e_main.h"
00030 
00032 #define OLDEVENTTIME
00033 
00034 #ifdef OLDEVENTTIME
00035 
00036 static int nextTime;    
00037 static int shootTime;   
00038 static int impactTime;  
00039 static qboolean parsedDeath;    
00040 #endif
00041 
00049 int CL_GetEventTime (const event_t eType, struct dbuffer *msg, const int dt)
00050 {
00051     const eventRegister_t *eventData = CL_GetEvent(eType);
00052 
00053 #ifdef OLDEVENTTIME
00054     /* the time the event should be executed. This value is used to sort the
00055      * event chain to determine which event must be executed at first. This
00056      * value also ensures, that the events are executed in the correct
00057      * order. E.g. @c impactTime is used to delay some events in case the
00058      * projectile needs some time to reach its target. */
00059     int eventTime;
00060 
00061     if (eType == EV_RESET) {
00062         parsedDeath = qfalse;
00063         nextTime = 0;
00064         shootTime = 0;
00065         impactTime = 0;
00066     } else if (eType == EV_ACTOR_DIE)
00067         parsedDeath = qtrue;
00068 
00069     /* get event time */
00070     if (nextTime < cl.time)
00071         nextTime = cl.time;
00072     if (impactTime < cl.time)
00073         impactTime = cl.time;
00074 
00075     if (eType == EV_ACTOR_DIE || eType == EV_MODEL_EXPLODE)
00076         eventTime = impactTime;
00077     else if (eType == EV_ACTOR_SHOOT || eType == EV_ACTOR_SHOOT_HIDDEN)
00078         eventTime = shootTime;
00079     else if (eType == EV_RESULTS)
00080         eventTime = nextTime + 1400;
00081     else
00082         eventTime = nextTime;
00083 
00084     if (eType == EV_ENT_APPEAR || eType == EV_INV_ADD || eType == EV_PARTICLE_APPEAR || eType == EV_PARTICLE_SPAWN) {
00085         if (parsedDeath) { /* drop items after death (caused by impact) */
00086             eventTime = impactTime + 400;
00087             /* EV_INV_ADD messages are the last events sent after a death */
00088             if (eType == EV_INV_ADD)
00089                 parsedDeath = qfalse;
00090         } else if (impactTime > cl.time) { /* item thrown on the ground */
00091             eventTime = impactTime + 75;
00092         }
00093     }
00094 
00095     /* calculate time interval before the next event */
00096     switch (eType) {
00097     case EV_ACTOR_APPEAR:
00098         if (cl.actTeam != cls.team)
00099             nextTime += 600;
00100         break;
00101     case EV_INV_RELOAD:
00102         /* let the reload sound play */
00103         nextTime += 600;
00104         break;
00105     case EV_ACTOR_START_SHOOT:
00106         nextTime += 300;
00107         shootTime = nextTime;
00108         break;
00109     case EV_ACTOR_SHOOT_HIDDEN:
00110         {
00111             int first;
00112             int objIdx;
00113             const objDef_t *obj;
00114             weaponFireDefIndex_t weapFdsIdx;
00115             fireDefIndex_t fireDefIndex;
00116 
00117             NET_ReadFormat(msg, eventData->formatString, &first, &objIdx, &weapFdsIdx, &fireDefIndex);
00118 
00119             obj = INVSH_GetItemByIDX(objIdx);
00120             if (first) {
00121                 nextTime += 500;
00122                 impactTime = shootTime = nextTime;
00123             } else {
00124                 const fireDef_t *fd = FIRESH_GetFiredef(obj, weapFdsIdx, fireDefIndex);
00125                 /* impact right away - we don't see it at all
00126                  * bouncing is not needed here, too (we still don't see it) */
00127                 impactTime = shootTime;
00128                 nextTime = shootTime + 1400;
00129                 if (fd->delayBetweenShots)
00130                     shootTime += 1000 / fd->delayBetweenShots;
00131             }
00132             parsedDeath = qfalse;
00133         }
00134         break;
00135     case EV_ACTOR_MOVE:
00136         {
00137             le_t *le;
00138             int number, i;
00139             int time = 0;
00140             int pathLength;
00141             byte crouchingState;
00142             pos3_t pos, oldPos;
00143 
00144             number = NET_ReadShort(msg);
00145             /* get le */
00146             le = LE_Get(number);
00147             if (!le)
00148                 LE_NotFoundError(number);
00149 
00150             pathLength = NET_ReadByte(msg);
00151 
00152             /* Also skip the final position */
00153             NET_ReadByte(msg);
00154             NET_ReadByte(msg);
00155             NET_ReadByte(msg);
00156 
00157             VectorCopy(le->pos, pos);
00158             crouchingState = LE_IsCrouched(le) ? 1 : 0;
00159 
00160             for (i = 0; i < pathLength; i++) {
00161                 const byte fulldv = NET_ReadByte(msg);
00162                 const byte dir = getDVdir(fulldv);
00163                 VectorCopy(pos, oldPos);
00164                 PosAddDV(pos, crouchingState, fulldv);
00165                 time += LE_ActorGetStepTime(le, pos, oldPos, dir, NET_ReadShort(msg));
00166                 NET_ReadShort(msg);
00167             }
00168             nextTime += time + 400;
00169         }
00170         break;
00171     case EV_ACTOR_SHOOT:
00172         {
00173             const fireDef_t *fd;
00174             int flags, dummy;
00175             int objIdx, surfaceFlags;
00176             objDef_t *obj;
00177             int weap_fds_idx, fd_idx;
00178             shoot_types_t shootType;
00179             vec3_t muzzle, impact;
00180 
00181             /* read data */
00182             NET_ReadFormat(msg, eventData->formatString, &dummy, &dummy, &dummy, &objIdx, &weap_fds_idx, &fd_idx, &shootType, &flags, &surfaceFlags, &muzzle, &impact, &dummy);
00183 
00184             obj = INVSH_GetItemByIDX(objIdx);
00185             fd = FIRESH_GetFiredef(obj, weap_fds_idx, fd_idx);
00186 
00187             if (!(flags & SF_BOUNCED)) {
00188                 /* shooting */
00189                 if (fd->speed && !CL_OutsideMap(impact, UNIT_SIZE * 10)) {
00190                     impactTime = shootTime + 1000 * VectorDist(muzzle, impact) / fd->speed;
00191                 } else {
00192                     impactTime = shootTime;
00193                 }
00194                 if (cl.actTeam != cls.team)
00195                     nextTime = impactTime + 1400;
00196                 else
00197                     nextTime = impactTime + 400;
00198                 if (fd->delayBetweenShots)
00199                     shootTime += 1000 / fd->delayBetweenShots;
00200             } else {
00201                 /* only a bounced shot */
00202                 eventTime = impactTime;
00203                 if (fd->speed) {
00204                     impactTime += 1000 * VectorDist(muzzle, impact) / fd->speed;
00205                     nextTime = impactTime;
00206                 }
00207             }
00208             parsedDeath = qfalse;
00209         }
00210         break;
00211     case EV_ACTOR_THROW:
00212         nextTime += NET_ReadShort(msg);
00213         impactTime = shootTime = nextTime;
00214         parsedDeath = qfalse;
00215         break;
00216     default:
00217         break;
00218     }
00219 
00220     Com_DPrintf(DEBUG_EVENTSYS, "%s => eventTime: %i, nextTime: %i, impactTime: %i, shootTime: %i\n",
00221             eventData->name, eventTime, nextTime, impactTime, shootTime);
00222 
00223     return eventTime;
00224 #else
00225     if (!eventData->timeCallback)
00226         return cl.time;
00227 
00228     return eventData->timeCallback(eventData, msg, dt);
00229 #endif
00230 }

Generated by  doxygen 1.6.2