Ejemplo n.º 1
0
/**
 * @brief Check if reload is possible.
 * @param[in] le Pointer to local entity for which we handle an action on hud menu.
 * @param[in] weapon An item in hands.
 * @param[in] container The container to get the ammo from
 * @return qfalse when action is not possible, otherwise qtrue
 * @sa HUD_ReloadLeft_f
 * @sa HUD_ReloadRight_f
 */
static qboolean HUD_CheckReload (const le_t* le, const invList_t *weapon, containerIndex_t container)
{
	int tus;

	if (!le)
		return qfalse;

	/* No item in hand. */
	if (!weapon || !weapon->item.t) {
		HUD_DisplayMessage(_("No item in hand.\n"));
		return qfalse;
	}

	/* Cannot reload because this item is not reloadable. */
	if (!weapon->item.t->reload) {
		HUD_DisplayMessage(_("Can't perform action:\nthis item is not reloadable.\n"));
		return qfalse;
	}

	tus = HUD_CalcReloadTime(le, weapon->item.t, container);
	/* Cannot reload because of no ammo in inventory. */
	if (tus == -1) {
		HUD_DisplayMessage(_("Can't perform action:\nammo not available.\n"));
		return qfalse;
	}
	/* Cannot reload because of not enough TUs. */
	if (le->TU < tus) {
		HUD_DisplayMessage(_("Can't perform action:\nnot enough TUs.\n"));
		return qfalse;
	}

	return qtrue;
}
Ejemplo n.º 2
0
/**
 * @brief Check if shooting is possible.
 * i.e. The weapon has ammo and can be fired with the 'available' hands.
 * TUs (i.e. "time") are are _not_ checked here, this needs to be done
 * elsewhere for the correct firemode.
 * @sa HUD_FireWeapon_f
 * @return qfalse when action is not possible, otherwise qtrue
 */
static qboolean HUD_CheckShooting (const le_t* le, invList_t *weapon)
{
	if (!le)
		return qfalse;

	/* No item in hand. */
	if (!weapon || !weapon->item.t) {
		HUD_DisplayMessage(_("No item in hand.\n"));
		return qfalse;
	}

	/* Cannot shoot because of lack of ammo. */
	if (weapon->item.a <= 0 && weapon->item.t->reload) {
		HUD_DisplayMessage(_("Can't perform action:\nout of ammo.\n"));
		return qfalse;
	}
	/* Cannot shoot because weapon is fireTwoHanded, yet both hands handle items. */
	if (weapon->item.t->fireTwoHanded && LEFT(le)) {
		HUD_DisplayMessage(_("This weapon cannot be fired\none handed.\n"));
		return qfalse;
	}

	return qtrue;
}
Ejemplo n.º 3
0
/**
 * @brief Finishes the current turn of the player in battlescape and starts the turn for the next team.
 */
static void CL_NextRound_f (void)
{
	/* can't end round if we are not in battlescape */
	if (!CL_BattlescapeRunning())
		return;

	/* can't end round if we're not active */
	if (!cls.isOurRound()) {
		HUD_DisplayMessage(_("It is not your turn!"));
		return;
	}

	/* send endround */
	dbuffer msg;
	NET_WriteByte(&msg, clc_endround);
	NET_WriteMsg(cls.netStream, msg);
}
Ejemplo n.º 4
0
/**
 * @brief Finishes the current round of the player in battlescape and starts the round for the next team.
 */
static void CL_NextRound_f (void)
{
	struct dbuffer *msg;
	/* can't end round if we are not in battlescape */
	if (!CL_BattlescapeRunning())
		return;

	/* can't end round if we're not active */
	if (cls.team != cl.actTeam) {
		HUD_DisplayMessage(_("This isn't your round"));
		return;
	}

	/* send endround */
	msg = new_dbuffer();
	NET_WriteByte(msg, clc_endround);
	NET_WriteMsg(cls.netStream, msg);
}
Ejemplo n.º 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"));
	}
}
Ejemplo n.º 6
0
/**
 * @brief Performs end-of-turn processing.
 * @param[in] self Pointer to the event structure that is currently executed
 * @param[in] msg The netchannel message
 * @sa CL_EndRoundAnnounce
 */
