コード例 #1
0
ファイル: cl_localentity.cpp プロジェクト: yason/ufoai
/**
 * @note Think function
 */
static void LET_Projectile (le_t* le)
{
	if (cl.time >= le->endTime) {
		vec3_t impact;
		VectorCopy(le->origin, impact);
		CL_ParticleFree(le->ptl);
		/* don't run the think function again */
		le->inuse = false;
		if (Q_strvalid(le->ref1)) {
			VectorCopy(le->ptl->s, impact);
			le->ptl = CL_ParticleSpawn(le->ref1, 0, impact, bytedirs[le->angle]);
			VecToAngles(bytedirs[le->state], le->ptl->angles);
		}
		if (Q_strvalid(le->ref2)) {
			S_LoadAndPlaySample(le->ref2, impact, le->fd->impactAttenuation, SND_VOLUME_WEAPONS);
		}
		if (le->ref3) {
			/* Spawn blood particles (if defined) if actor(-body) was hit. Even if actor is dead. */
			/** @todo Special particles for stun attack (mind you that there is
			 * electrical and gas/chemical stunning)? */
			if (le->fd->obj->dmgtype != csi.damStunGas)
				LE_ActorBodyHit(le->ref3, impact, le->angle);
			CL_ActorPlaySound(le->ref3, SND_HURT);
		}
	} else if (CL_OutsideMap(le->ptl->s, UNIT_SIZE * 10)) {
		le->endTime = cl.time;
		CL_ParticleFree(le->ptl);
		/* don't run the think function again */
		le->inuse = false;
	}
}
コード例 #2
0
ファイル: e_event_actordie.cpp プロジェクト: jklemmack/ufoai
/**
 * @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);
}
コード例 #3
0
ファイル: cl_localentity.cpp プロジェクト: yason/ufoai
void LE_AddProjectile (const fireDef_t* fd, int flags, const vec3_t muzzle, const vec3_t impact, int normal, le_t* leVictim)
{
	/* add le */
	le_t* le = LE_Add(0);
	if (!le)
		return;
	LE_SetInvisible(le);
	/* bind particle */
	le->ptl = CL_ParticleSpawn(fd->projectile, 0, muzzle);
	if (!le->ptl) {
		le->inuse = false;
		return;
	}

	/* calculate parameters */
	vec3_t delta;
	VectorSubtract(impact, muzzle, delta);
	const float dist = VectorLength(delta);

	VecToAngles(delta, le->ptl->angles);
	/* direction - bytedirs index */
	le->angle = normal;
	le->fd = fd;

	/* infinite speed projectile? */
	if (!fd->speed) {
		le->inuse = false;
		le->ptl->size[0] = dist;
		VectorMA(muzzle, 0.5, delta, le->ptl->s);
		if ((flags & (SF_IMPACT | SF_BODY)) || (fd->splrad && !fd->bounce)) {
			ptl_t* ptl = nullptr;
			const float* dir = bytedirs[le->angle];
			if (flags & SF_BODY) {
				if (fd->hitBodySound != nullptr) {
					S_LoadAndPlaySample(fd->hitBodySound, le->origin, le->fd->impactAttenuation, SND_VOLUME_WEAPONS);
				}
				if (fd->hitBody != nullptr)
					ptl = CL_ParticleSpawn(fd->hitBody, 0, impact, dir);

				/* Spawn blood particles (if defined) if actor(-body) was hit. Even if actor is dead. */
				/** @todo Special particles for stun attack (mind you that there is
				 * electrical and gas/chemical stunning)? */
				if (leVictim) {
					if (fd->obj->dmgtype != csi.damStunGas)
						LE_ActorBodyHit(leVictim, impact, le->angle);
					if (fd->damage[0] >= 0)
						CL_ActorPlaySound(leVictim, SND_HURT);
				}
			} else {
				if (fd->impactSound != nullptr) {
					S_LoadAndPlaySample(fd->impactSound, le->origin, le->fd->impactAttenuation, SND_VOLUME_WEAPONS);
				}
				if (fd->impact != nullptr)
					ptl = CL_ParticleSpawn(fd->impact, 0, impact, dir);
			}
			if (ptl)
				VecToAngles(dir, ptl->angles);
		}
		return;
	}
	/* particle properties */
	VectorScale(delta, fd->speed / dist, le->ptl->v);
	le->endTime = cl.time + 1000 * dist / fd->speed;

	/* think function */
	if (flags & SF_BODY) {
		le->ref1 = fd->hitBody;
		le->ref2 = fd->hitBodySound;
		le->ref3 = leVictim;
	} else if ((flags & SF_IMPACT) || (fd->splrad && !fd->bounce)) {
		le->ref1 = fd->impact;
		le->ref2 = fd->impactSound;
	} else {
		le->ref1 = nullptr;
		if (flags & SF_BOUNCING)
			le->ref2 = fd->bounceSound;
	}

	LE_SetThink(le, LET_Projectile);
	LE_ExecuteThink(le);
}