예제 #1
0
/**
 * @brief Move the actor along the path to the given location
 * @note Think function
 * @sa CL_ActorDoMove
 */
static void LET_PathMove (le_t* le)
{
	/* check for start of the next step */
	if (cl.time < le->startTime)
		return;

	/* move ahead */
	while (cl.time >= le->endTime) {
		/* Ensure that we are displayed where we are supposed to be, in case the last frame came too quickly. */
		Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->pos, le->origin);

		/* Record the last position of movement calculations. */
		VectorCopy(le->pos, le->oldPos);

		if (le->pathPos < le->pathLength) {
			LE_DoPathMove(le);
		} else {
			LE_DoEndPathMove(le);
			return;
		}
	}

	/* interpolate the position */
	vec3_t start, dest, delta;
	Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->oldPos, start);
	Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->pos, dest);
	VectorSubtract(dest, start, delta);

	const float frac = (float) (cl.time - le->startTime) / (float) (le->endTime - le->startTime);

	/* calculate the new interpolated actor origin in the world */
	VectorMA(start, frac, delta, le->origin);
}
예제 #2
0
/**
 * sqrt(2) for diagonal movement
 */
int LE_ActorGetStepTime (const le_t* le, const pos3_t pos, const pos3_t oldPos, const int dir, const int speed)
{
	if (dir != DIRECTION_FALL) {
		return (((dir & (CORE_DIRECTIONS - 1)) >= BASE_DIRECTIONS ? UNIT_SIZE * 1.41 : UNIT_SIZE) * 1000 / speed);
	} else {
		vec3_t start, dest;
		/* This needs to account for the distance of the fall. */
		Grid_PosToVec(cl.mapData->routing, le->fieldSize, oldPos, start);
		Grid_PosToVec(cl.mapData->routing, le->fieldSize, pos, dest);
		/* 1/1000th of a second per model unit in height change */
		return (start[2] - dest[2]);
	}
}
예제 #3
0
/**
 * @brief Let an entity appear - like an item on the ground that just got visible
 * @sa EV_ENT_APPEAR
 * @sa CL_EntPerish
 * @sa CL_AddEdict
 */
void CL_EntAppear (const eventRegister_t* self, dbuffer* msg)
{
	int		entnum;
	entity_type_t type;
	pos3_t	pos;

	NET_ReadFormat(msg, self->formatString, &entnum, &type, &pos);

	/* check if the ent is already visible */
	le_t* le = LE_Get(entnum);
	if (!le) {
		le = LE_Add(entnum);
	} else {
		Com_DPrintf(DEBUG_CLIENT, "CL_EntAppear: Entity appearing already visible... overwriting the old one\n");
		le->inuse = true;
	}

	le->type = type;

	/* the default is invisible - another event will follow which spawns not
	 * only the le, but also the particle. The visibility is set there, too */
	if (le->type == ET_PARTICLE)
		LE_SetInvisible(le);

	VectorCopy(pos, le->pos);
	Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->pos, le->origin);
}
예제 #4
0
/**
 * @brief Adds an hidden actor to the list of le's
 * @sa CL_ActorAppear
 * @note Actor is invisible until CL_ActorAppear (EV_ACTOR_APPEAR) was triggered
 * @note EV_ACTOR_ADD
 * @sa G_SendInvisible
 */
void CL_ActorAdd (const eventRegister_t* self, dbuffer* msg)
{
	/* check if the actor is already visible */
	const int entnum = NET_ReadShort(msg);
	le_t* le = LE_Get(entnum);
	if (le) {
		Com_Printf("CL_ActorAdd: Actor with number %i already exists\n", entnum);
		NET_SkipFormat(msg, self->formatString);
		return;
	}
	le = LE_Add(entnum);

	/* get the info */
	int teamDefID;
	NET_ReadFormat(msg, self->formatString,
				&le->team, &teamDefID,
				&le->gender, &le->pnum, &le->pos,
				&le->state, &le->fieldSize);

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

	/*Com_Printf("CL_ActorAdd: Add number: %i\n", entnum);*/

	le->type = ET_ACTORHIDDEN;

	Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->pos, le->origin);
	le->flags = LE_INVISIBLE;
}
예제 #5
0
/**
 * @sa CL_BiggestItem
 * @param[in] le The local entity (ET_ITEM) with the floor container
 */
void LE_PlaceItem (le_t* le)
{
	assert(LE_IsItem(le));

	/* search owners (there can be many, some of them dead) */
	le_t* actor = nullptr;
	while ((actor = LE_GetNextInUse(actor))) {
		if ((actor->type == ET_ACTOR || actor->type == ET_ACTOR2x2)
		 && VectorCompare(actor->pos, le->pos)) {
			if (le->getFloorContainer())
				actor->setFloor(le);
		}
	}

	/* the le is an ET_ITEM entity, this entity is there to render dropped items
	 * if there are no items in the floor container, this entity can be
	 * deactivated */
	Item* floorCont = le->getFloorContainer();
	if (floorCont) {
		const objDef_t* biggest = LE_BiggestItem(floorCont);
		le->model1 = cls.modelPool[biggest->idx];
		if (!le->model1)
			Com_Error(ERR_DROP, "Model for item %s is not precached in the cls.model_weapons array",
				biggest->id);
		Grid_PosToVec(cl.mapData->routing, le->fieldSize, le->pos, le->origin);
		VectorSubtract(le->origin, biggest->center, le->origin);
		le->angles[ROLL] = 90;
		/*le->angles[YAW] = 10*(int)(le->origin[0] + le->origin[1] + le->origin[2]) % 360; */
		le->origin[2] -= GROUND_DELTA;
	} else {
		/* If no items in floor inventory, don't draw this le - the container is
		 * maybe empty because an actor picked up the last items here */
		le->flags |= LE_REMOVE_NEXT_FRAME;
	}
}
예제 #6
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);
}