void CL_DoEndRound (const eventRegister_t* self, dbuffer* msg)
{
	/* hud changes */
	if (cls.isOurRound())
		UI_ExecuteConfunc("endround");

	refdef.rendererFlags &= ~RDF_IRGOGGLES;

	/* change active player */
	Com_Printf("Team %i ended round\n", cl.actTeam);
	cl.actTeam = NET_ReadByte(msg);
	Com_Printf("Team %i's round started!\n", cl.actTeam);

	/* hud changes */
	if (cls.isOurRound()) {
		/* check whether a particle has to go */
		CL_ParticleCheckRounds();
		UI_ExecuteConfunc("startround");
		HUD_DisplayMessage(_("Your round started!"));
		S_StartLocalSample("misc/roundstart", SND_VOLUME_DEFAULT);
		CL_ActorConditionalMoveCalc(selActor);
	}
}
Ejemplo n.º 7
0
/**
 * @brief Revitalizes a stunned actor (all that is needed is the local entity state set).
 * @param[in] msg The netchannel message
 * @param[in] self Pointer to the event structure that is currently executed
 */
void CL_ActorRevitalised (const eventRegister_t* self, dbuffer* msg)
{
	int entnum, state;
	NET_ReadFormat(msg, self->formatString, &entnum, &state);

	/* get les */
	le_t* le = LE_Get(entnum);
	if (!le)
		LE_NotFoundError(entnum);

	if (!LE_IsStunned(le) && !LE_IsLivingActor(le))
		Com_Error(ERR_DROP, "CL_ActorRevitalised: Can't revitalise, LE is not a dead or stunned actor");

	LE_Lock(le);

	/* link any floor container into the actor temp floor container */
	le_t* floor = LE_Find(ET_ITEM, le->pos);
	if (floor)
		le->setFloor(floor);

	le->state = state;

	/* play animation */
	LE_SetThink(le, LET_StartIdle);

	/* Print some info. */
	if (le->team == cls.team) {
		const character_t* chr = CL_ActorGetChr(le);
		if (chr) {
			char tmpbuf[128];
			Com_sprintf(tmpbuf, lengthof(tmpbuf), _("%s was revitalised\n"), chr->name);
			HUD_DisplayMessage(tmpbuf);
		}
	} else {
		switch (le->team) {
		case (TEAM_CIVILIAN):
			HUD_DisplayMessage(_("A civilian was revitalised."));
			break;
		case (TEAM_ALIEN):
			HUD_DisplayMessage(_("An alien was revitalised."));
			break;
		case (TEAM_PHALANX):
			HUD_DisplayMessage(_("A soldier was revitalised."));
			break;
		default:
			HUD_DisplayMessage(va(_("A member of team %i was revitalised."), le->team));
			break;
		}
	}

	le->aabb.setMaxs(player_maxs);

	if (le->ptl) {
		CL_ParticleFree(le->ptl);
		le->ptl = nullptr;
	}

	/* add team members to the actor list */
	CL_ActorAddToTeamList(le);

	/* update pathing as we maybe not can walk onto this actor anymore */
	CL_ActorConditionalMoveCalc(selActor);
	LE_Unlock(le);
}
Ejemplo n.º 8
0
/**
 * @brief Kills an actor (all that is needed is the local entity state set to STATE_DEAD).
 * @note Also changes the animation to a random death sequence and appends the dead animation
 * @param[in] msg The netchannel message
 * @param[in] self Pointer to the event structure that is currently executed
 */
