/**
 * @brief Decides if following events should be delayed
 */
int CL_ActorShootHiddenTime (const eventRegister_t *self, dbuffer *msg, eventTiming_t *eventTiming)
{
	int first;
	int objIdx;
	const objDef_t *obj;
	weaponFireDefIndex_t weapFdsIdx;
	fireDefIndex_t fireDefIndex;
	const int eventTime = eventTiming->shootTime;

	NET_ReadFormat(msg, self->formatString, &first, &objIdx, &weapFdsIdx, &fireDefIndex);

	obj = INVSH_GetItemByIDX(objIdx);
	if (first) {
		eventTiming->nextTime += 500;
		eventTiming->impactTime = eventTiming->shootTime = eventTiming->nextTime;
	} else {
		const fireDef_t *fd = FIRESH_GetFiredef(obj, weapFdsIdx, fireDefIndex);
		/* impact right away - we don't see it at all
		 * bouncing is not needed here, too (we still don't see it) */
		eventTiming->impactTime = eventTiming->shootTime;
		eventTiming->nextTime = CL_GetNextTime(self, eventTiming, eventTiming->shootTime + 1400);
		if (fd->delayBetweenShots > 0.0)
			eventTiming->shootTime += 1000 / fd->delayBetweenShots;
	}
	eventTiming->parsedDeath = false;

	return eventTime;
}
/**
 * @brief Decides if following events should be delayed. If the projectile has a speed value assigned, the
 * delay is relative to the distance the projectile flies. There are other fire definition related options
 * that might delay the execution of further events.
 */
int CL_ActorDoShootTime (const eventRegister_t* self, dbuffer* msg, eventTiming_t* eventTiming)
{
	int flags, dummy;
	int objIdx, surfaceFlags;
	int weap_fds_idx, fd_idx;
	shoot_types_t shootType;
	vec3_t muzzle, impact;
	int eventTime = eventTiming->shootTime;

	/* read data */
	NET_ReadFormat(msg, self->formatString, &dummy, &dummy, &dummy, &objIdx, &weap_fds_idx, &fd_idx, &shootType, &flags,
			&surfaceFlags, &muzzle, &impact, &dummy);

	const objDef_t* obj = INVSH_GetItemByIDX(objIdx);
	const fireDef_t* fd = FIRESH_GetFiredef(obj, weap_fds_idx, fd_idx);

	if (!(flags & SF_BOUNCED)) {
		/* shooting */
		if (fd->speed > 0.0 && !CL_OutsideMap(impact, UNIT_SIZE * 10)) {
			eventTiming->impactTime = eventTiming->shootTime + 1000 * VectorDist(muzzle, impact) / fd->speed;
		} else {
			eventTiming->impactTime = eventTiming->shootTime;
		}
		if (!cls.isOurRound())
			eventTiming->nextTime = CL_GetNextTime(self, eventTiming, eventTiming->impactTime + 1400);
		else
			eventTiming->nextTime = CL_GetNextTime(self, eventTiming, eventTiming->impactTime + 400);
		if (fd->delayBetweenShots > 0.0)
			eventTiming->shootTime += 1000 / fd->delayBetweenShots;
	} else {
		/* only a bounced shot */
		eventTime = eventTiming->impactTime;
		if (fd->speed > 0.0) {
			eventTiming->impactTime += 1000 * VectorDist(muzzle, impact) / fd->speed;
			eventTiming->nextTime = CL_GetNextTime(self, eventTiming, eventTiming->impactTime);
		}
	}
	eventTiming->parsedDeath = false;

	return eventTime;
}