e_event_actorshoot.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2002-2010 UFO: Alien Invasion.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "../../../../client.h"
00026 #include "../../../cl_localentity.h"
00027 #include "../../../cl_actor.h"
00028 #include "../../../cl_particle.h"
00029 #include "../../../../renderer/r_mesh.h"
00030 #include "../../../../renderer/r_mesh_anim.h"
00031 #include "e_event_actorshoot.h"
00032 
00033 int CL_ActorDoShootTime (const eventRegister_t *self, struct dbuffer *msg, const int dt)
00034 {
00035 #if 0
00036     const fireDef_t *fd;
00037     static int impactTime;
00038     int flags, dummy;
00039     int objIdx, surfaceFlags;
00040     objDef_t *obj;
00041     int weap_fds_idx, fd_idx;
00042     shoot_types_t shootType;
00043     vec3_t muzzle, impact;
00044 
00045     if (impactTime < cl.time)
00046         impactTime = cl.time;
00047 
00048     /* read data */
00049     NET_ReadFormat(msg, self->formatString, &dummy, &dummy, &objIdx, &weap_fds_idx, &fd_idx, &shootType, &flags, &surfaceFlags, &muzzle, &impact, &dummy);
00050 
00051     obj = INVSH_GetItemByIDX(objIdx);
00052     fd = FIRESH_GetFiredef(obj, weap_fds_idx, fd_idx);
00053 
00054     if (!(flags & SF_BOUNCED)) {
00055         /* shooting */
00056         if (fd->speed && !CL_OutsideMap(impact, UNIT_SIZE * 10)) {
00057             impactTime = shootTime + 1000 * VectorDist(muzzle, impact) / fd->speed;
00058         } else {
00059             impactTime = shootTime;
00060         }
00061         if (cl.actTeam != cls.team)
00062             nextTime = impactTime + 1400;
00063         else
00064             nextTime = impactTime + 400;
00065         if (fd->delayBetweenShots)
00066             shootTime += 1000 / fd->delayBetweenShots;
00067     } else {
00068         /* only a bounced shot */
00069         eventTime = impactTime;
00070         if (fd->speed) {
00071             impactTime += 1000 * VectorDist(muzzle, impact) / fd->speed;
00072             nextTime = impactTime;
00073         }
00074     }
00075 #else
00076     return cl.time;
00077 #endif
00078 }
00079 
00090 static void CL_ActorGetMuzzle (const le_t* actor, vec3_t muzzle, shoot_types_t shootType)
00091 {
00092     const struct model_s *model;
00093     const char *tag;
00094     const float *shooterTag, *muzzleTag;
00095     float matrix[16], mc[16], modifiedMatrix[16];
00096     const objDef_t* od;
00097     const invList_t *invlistWeapon;
00098 
00099     if (actor == NULL)
00100         return;
00101 
00102     if (IS_SHOT_RIGHT(shootType)) {
00103         tag = "tag_rweapon";
00104         invlistWeapon = RIGHT(actor);
00105     } else {
00106         tag = "tag_lweapon";
00107         invlistWeapon = LEFT(actor);
00108     }
00109 
00110     if (!invlistWeapon || !invlistWeapon->item.t)
00111         return;
00112 
00113     od = invlistWeapon->item.t;
00114 
00115     model = cls.modelPool[od->idx];
00116     if (!model)
00117         Com_Error(ERR_DROP, "Model for item %s is not precached", od->id);
00118 
00119     /* not every weapon has a muzzle tag assigned */
00120     muzzleTag = R_GetTagMatrix(model, "tag_muzzle");
00121     if (!muzzleTag)
00122         return;
00123 
00124     shooterTag = R_GetTagMatrix(actor->model1, tag);
00125     if (!shooterTag)
00126         Com_Error(ERR_DROP, "Could not find tag %s for actor model %s", tag, actor->model1->name);
00127 
00128     GLMatrixAssemble(actor->origin, actor->angles, mc);
00129 
00130     memcpy(modifiedMatrix, shooterTag, sizeof(modifiedMatrix));
00131     modifiedMatrix[12] = -modifiedMatrix[12];
00132     GLMatrixMultiply(mc, modifiedMatrix, matrix);
00133 
00134     memcpy(modifiedMatrix, muzzleTag, sizeof(modifiedMatrix));
00135     modifiedMatrix[12] = -modifiedMatrix[12];
00136     GLMatrixMultiply(matrix, modifiedMatrix, mc);
00137 
00138     muzzle[0] = mc[12];
00139     muzzle[1] = mc[13];
00140     muzzle[2] = mc[14];
00141 }
00142 
00150 void CL_ActorDoShoot (const eventRegister_t *self, struct dbuffer *msg)
00151 {
00152     const fireDef_t *fd;
00153     le_t *leShooter, *leVictim;
00154     vec3_t muzzle, impact;
00155     int flags, normal, shooterEntnum, victimEntnum;
00156     int objIdx;
00157     int first;
00158     const objDef_t *obj;
00159     weaponFireDefIndex_t weapFdsIdx;
00160     fireDefIndex_t fdIdx;
00161     int surfaceFlags;
00162     shoot_types_t shootType;
00163 
00164     /* read data */
00165     NET_ReadFormat(msg, self->formatString, &shooterEntnum, &victimEntnum, &first, &objIdx, &weapFdsIdx, &fdIdx, &shootType, &flags, &surfaceFlags, &muzzle, &impact, &normal);
00166 
00167     if (victimEntnum != SKIP_LOCAL_ENTITY) {
00168         leVictim = LE_Get(victimEntnum);
00169         if (!leVictim)
00170             LE_NotFoundError(victimEntnum);
00171     } else {
00172         leVictim = NULL;
00173     }
00174 
00175     /* get shooter le */
00176     leShooter = LE_Get(shooterEntnum);
00177 
00178     /* get the fire def */
00179     obj = INVSH_GetItemByIDX(objIdx);
00180     fd = FIRESH_GetFiredef(obj, weapFdsIdx, fdIdx);
00181 
00182     CL_ActorGetMuzzle(leShooter, muzzle, shootType);
00183 
00184     /* add effect le */
00185     LE_AddProjectile(fd, flags, muzzle, impact, normal, leVictim);
00186 
00187     /* start the sound */
00188     if ((first || !fd->soundOnce) && fd->fireSound[0] && !(flags & SF_BOUNCED))
00189         S_PlaySample(muzzle, S_LoadSample(fd->fireSound), fd->fireAttenuation, SND_VOLUME_WEAPONS);
00190 
00191     if (fd->irgoggles)
00192         refdef.rendererFlags |= RDF_IRGOGGLES;
00193 
00194     /* do actor related stuff */
00195     if (!leShooter)
00196         return; /* maybe hidden or inuse is false? */
00197 
00198     if (!LE_IsActor(leShooter))
00199         Com_Error(ERR_DROP, "Can't shoot, LE not an actor (type: %i)", leShooter->type);
00200 
00201     /* no animations for hidden actors */
00202     if (leShooter->type == ET_ACTORHIDDEN)
00203         return;
00204 
00205     if (LE_IsDead(leShooter)) {
00206         Com_DPrintf(DEBUG_CLIENT, "Can't shoot, actor dead or stunned.\n");
00207         return;
00208     }
00209 
00210     /* Animate - we have to check if it is right or left weapon usage. */
00211     if (IS_SHOT_RIGHT(shootType)) {
00212         R_AnimChange(&leShooter->as, leShooter->model1, LE_GetAnim("shoot", leShooter->right, leShooter->left, leShooter->state));
00213         R_AnimAppend(&leShooter->as, leShooter->model1, LE_GetAnim("stand", leShooter->right, leShooter->left, leShooter->state));
00214     } else if (IS_SHOT_LEFT(shootType)) {
00215         R_AnimChange(&leShooter->as, leShooter->model1, LE_GetAnim("shoot", leShooter->left, leShooter->right, leShooter->state));
00216         R_AnimAppend(&leShooter->as, leShooter->model1, LE_GetAnim("stand", leShooter->left, leShooter->right, leShooter->state));
00217     } else if (!IS_SHOT_HEADGEAR(shootType)) {
00218         /* no animation for headgear (yet) */
00219         Com_Error(ERR_DROP, "CL_ActorDoShoot: Invalid shootType given (entnum: %i, shootType: %i).\n", shootType, shooterEntnum);
00220     }
00221 }

Generated by  doxygen 1.6.2