void CL_ActorDie (const eventRegister_t *self, dbuffer *msg)
{
	le_t *le;
	int entnum, state, playerNum;

	NET_ReadFormat(msg, self->formatString, &entnum, &state, &playerNum);

	/* get les */
	le = LE_Get(entnum);

	if (!le)
		LE_NotFoundError(entnum);

	if (!LE_IsLivingActor(le))
		Com_Error(ERR_DROP, "CL_ActorDie: Can't kill, LE is not an actor (type: %i)", le->type);

	if (!LE_IsStunned(le) && LE_IsDead(le))
		Com_Error(ERR_DROP, "CL_ActorDie: Can't kill, actor already dead");

	LE_Lock(le);

	/* set relevant vars */
	FLOOR(le) = NULL;

	le->state = state;

	/* count spotted aliens */
	cl.numEnemiesSpotted = CL_CountVisibleEnemies();

	/* play animation */
	LE_SetThink(le, NULL);
	R_AnimChange(&le->as, le->model1, va("death%i", LE_GetAnimationIndexForDeath(le)));
	R_AnimAppend(&le->as, le->model1, va("dead%i", LE_GetAnimationIndexForDeath(le)));

	/* Print some info about the death or stun. */
	if (le->team == cls.team) {
		if (playerNum != le->pnum) {
			const char *playerName = CL_PlayerGetName(playerNum);
			char tmpbuf[128];
			Com_sprintf(tmpbuf, lengthof(tmpbuf), _("%s lost a soldier\n"), playerName);
			HUD_DisplayMessage(tmpbuf);
		} else {
			const character_t *chr = CL_ActorGetChr(le);
			if (chr) {
				char tmpbuf[128];
				if (LE_IsStunned(le)) {
					Com_sprintf(tmpbuf, lengthof(tmpbuf), _("%s was stunned\n"), chr->name);
				} else {
					Com_sprintf(tmpbuf, lengthof(tmpbuf), _("%s was killed\n"), chr->name);
				}
				HUD_DisplayMessage(tmpbuf);
			}
		}
	} else {
		switch (le->team) {
		case (TEAM_CIVILIAN):
			if (LE_IsStunned(le))
				HUD_DisplayMessage(_("A civilian was stunned."));
			else
				HUD_DisplayMessage(_("A civilian was killed."));
			break;
		case (TEAM_ALIEN):
			if (LE_IsStunned(le))
				HUD_DisplayMessage(_("An alien was stunned."));
			else
				HUD_DisplayMessage(_("An alien was killed."));
			break;
		case (TEAM_PHALANX):
			if (LE_IsStunned(le))
				HUD_DisplayMessage(_("A soldier was stunned."));
			else
				HUD_DisplayMessage(_("A soldier was killed."));
			break;
		default:
			if (LE_IsStunned(le))
				HUD_DisplayMessage(va(_("A member of team %i was stunned."), le->team));
			else
				HUD_DisplayMessage(va(_("A member of team %i was killed."), le->team));
			break;
		}
	}

	/**
	 * @todo CHRSH_IsTeamDefRobot: spawn smoke particles for robots
	 */

	CL_ActorPlaySound(le, SND_DEATH);

	VectorCopy(player_dead_maxs, le->maxs);
	if (!LE_IsStunned(le))
		le->contents = CONTENTS_DEADACTOR;
	CL_ActorRemoveFromTeamList(le);

	/* update pathing as we maybe can walk onto the dead actor now */
	CL_ActorConditionalMoveCalc(selActor);
	LE_Unlock(le);
}
Ejemplo n.º 9
0
/**
 * @sa CL_ActorAddToTeamList
 * @sa G_AppearPerishEvent
 * @sa CL_ActorAdd
 * @note EV_ACTOR_APPEAR
 */
