コード例 #1
0
ファイル: g_client.c プロジェクト: darkshade9/aq2w
/*
 * G_ClientCorpse
 */
static void G_ClientCorpse(g_edict_t *self) {
	const float f = frand();
	g_edict_t *ent = G_Spawn();

	ent->class_name = "corpse";
	ent->move_type = MOVE_TYPE_TOSS;
	ent->solid = SOLID_NOT;

	VectorScale(PM_MINS, PM_SCALE, ent->mins);
	VectorScale(PM_MAXS, PM_SCALE, ent->maxs);

	VectorCopy(self->velocity, ent->velocity);

	memcpy(&ent->s, &self->s, sizeof(ent->s));
	ent->s.number = ent - g_game.edicts;

	ent->s.model2 = 0;
	ent->s.model3 = 0;
	ent->s.model4 = 0;

	if (f < 0.33)
		G_SetAnimation(ent, ANIM_BOTH_DEATH1, true);
	else if (f < 0.66)
		G_SetAnimation(ent, ANIM_BOTH_DEATH2, true);
	else
		G_SetAnimation(ent, ANIM_BOTH_DEATH3, true);

	ent->think = G_ClientCorpse_think;
	ent->next_think = g_level.time + 1.0;

	gi.LinkEntity(ent);
}
コード例 #2
0
ファイル: g_client.c プロジェクト: darkshade9/aq2w
/*
 * G_ClientRespawn_
 *
 * The grunt work of putting the client into the server on [re]spawn.
 */
static void G_ClientRespawn_(g_edict_t *ent) {
	vec3_t spawn_origin, spawn_angles, old_angles;
	float height;
	g_client_t *cl;
	g_client_persistent_t locals;
	int i;

	// find a spawn point
	G_SelectSpawnPoint(ent, spawn_origin, spawn_angles);

	cl = ent->client;

	// retain last angles for delta
	VectorCopy(ent->client->cmd_angles, old_angles);

	// reset inventory, health, etc
	G_InitClientLocals(cl);

	// clear everything but locals
	locals = cl->persistent;
	memset(cl, 0, sizeof(*cl));
	cl->persistent = locals;

	// clear entity values
	VectorScale(PM_MINS, PM_SCALE, ent->mins);
	VectorScale(PM_MAXS, PM_SCALE, ent->maxs);
	height = ent->maxs[2] - ent->mins[2];

	ent->ground_entity = NULL;
	ent->take_damage = true;
	ent->move_type = MOVE_TYPE_WALK;
	ent->view_height = ent->mins[2] + (height * 0.75);
	ent->class_name = "player";
	ent->mass = 200.0;
	ent->solid = SOLID_BOX;
	ent->dead = false;
	ent->clip_mask = MASK_PLAYER_SOLID;
	ent->pain = G_ClientPain;
	ent->die = G_ClientDie;
	ent->water_level = 0;
	ent->water_type = 0;
	ent->sv_flags = 0;

	// copy these back once they have been set in locals
	ent->health = ent->client->persistent.health;
	ent->max_health = ent->client->persistent.max_health;

	VectorClear(ent->velocity);
	ent->velocity[2] = 150.0;

	// clear player state values
	memset(&ent->client->ps, 0, sizeof(cl->ps));

	cl->ps.pmove.origin[0] = spawn_origin[0] * 8.0;
	cl->ps.pmove.origin[1] = spawn_origin[1] * 8.0;
	cl->ps.pmove.origin[2] = spawn_origin[2] * 8.0;

	// clear entity state values
	ent->s.effects = 0;
	ent->s.model1 = 0xff; // use the client info model
	ent->s.model2 = 0;
	ent->s.model3 = 0;
	ent->s.model4 = 0;
	ent->s.client = ent - g_game.edicts - 1;

	G_SetAnimation(ent, ANIM_TORSO_STAND1, true);
	G_SetAnimation(ent, ANIM_LEGS_JUMP1, true);

	VectorCopy(spawn_origin, ent->s.origin);
	VectorCopy(ent->s.origin, ent->s.old_origin);

	// set the delta angle of the spawn point
	for (i = 0; i < 3; i++) {
		cl->ps.pmove.delta_angles[i]
				= ANGLE2SHORT(spawn_angles[i] - old_angles[i]);
	}

	VectorClear(cl->cmd_angles);
	VectorClear(cl->angles);
	VectorClear(ent->s.angles);

	// spawn a spectator
	if (cl->persistent.spectator) {
		cl->chase_target = NULL;

		cl->persistent.weapon = NULL;
		cl->persistent.team = NULL;
		cl->persistent.ready = false;

		ent->move_type = MOVE_TYPE_NO_CLIP;
		ent->solid = SOLID_NOT;
		ent->sv_flags |= SVF_NO_CLIENT;
		ent->take_damage = false;

		gi.LinkEntity(ent);
		return;
	}

	// or spawn a player
	ent->s.event = EV_TELEPORT;

	// hold in place briefly
	cl->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
	cl->ps.pmove.pm_time = 20;

	cl->persistent.match_num = g_level.match_num;
	cl->persistent.round_num = g_level.round_num;

	gi.UnlinkEntity(ent);

	G_KillBox(ent); // telefrag anyone in our spot

	gi.LinkEntity(ent);

	// force the current weapon up
	cl->new_weapon = cl->persistent.weapon;
	G_ChangeWeapon(ent);
}
コード例 #3
0
ファイル: g_client_view.c プロジェクト: EEmmanuel7/quetoo
/*
 * @brief Sets the animation sequences for the specified entity. This is called
 * towards the end of each frame, after our ground entity and water level have
 * been resolved.
 */
