예제 #1
0
파일: cl_game.c 프로젝트: chrisglass/ufoai
/**
 * @sa G_WriteItem
 * @sa G_ReadItem
 * @note The amount of the item_t struct should not be needed here - because
 * the amount is only valid for idFloor and idEquip
 */
static void CL_NetSendItem (struct dbuffer *buf, item_t item, containerIndex_t container, int x, int y)
{
	const int ammoIdx = item.m ? item.m->idx : NONE;
	const eventRegister_t *eventData = CL_GetEvent(EV_INV_TRANSFER);
	assert(item.t);
	Com_DPrintf(DEBUG_CLIENT, "CL_NetSendItem: Add item %s to container %i (t=%i:a=%i:m=%i) (x=%i:y=%i)\n",
		item.t->id, container, item.t->idx, item.a, ammoIdx, x, y);
	NET_WriteFormat(buf, eventData->formatString, item.t->idx, item.a, ammoIdx, container, x, y, item.rotated, item.amount);
}
예제 #2
0
/**
 * @sa G_WriteItem
 * @sa G_ReadItem
 * @note The amount of the item_t struct should not be needed here - because
 * the amount is only valid for idFloor and idEquip
 */
static void CL_NetReceiveItem (dbuffer *buf, item_t *item, containerIndex_t *container, int *x, int *y)
{
	const eventRegister_t *eventData = CL_GetEvent(EV_INV_TRANSFER);

	/* reset */
	int t, m;
	item->item = item->ammo = NULL;
	item->ammoLeft = NONE_AMMO;
	NET_ReadFormat(buf, eventData->formatString, &t, &item->ammoLeft, &m, container, x, y, &item->rotated, &item->amount);

	item->item = INVSH_GetItemByIDX(t);
	item->ammo = INVSH_GetItemByIDX(m);

	if (!item->item)
		Com_Error(ERR_DROP, "no weapon given for item");
}
예제 #3
0
/**
 * @sa G_WriteItem
 * @sa G_ReadItem
 * @note The amount of the Item should not be needed here - because
 * the amount is only valid for CID_FLOOR and CID_EQUIP
 */
static void CL_NetReceiveItem (dbuffer* buf, Item* item, containerIndex_t* container, int* x, int* y)
{
	const eventRegister_t* eventData = CL_GetEvent(EV_INV_TRANSFER);

	/* reset */
	int itemIdx, ammoIdx;
	int ammoleft = NONE_AMMO;
	int amount = 0;
	item->setDef(nullptr);
	item->setAmmoDef(nullptr);
	NET_ReadFormat(buf, eventData->formatString, &itemIdx, &ammoleft, &ammoIdx, container, x, y, &item->rotated, &amount);
	item->setAmmoLeft(ammoleft);
	item->setAmount(amount);
	item->setDef(INVSH_GetItemByIDX(itemIdx));
	item->setAmmoDef(INVSH_GetItemByIDX(ammoIdx));

	if (!item->def())
		Com_Error(ERR_DROP, "no weapon given for item");
}
예제 #4
0
파일: e_time.c 프로젝트: chrisglass/ufoai
/**
 * @brief Calculates the time the event should get executed. If two events return the same time,
 * they are going to be executed in the order the were parsed.
 * @param[in] eType The event type
 * @param[in,out] msg The message buffer that can be modified to get the event time
 * @param[in] dt Delta time in msec since the last event was parsed
 */