void CL_ActorAppear (const eventRegister_t *self, struct dbuffer *msg)
{
	le_t *le, *leResponsible;
	int entnum, entnumResponsible, modelnum1, modelnum2;
	int teamDefID = -1;

	/* check if the actor is already visible */
	entnum = NET_ReadShort(msg);
	entnumResponsible = NET_ReadShort(msg);
	le = LE_Get(entnum);
	leResponsible = LE_Get(entnumResponsible);

	if (entnumResponsible != SKIP_LOCAL_ENTITY && !leResponsible)
		LE_NotFoundError(entnumResponsible);

	/* mission start - no actor is spawned yet - so create it */
	if (!le)
		le = LE_Add(entnum);

	/* Locking should be unnecessary if CL_CheckDefault filters this call, since this event starts and
	 * ends in this function only.  Adding lock/unlock just to be sure. */
	LE_Lock(le);

	/* maybe added via CL_ActorAdd before */
	le->invis = false;

	/* get the info */
	NET_ReadFormat(msg, self->formatString,
			&le->team, &teamDefID, &le->gender, &le->ucn, &le->pnum, &le->pos,
			&le->angle, &le->right, &le->left,
			&modelnum1, &modelnum2, &le->bodySkin, &le->headSkin,
			&le->state, &le->fieldSize,
			&le->maxTU, &le->maxMorale, &le->maxHP);

	if (teamDefID < 0 || teamDefID > csi.numTeamDefs)
		Com_Printf("CL_ActorAppear: Invalid teamDef index\n");
	else
		le->teamDef = &csi.teamDef[teamDefID];

	switch (le->fieldSize) {
	case ACTOR_SIZE_NORMAL:
		le->addFunc = CL_AddActor;
		le->type = ET_ACTOR;
		break;
	case ACTOR_SIZE_2x2:
		le->addFunc = CL_AddUGV;
		le->type = ET_ACTOR2x2;
		break;
	default:
		Com_Error(ERR_DROP, "Unknown fieldSize for le in CL_ActorAppear (EV_ACTOR_APPEAR)");
	}
	le->modelnum1 = modelnum1;
	le->modelnum2 = modelnum2;
	le->model1 = LE_GetDrawModel(modelnum1);
	le->model2 = LE_GetDrawModel(modelnum2);
	Grid_PosToVec(cl.mapData->map, le->fieldSize, le->pos, le->origin);
	le->angles[YAW] = directionAngles[le->angle];

	if (LE_IsDead(le) && !LE_IsStunned(le))
		le->contents = CONTENTS_DEADACTOR;
	else
		le->contents = CONTENTS_ACTOR;
	VectorCopy(player_mins, le->mins);
	if (LE_IsDead(le))
		VectorCopy(player_dead_maxs, le->maxs);
	else
		VectorCopy(player_maxs, le->maxs);

	LE_SetThink(le, LET_StartIdle);

	/* count spotted aliens (also stunned) */
	cl.numEnemiesSpotted = CL_CountVisibleEnemies();

	if (LE_IsLivingActor(le)) {
		if (cl.actTeam != cls.team) {
			/* center view (if wanted) */
			LE_CenterView(le);
		}

		/* draw line of sight */
		if (le->team != cls.team) {
			if (leResponsible)
				CL_DrawLineOfSight(leResponsible, le);

			/* message */
			if (le->team != TEAM_CIVILIAN) {
				if (GAME_TeamIsKnown(le->teamDef)) {
					char tmpbuf[128];
					Com_sprintf(tmpbuf, sizeof(tmpbuf), _("Enemy spotted: %s!"), _(le->teamDef->name));
					HUD_DisplayMessage(tmpbuf);
				} else
					HUD_DisplayMessage(_("Unknown enemy spotted!"));
			} else
				HUD_DisplayMessage(_("Civilian spotted."));

			/* update pathing as new actor could block path */
			CL_ActorConditionalMoveCalc(leResponsible ? leResponsible : selActor);
		}
	}

	/* add team members to the actor list */
	CL_ActorAddToTeamList(le);
	LE_Unlock(le);
}