/** * @brief Get the weapon firing TUs of the item in the right hand of the edict. * @return -1 if no firedef was found for the item or the reaction fire mode is not activated for the right hand. * @todo why only right hand? * @param[in] ent The reaction firing actor * @param[in] target The target to check reaction fire for (e.g. check whether the weapon that was marked for * using in reaction fire situations can handle the distance between the shooter and the target) * @param[in] invList The items that are checked for reaction fire * @note This does 'not' return the weapon (lowest TU costs, highest damage, highest accuracy) but the first weapon that * would fit for reaction fire. */ static int G_ReactionFireGetTUsForItem (const edict_t *ent, const edict_t *target, const invList_t *invList) { if (invList && invList->item.m && invList->item.t->weapon && (!invList->item.t->reload || invList->item.a > 0)) { const fireDef_t *fdArray = FIRESH_FiredefForWeapon(&invList->item); const chrFiremodeSettings_t *fmSetting; if (fdArray == NULL) return -1; fmSetting = &ent->chr.RFmode; if (fmSetting->hand == ACTOR_HAND_RIGHT && fmSetting->fmIdx >= 0 && fmSetting->fmIdx < MAX_FIREDEFS_PER_WEAPON) { /* If a RIGHT-hand firemode is selected and sane. */ const fireDefIndex_t fmIdx = fmSetting->fmIdx; const int reactionFire = G_PLAYER_FROM_ENT(ent)->reactionLeftover; const fireDef_t *fd = &fdArray[fmIdx]; const int tus = fd->time + reactionFire; if (tus <= ent->TU && fd->range > VectorDist(ent->origin, target->origin)) { return tus; } } } return -1; }
/** * @brief Shoots the actor. */ static int actorL_shoot (lua_State *L) { int tu, shots; shoot_types_t shootType; const item_t *item; const fireDef_t *fdArray; assert(lua_isactor(L, 1)); /* Target */ aiActor_t *target = lua_toactor(L, 1); /* Number of TU to spend shooting, fire mode will adjust to that. */ if (lua_gettop(L) > 1) { assert(lua_isnumber(L, 2)); /* Must be a number. */ tu = (int) lua_tonumber(L, 2); } else { tu = G_ActorUsableTUs(AIL_ent); } shootType = ST_RIGHT; item = AI_GetItemForShootType(shootType, AIL_ent); if (item == NULL) { shootType = ST_LEFT; item = AI_GetItemForShootType(shootType, AIL_ent); } /* Failure - no weapon. */ if (item == NULL) { lua_pushboolean(L, 0); return 1; } /** @todo Choose fire mode based on TU available - currently the first one is used. */ fdArray = FIRESH_FiredefForWeapon(item); if (fdArray == NULL) { /* Failure - no weapon. */ lua_pushboolean(L, 0); return 1; } shots = tu / G_GetActorTimeForFiredef(AIL_ent, fdArray, false); while (shots > 0) { shots--; /** @todo actually handle fire modes */ G_ClientShoot(AIL_player, AIL_ent, target->ent->pos, shootType, 0, NULL, true, 0); } /* Success. */ lua_pushboolean(L, 1); return 1; }
/** * @brief Returns the fire definition of the item the actor has in the given hand. * @param[in] actor The pointer to the actor we want to get the data from. * @param[in] hand Which hand to use * @return the used @c fireDef_t */ const fireDef_t *HUD_GetFireDefinitionForHand (const le_t * actor, const actorHands_t hand) { const invList_t *invlistWeapon; if (!actor) return NULL; invlistWeapon = ACTOR_GET_INV(actor, hand); if (!invlistWeapon || !invlistWeapon->item.t) return NULL; return FIRESH_FiredefForWeapon(&invlistWeapon->item); }
/** * @brief Checks if the currently selected firemode is usable with the defined weapon. * @param[in] actor The actor to check the firemode for. */ static bool G_ActorHasWorkingFireModeSet (const edict_t *actor) { const FiremodeSettings *fmSettings = &actor->chr.RFmode; if (!fmSettings->isSaneFiremode()) /* just checks for valid values */ return false; const invList_t* invList = ACTOR_GET_INV(actor, fmSettings->getHand()); if (!invList) return false; const fireDef_t *fd = FIRESH_FiredefForWeapon(&invList->item); if (fd == NULL) return false; if (fd->obj->weapons[fd->weapFdsIdx] == fmSettings->weapon && fmSettings->fmIdx < fd->obj->numFiredefs[fd->weapFdsIdx]) { return true; } return false; }
/** * @brief Checks if the currently selected firemode is usable with the defined weapon. * @param[in] actor The actor to check the firemode for. */ static bool G_ActorHasWorkingFireModeSet (const edict_t *actor) { const fireDef_t *fd; const chrFiremodeSettings_t *fmSettings = &actor->chr.RFmode; const invList_t* invList; if (!SANE_FIREMODE(fmSettings)) return false; invList = ACTOR_GET_INV(actor, fmSettings->hand); if (!invList) return false; fd = FIRESH_FiredefForWeapon(&invList->item); if (fd == NULL) return false; if (fd->obj->weapons[fd->weapFdsIdx] == fmSettings->weapon && fmSettings->fmIdx < fd->obj->numFiredefs[fd->weapFdsIdx]) { return true; } return false; }