int CL_GetEventTime (const event_t eType, struct dbuffer *msg, const int dt)
{
	const eventRegister_t *eventData = CL_GetEvent(eType);

#ifdef OLDEVENTTIME
	/* the time the event should be executed. This value is used to sort the
	 * event chain to determine which event must be executed at first. This
	 * value also ensures, that the events are executed in the correct
	 * order. E.g. @c impactTime is used to delay some events in case the
	 * projectile needs some time to reach its target. */
	int eventTime;

	if (eType == EV_RESET) {
		parsedDeath = qfalse;
		nextTime = 0;
		shootTime = 0;
		impactTime = 0;
	} else if (eType == EV_ACTOR_DIE)
		parsedDeath = qtrue;

	/* get event time */
	if (nextTime < cl.time)
		nextTime = cl.time;
	if (impactTime < cl.time)
		impactTime = cl.time;

	if (eType == EV_ACTOR_DIE || eType == EV_MODEL_EXPLODE)
		eventTime = impactTime;
	else if (eType == EV_ACTOR_SHOOT || eType == EV_ACTOR_SHOOT_HIDDEN)
		eventTime = shootTime;
	else if (eType == EV_RESULTS)
		eventTime = nextTime + 1400;
	else
		eventTime = nextTime;

	if (eType == EV_ENT_APPEAR || eType == EV_INV_ADD || eType == EV_PARTICLE_APPEAR || eType == EV_PARTICLE_SPAWN) {
		if (parsedDeath) { /* drop items after death (caused by impact) */
			eventTime = impactTime + 400;
			/* EV_INV_ADD messages are the last events sent after a death */
			if (eType == EV_INV_ADD)
				parsedDeath = qfalse;
		} else if (impactTime > cl.time) { /* item thrown on the ground */
			eventTime = impactTime + 75;
		}
	}

	/* calculate time interval before the next event */
	switch (eType) {
	case EV_ACTOR_APPEAR:
		if (cl.actTeam != cls.team)
			nextTime += 600;
		break;
	case EV_INV_RELOAD:
		/* let the reload sound play */
		nextTime += 600;
		break;
	case EV_ACTOR_START_SHOOT:
		nextTime += 300;
		shootTime = nextTime;
		break;
	case EV_ACTOR_SHOOT_HIDDEN:
		{
			int first;
			int objIdx;
			const objDef_t *obj;
			weaponFireDefIndex_t weapFdsIdx;
			fireDefIndex_t fireDefIndex;

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

			obj = INVSH_GetItemByIDX(objIdx);
			if (first) {
				nextTime += 500;
				impactTime = shootTime = 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) */
				impactTime = shootTime;
				nextTime = shootTime + 1400;
				if (fd->delayBetweenShots > 0.0)
					shootTime += 1000 / fd->delayBetweenShots;
			}
			parsedDeath = qfalse;
		}
		break;
	case EV_ACTOR_MOVE:
		{
			le_t *le;
			int number, i;
			int time = 0;
			int pathLength;
			byte crouchingState;
			pos3_t pos, oldPos;

			number = NET_ReadShort(msg);
			/* get le */
			le = LE_Get(number);
			if (!le)
				LE_NotFoundError(number);

			pathLength = NET_ReadByte(msg);

			/* Also skip the final position */
			NET_ReadByte(msg);
			NET_ReadByte(msg);
			NET_ReadByte(msg);

			VectorCopy(le->pos, pos);
			crouchingState = LE_IsCrouched(le) ? 1 : 0;

			for (i = 0; i < pathLength; i++) {
				const dvec_t dvec = NET_ReadShort(msg);
				const byte dir = getDVdir(dvec);
				VectorCopy(pos, oldPos);
				PosAddDV(pos, crouchingState, dvec);
				time += LE_ActorGetStepTime(le, pos, oldPos, dir, NET_ReadShort(msg));
				NET_ReadShort(msg);
			}
			nextTime += time + 400;
		}
		break;
	case EV_ACTOR_SHOOT:
		{
			const fireDef_t	*fd;
			int flags, dummy;
			int objIdx, surfaceFlags;
			objDef_t *obj;
			int weap_fds_idx, fd_idx;
			shoot_types_t shootType;
			vec3_t muzzle, impact;

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

			obj = INVSH_GetItemByIDX(objIdx);
			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)) {
					impactTime = shootTime + 1000 * VectorDist(muzzle, impact) / fd->speed;
				} else {
					impactTime = shootTime;
				}
				if (cl.actTeam != cls.team)
					nextTime = impactTime + 1400;
				else
					nextTime = impactTime + 400;
				if (fd->delayBetweenShots > 0.0)
					shootTime += 1000 / fd->delayBetweenShots;
			} else {
				/* only a bounced shot */
				eventTime = impactTime;
				if (fd->speed > 0.0) {
					impactTime += 1000 * VectorDist(muzzle, impact) / fd->speed;
					nextTime = impactTime;
				}
			}
			parsedDeath = qfalse;
		}
		break;
	case EV_ACTOR_THROW:
		nextTime += NET_ReadShort(msg);
		impactTime = shootTime = nextTime;
		parsedDeath = qfalse;
		break;
	default:
		break;
	}

	Com_DPrintf(DEBUG_EVENTSYS, "%s => eventTime: %i, nextTime: %i, impactTime: %i, shootTime: %i\n",
			eventData->name, eventTime, nextTime, impactTime, shootTime);

	return eventTime;
#else
	if (!eventData->timeCallback)
		return cl.time;

	return eventData->timeCallback(eventData, msg, dt);
#endif
}