00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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
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
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
00176 leShooter = LE_Get(shooterEntnum);
00177
00178
00179 obj = INVSH_GetItemByIDX(objIdx);
00180 fd = FIRESH_GetFiredef(obj, weapFdsIdx, fdIdx);
00181
00182 CL_ActorGetMuzzle(leShooter, muzzle, shootType);
00183
00184
00185 LE_AddProjectile(fd, flags, muzzle, impact, normal, leVictim);
00186
00187
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
00195 if (!leShooter)
00196 return;
00197
00198 if (!LE_IsActor(leShooter))
00199 Com_Error(ERR_DROP, "Can't shoot, LE not an actor (type: %i)", leShooter->type);
00200
00201
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
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
00219 Com_Error(ERR_DROP, "CL_ActorDoShoot: Invalid shootType given (entnum: %i, shootType: %i).\n", shootType, shooterEntnum);
00220 }
00221 }