/** * @brief Starts shooting with actor. * @param[in] self Pointer to the event structure that is currently executed * @param[in] msg The netchannel message * @sa CL_ActorShootHidden * @sa CL_ActorShoot * @sa CL_ActorDoShoot * @todo Improve detection of left- or right animation. * @sa EV_ACTOR_START_SHOOT */ void CL_ActorStartShoot (const eventRegister_t *self, dbuffer *msg) { le_t *le; pos3_t from, target; int entnum; shoot_types_t shootType; NET_ReadFormat(msg, self->formatString, &entnum, &shootType, &from, &target); /* shooting actor */ le = LE_Get(entnum); /* center view (if wanted) */ if (cl.actTeam != cls.team) CL_CameraRoute(from, target); /* actor dependent stuff following */ if (!le) /* it's OK, the actor is not visible */ return; if (!LE_IsLivingActor(le) || LE_IsStunned(le)) { Com_Printf("CL_ActorStartShoot: LE (%i) not a living actor (type: %i)\n", entnum, le->type); return; } /* ET_ACTORHIDDEN actors don't have a model yet */ if (le->type == ET_ACTORHIDDEN) return; /* Animate - we have to check if it is right or left weapon usage. */ if (IS_SHOT_RIGHT(shootType)) { R_AnimChange(&le->as, le->model1, LE_GetAnim("move", le->right, le->left, le->state)); } else if (IS_SHOT_LEFT(shootType)) { R_AnimChange(&le->as, le->model1, LE_GetAnim("move", le->left, le->right, le->state)); } else if (!IS_SHOT_HEADGEAR(shootType)) { /* no animation for headgear (yet) */ Com_Error(ERR_DROP, "CL_ActorStartShoot: Invalid shootType given (entnum: %i, shootType: %i).\n", shootType, entnum); } }
/** * @brief Shoot with weapon. * @sa CL_ActorShoot * @sa CL_ActorShootHidden * @todo Improve detection of left- or right animation. * @sa EV_ACTOR_SHOOT */ void CL_ActorDoShoot (const eventRegister_t* self, dbuffer* msg) { vec3_t muzzle, impact; int flags, normal, shooterEntnum, victimEntnum; int objIdx; int first; weaponFireDefIndex_t weapFdsIdx; fireDefIndex_t fdIdx; int surfaceFlags; shoot_types_t shootType; /* read data */ NET_ReadFormat(msg, self->formatString, &shooterEntnum, &victimEntnum, &first, &objIdx, &weapFdsIdx, &fdIdx, &shootType, &flags, &surfaceFlags, &muzzle, &impact, &normal); le_t* leVictim; if (victimEntnum != SKIP_LOCAL_ENTITY) { leVictim = LE_Get(victimEntnum); if (!leVictim) LE_NotFoundError(victimEntnum); } else { leVictim = nullptr; } /* get shooter le */ le_t* leShooter = LE_Get(shooterEntnum); /* get the fire def */ const objDef_t* obj = INVSH_GetItemByIDX(objIdx); const fireDef_t* fd = FIRESH_GetFiredef(obj, weapFdsIdx, fdIdx); CL_ActorGetMuzzle(leShooter, muzzle, shootType); /* add effect le */ LE_AddProjectile(fd, flags, muzzle, impact, normal, leVictim); /* start the sound */ if ((first || !fd->soundOnce) && fd->fireSound != nullptr && !(flags & SF_BOUNCED)) S_LoadAndPlaySample(fd->fireSound, muzzle, fd->fireAttenuation, SND_VOLUME_WEAPONS); /* do actor related stuff */ if (!leShooter) return; /* maybe hidden or inuse is false? */ if (!LE_IsActor(leShooter)) Com_Error(ERR_DROP, "Can't shoot, LE not an actor (type: %i)", leShooter->type); /* no animations for hidden actors */ if (leShooter->type == ET_ACTORHIDDEN) return; if (LE_IsDead(leShooter)) { Com_DPrintf(DEBUG_CLIENT, "Can't shoot, actor dead or stunned.\n"); return; } /* Animate - we have to check if it is right or left weapon usage. */ if (IS_SHOT_RIGHT(shootType)) { R_AnimChange(&leShooter->as, leShooter->model1, LE_GetAnim("shoot", leShooter->right, leShooter->left, leShooter->state)); R_AnimAppend(&leShooter->as, leShooter->model1, LE_GetAnim("stand", leShooter->right, leShooter->left, leShooter->state)); } else if (IS_SHOT_LEFT(shootType)) { R_AnimChange(&leShooter->as, leShooter->model1, LE_GetAnim("shoot", leShooter->left, leShooter->right, leShooter->state)); R_AnimAppend(&leShooter->as, leShooter->model1, LE_GetAnim("stand", leShooter->left, leShooter->right, leShooter->state)); } else if (IS_SHOT_HEADGEAR(shootType)) { if (fd->irgoggles) { leShooter->state |= RF_IRGOGGLESSHOT; if (LE_IsSelected(leShooter)) refdef.rendererFlags |= RDF_IRGOGGLES; } } else { /* no animation for headgear (yet) */ Com_Error(ERR_DROP, "CL_ActorDoShoot: Invalid shootType given (entnum: %i, shootType: %i).\n", shootType, shooterEntnum); } }