static void G_ClientAnimation(g_entity_t *ent) {

	if (ent->s.model1 != MODEL_CLIENT)
		return;

	// corpses animate to their final resting place

	if (ent->solid == SOLID_DEAD) {
		if (g_level.time >= ent->client->locals.respawn_time) {
			switch (ent->s.animation1) {
				case ANIM_BOTH_DEATH1:
				case ANIM_BOTH_DEATH2:
				case ANIM_BOTH_DEATH3:
					G_SetAnimation(ent, ent->s.animation1 + 1, false);
					break;
				default:
					break;
			}
		}
		return;
	}

	// no-clippers do not animate

	if (ent->locals.move_type == MOVE_TYPE_NO_CLIP) {
		G_SetAnimation(ent, ANIM_TORSO_STAND1, false);
		G_SetAnimation(ent, ANIM_LEGS_JUMP1, false);
		return;
	}

	// check for falling

	g_client_locals_t *cl = &ent->client->locals;
	if (!ent->locals.ground_entity) { // not on the ground

		if (g_level.time - cl->jump_time > 400) {
			if (ent->locals.water_level == 3 && cl->speed > 10.0) { // swimming
				G_SetAnimation(ent, ANIM_LEGS_SWIM, false);
				return;
			}
			if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducking
				G_SetAnimation(ent, ANIM_LEGS_IDLECR, false);
				return;
			}
		}

		_Bool jumping = G_IsAnimation(ent, ANIM_LEGS_JUMP1);
		jumping |= G_IsAnimation(ent, ANIM_LEGS_JUMP2);

		if (!jumping)
			G_SetAnimation(ent, ANIM_LEGS_JUMP1, false);

		return;
	}

	// duck, walk or run after landing

	if (g_level.time - 400 > cl->land_time && g_level.time - 50 > cl->ground_time) {

		if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducked
			if (cl->speed < 1.0)
				G_SetAnimation(ent, ANIM_LEGS_IDLECR, false);
			else
				G_SetAnimation(ent, ANIM_LEGS_WALKCR, false);

			return;
		}

		if (cl->speed < 1.0 && !cl->cmd.forward && !cl->cmd.right && !cl->cmd.up) {
			G_SetAnimation(ent, ANIM_LEGS_IDLE, false);
			return;
		}

		vec3_t angles, forward;

		VectorSet(angles, 0.0, ent->s.angles[YAW], 0.0);
		AngleVectors(angles, forward, NULL, NULL);

		if (DotProduct(ent->locals.velocity, forward) < -0.1)
			G_SetAnimation(ent, ANIM_LEGS_BACK, false);
		else if (cl->speed < 200.0)
			G_SetAnimation(ent, ANIM_LEGS_WALK, false);
		else
			G_SetAnimation(ent, ANIM_LEGS_RUN, false);

		return;
	}
}
コード例 #4
0
ファイル: g_client.c プロジェクト: darkshade9/aq2w
/*
 * G_ClientThink
 *
 * This will be called once for each client frame, which will usually be a
 * couple times for each server frame.
 */
