Exemple #1
0
/**
 * @param ent The actor to set the reaction fire for
 * @return @c true if the needed settings could have been made or settings are
 * already valid, @c false otherwise.
 */
static bool G_ReactionFireSetDefault (edict_t *ent)
{
	const objDef_t *weapon;
	const invList_t *invList;
	actorHands_t hand = ACTOR_HAND_RIGHT;

	if (G_ActorHasWorkingFireModeSet(ent))
		return true;

	invList = ACTOR_GET_INV(ent, hand);
	if (!invList) {
		hand = ACTOR_HAND_LEFT;
		invList = ACTOR_GET_INV(ent, hand);
	}

	weapon = INVSH_HasReactionFireEnabledWeapon(invList);
	if (!weapon)
		return false;

	ent->chr.RFmode.fmIdx = 0;
	ent->chr.RFmode.hand = hand;
	ent->chr.RFmode.weapon = weapon;

	if (!G_IsAI(ent))
		G_EventReactionFireChange(ent);

	return true;
}
Exemple #2
0
/**
 * @param ent The actor to set the reaction fire for
 * @return @c true if the needed settings could have been made or settings are
 * already valid, @c false otherwise.
 */
static bool G_ReactionFireSetDefault (edict_t *ent)
{
	if (G_ActorHasWorkingFireModeSet(ent))
		return true;

	actorHands_t hand = ACTOR_HAND_RIGHT;
	const invList_t *invList = ACTOR_GET_INV(ent, hand);
	if (!invList) {
		hand = ACTOR_HAND_LEFT;
		invList = ACTOR_GET_INV(ent, hand);
	}

	const objDef_t *weapon = INVSH_HasReactionFireEnabledWeapon(invList);
	if (!weapon)
		return false;

	ent->chr.RFmode.set(hand, 0, weapon);	/* no special firemode */

	if (!G_ActorHasWorkingFireModeSet(ent))
		return false;

	if (!G_IsAI(ent))
		G_EventReactionFireChange(ent);

	return true;
}
Exemple #3
0
/**
 * @brief Check whether ent can reaction fire at target, i.e. that it can see it and neither is dead etc.
 * @param[in] ent The entity that might be firing
 * @param[in] target The entity that might be fired at
 * @return @c true if 'ent' can actually fire at 'target', @c false otherwise
 */
static bool G_ReactionFireIsPossible (const edict_t *ent, const edict_t *target)
{
	float actorVis;
	bool frustum;

	/* an entity can't reaction fire at itself */
	if (ent == target)
		return false;

	/* Don't react in your own turn */
	if (ent->team == level.activeTeam)
		return false;

	/* ent can't use RF if is in STATE_DAZED (flashbang impact) */
	if (G_IsDazed(ent))
		return false;

	if (G_IsDead(target))
		return false;

	/* check ent has reaction fire enabled */
	if (!G_IsShaken(ent) && !G_IsReaction(ent))
		return false;

	/* check ent has weapon in RF hand */
	/* @todo Should this situation even happen when G_IsReaction(ent) is true? */
	if (!ACTOR_GET_INV(ent, ent->chr.RFmode.hand)) {
		/* print character info if this happens, for now */
		gi.DPrintf("Reaction fire enabled but no weapon for hand (name=%s,hand=%i,fmIdx=%i)\n",
				ent->chr.name, ent->chr.RFmode.hand, ent->chr.RFmode.fmIdx);
		return false;
	}

	if (!G_IsVisibleForTeam(target, ent->team))
		return false;

	/* If reaction fire is triggered by a friendly unit
	 * and the shooter is still sane, don't shoot;
	 * well, if the shooter isn't sane anymore... */
	if (G_IsCivilian(target) || target->team == ent->team)
		if (!G_IsShaken(ent) || (float) ent->morale / mor_shaken->value > frand())
			return false;

	/* check in range and visible */
	if (VectorDistSqr(ent->origin, target->origin) > MAX_SPOT_DIST * MAX_SPOT_DIST)
		return false;

	frustum = G_FrustumVis(ent, target->origin);
	if (!frustum)
		return false;

	actorVis = G_ActorVis(ent->origin, ent, target, true);
	if (actorVis <= 0.2)
		return false;

	/* okay do it then */
	return true;
}
Exemple #4
0
/**
 * @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);
}
Exemple #5
0
/**
 * @brief Starts aiming/target mode for selected left/right firemode.
 * @note Previously know as a combination of CL_FireRightPrimary, CL_FireRightSecondary,
 * @note CL_FireLeftPrimary and CL_FireLeftSecondary.
 */
static void HUD_FireWeapon_f (void)
{
	actorHands_t hand;
	fireDefIndex_t firemode;
	const objDef_t *ammo;
	const fireDef_t *fd;

	if (Cmd_Argc() < 3) { /* no argument given */
		Com_Printf("Usage: %s <l|r> <firemode number>\n", Cmd_Argv(0));
		return;
	}

	if (!selActor)
		return;

	hand = ACTOR_GET_HAND_INDEX(Cmd_Argv(1)[0]);
	firemode = atoi(Cmd_Argv(2));
	if (firemode >= MAX_FIREDEFS_PER_WEAPON || firemode < 0)
		return;

	fd = HUD_GetFireDefinitionForHand(selActor, hand);
	if (fd == NULL)
		return;

	ammo = fd->obj;

	/* Let's check if shooting is possible. */
	if (!HUD_CheckShooting(selActor, ACTOR_GET_INV(selActor, hand)))
		return;

	if (ammo->fd[fd->weapFdsIdx][firemode].time <= CL_ActorUsableTUs(selActor)) {
		/* Actually start aiming. This is done by changing the current mode of display. */
		if (hand == ACTOR_HAND_RIGHT)
			CL_ActorSetMode(selActor, M_FIRE_R);
		else
			CL_ActorSetMode(selActor, M_FIRE_L);
		/* Store firemode. */
		selActor->currentSelectedFiremode = firemode;
	} else {
		/* Cannot shoot because of not enough TUs - every other
		 * case should be checked previously in this function. */
		HUD_DisplayMessage(_("Can't perform action:\nnot enough TUs.\n"));
	}
}
Exemple #6
0
/**
 * @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;
}
Exemple #7
0
/**
 * @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;
}