void G_ClientThink(g_edict_t *ent, user_cmd_t *ucmd) {
	g_client_t *client;
	g_edict_t *other;
	int i, j;

	g_level.current_entity = ent;
	client = ent->client;

	if (g_level.intermission_time) {
		client->ps.pmove.pm_type = PM_FREEZE;
		return;
	}

	if (client->chase_target) { // ensure chase is valid

		client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;

		if (!client->chase_target->in_use
				|| client->chase_target->client->persistent.spectator) {

			other = client->chase_target;

			G_ChaseNext(ent);

			if (client->chase_target == other) { // no one to chase
				client->chase_target = NULL;
			}
		}
	}

	if (!client->chase_target) { // set up for pmove
		pm_move_t pm;

		client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;

		if (ent->move_type == MOVE_TYPE_NO_CLIP)
			client->ps.pmove.pm_type = PM_SPECTATOR;
		else if (ent->s.model1 != 255 || ent->dead)
			client->ps.pmove.pm_type = PM_DEAD;
		else
			client->ps.pmove.pm_type = PM_NORMAL;

		client->ps.pmove.gravity = g_level.gravity;

		memset(&pm, 0, sizeof(pm));
		pm.s = client->ps.pmove;

		for (i = 0; i < 3; i++) {
			pm.s.origin[i] = ent->s.origin[i] * 8.0;
			pm.s.velocity[i] = ent->velocity[i] * 8.0;
		}

		pm.cmd = *ucmd;

		pm.Trace = G_ClientMoveTrace; // adds default params
		pm.PointContents = gi.PointContents;

		// perform a pmove
		gi.Pmove(&pm);

		// save results of pmove
		client->ps.pmove = pm.s;

		for (i = 0; i < 3; i++) {
			ent->s.origin[i] = pm.s.origin[i] * 0.125;
			ent->velocity[i] = pm.s.velocity[i] * 0.125;
		}

		VectorCopy(pm.mins, ent->mins);
		VectorCopy(pm.maxs, ent->maxs);

		client->cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]);
		client->cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]);
		client->cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]);

		// check for jump, play randomized sound
		if (ent->ground_entity && !pm.ground_entity && (pm.cmd.up >= 10)
				&& (pm.water_level == 0) && client->jump_time < g_level.time
				- 0.2) {

			vec3_t angles, forward, velocity;
			float speed;

			VectorSet(angles, 0.0, ent->s.angles[YAW], 0.0);
			AngleVectors(angles, forward, NULL, NULL);

			VectorCopy(ent->velocity, velocity);
			velocity[2] = 0.0;

			speed = VectorNormalize(velocity);

			if (DotProduct(velocity, forward) < 0.0 && speed > 200.0)
				G_SetAnimation(ent, ANIM_LEGS_JUMP2, true);
			else
				G_SetAnimation(ent, ANIM_LEGS_JUMP1, true);

			ent->s.event = EV_CLIENT_JUMP;
			client->jump_time = g_level.time;
		}

		ent->view_height = pm.view_height;
		ent->water_level = pm.water_level;
		ent->water_type = pm.water_type;
		ent->ground_entity = pm.ground_entity;

		if (ent->ground_entity)
			ent->ground_entity_link_count = ent->ground_entity->link_count;

		VectorCopy(pm.angles, client->angles);
		VectorCopy(pm.angles, client->ps.angles);

		gi.LinkEntity(ent);

		// touch jump pads, hurt brushes, etc..
		if (ent->move_type != MOVE_TYPE_NO_CLIP && ent->health > 0)
			G_TouchTriggers(ent);

		// touch other objects
		for (i = 0; i < pm.num_touch; i++) {

			other = pm.touch_ents[i];

			for (j = 0; j < i; j++)
				if (pm.touch_ents[j] == other)
					break;

			if (j != i)
				continue; // duplicated

			if (!other->touch)
				continue;

			other->touch(other, ent, NULL, NULL);
		}
	}

	client->old_buttons = client->buttons;
	client->buttons = ucmd->buttons;
	client->latched_buttons |= client->buttons & ~client->old_buttons;

	// fire weapon if requested
	if (client->latched_buttons & BUTTON_ATTACK) {
		if (client->persistent.spectator) {

			client->latched_buttons = 0;

			if (client->chase_target) { // toggle chase camera
				client->chase_target = NULL;
				client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
			} else {
				G_ChaseTarget(ent);
			}
		} else if (client->weapon_think_time < g_level.time) {
			G_WeaponThink(ent);
		}
	}

	// update chase camera if being followed
	for (i = 1; i <= sv_max_clients->integer; i++) {

		other = g_game.edicts + i;

		if (other->in_use && other->client->chase_target == ent) {
			G_ChaseThink(other);
		}
	}

	G_ClientInventoryThink(ent);
}
コード例 #5
0
ファイル: g_client_view.c プロジェクト: jayschwa/quake2world
/*
 * @brief Sets the animation sequences for the specified entity. This is called
 * towards the end of each frame, after our ground entity and water level have
 * been resolved.
 */
static void G_ClientAnimation(g_edict_t *ent) {

	if (ent->sv_flags & SVF_NO_CLIENT)
		return;

	// no-clippers do not animate

	if (ent->locals.move_type == MOVE_TYPE_NO_CLIP) {
		G_SetAnimation(ent, ANIM_TORSO_STAND1, false);
		G_SetAnimation(ent, ANIM_LEGS_JUMP1, false);
		return;
	}

	// check for falling

	g_client_locals_t *cl = &ent->client->locals;
	if (!ent->locals.ground_entity) { // not on the ground

		if (g_level.time - cl->jump_time > 400) {
			if (ent->locals.water_level == 3 && cl->speed > 10.0) { // swimming
				G_SetAnimation(ent, ANIM_LEGS_SWIM, false);
				return;
			}
			if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducking
				G_SetAnimation(ent, ANIM_LEGS_IDLECR, false);
				return;
			}
		}

		_Bool jumping = G_IsAnimation(ent, ANIM_LEGS_JUMP1);
		jumping |= G_IsAnimation(ent, ANIM_LEGS_JUMP2);

		if (!jumping)
			G_SetAnimation(ent, ANIM_LEGS_JUMP1, false);

		return;
	}

	// duck, walk or run after landing

	if (g_level.time - 400 > cl->land_time && g_level.time - 50 > cl->ground_time) {

		if (ent->client->ps.pm_state.flags & PMF_DUCKED) { // ducked
			if (cl->speed < 1.0)
				G_SetAnimation(ent, ANIM_LEGS_IDLECR, false);
			else
				G_SetAnimation(ent, ANIM_LEGS_WALKCR, false);

			return;
		}

		if (cl->speed < 1.0 && !cl->cmd.forward && !cl->cmd.right && !cl->cmd.up) {
			G_SetAnimation(ent, ANIM_LEGS_IDLE, false);
			return;
		}

		vec3_t angles, forward;

		VectorSet(angles, 0.0, ent->s.angles[YAW], 0.0);
		AngleVectors(angles, forward, NULL, NULL);

		if (DotProduct(ent->locals.velocity, forward) < -0.1)
			G_SetAnimation(ent, ANIM_LEGS_BACK, false);
		else if (cl->speed < 200.0)
			G_SetAnimation(ent, ANIM_LEGS_WALK, false);
		else
			G_SetAnimation(ent, ANIM_LEGS_RUN, false);

		return;
	}
}