Beispiel #1
0
void AllyID (edict_t *ent)
{
	vec3_t	forward, right, offset, start, end;
	trace_t tr;
	edict_t *e=NULL;

	if (!allies->value)
		return;
	if (!numAllies(ent))
		return;

	// find entity near crosshair
	AngleVectors (ent->client->v_angle, forward, right, NULL);
	VectorSet(offset, 0, 7,  ent->viewheight-8);
	P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
	VectorMA(start, 8192, forward, end);
	tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT);

	if (tr.ent)
		e = tr.ent;

	if (e && e->inuse && (e->health > 0) && (level.time > ent->msg_time))
	{
		if (PM_MonsterHasPilot(e))
			e = e->owner;
		else if (!e->client)
			return;

		if (IsAlly(ent, e))
		{
			gi.centerprintf(ent, "Ally: %s\n", e->client->pers.netname);
			ent->msg_time = level.time + 5;
		}
	}
}
Beispiel #2
0
void CurseMessage (edict_t *caster, edict_t *target, int type, float duration, qboolean isCurse)
{
	char *curseName = GetCurseName(type);
	char *typeName;

	if (isCurse)
		typeName = "cursed";
	else
		typeName = "blessed";

	//Notify the target
	if ((target->client) && !(target->svflags & SVF_MONSTER))
	{
		gi.cprintf(target, PRINT_HIGH, "**You have been %s with %s for %0.1f second(s)**\n", typeName, curseName, duration);
		if (caster && caster->client)
			gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, target->myskills.player_name, curseName, duration);
	}
	else if (target->mtype)
	{
		if (PM_MonsterHasPilot(target))
		{
			gi.cprintf(target->activator, PRINT_HIGH, "**You have been %s with %s for %0.1f second(s)**\n", typeName, curseName, duration);
			if (caster && caster->client)
				gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, target->activator->client->pers.netname, curseName, duration);
			return;
		}

		if (caster && caster->client)
			gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, V_GetMonsterName(target), curseName, duration);
	}
	else if (caster && caster->client)
		gi.cprintf(caster, PRINT_HIGH, "%s %s with %s for %0.1f second(s)\n", typeName, target->classname, curseName, duration);
}
Beispiel #3
0
void wormhole_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	if (!other || !other->inuse)
		return;

	// point to monster's pilot
	if (PM_MonsterHasPilot(other))
		other = other->activator;

	if ((other == self->creator) || IsAlly(self->creator, other))
	{
		float time;
		
		// can't enter wormhole with the flag
		if (HasFlag(other))
			return;
		
		// can't enter wormhole while being hurt
		if (other->lasthurt + DAMAGE_ESCAPE_DELAY > level.time)
			return;
		
		// can't enter wormhole while cursed (this includes healing, bless)
		if (que_typeexists(other->curses, -1))
			return;

		// can't stay in wormhole long if we're warring
		if (SPREE_WAR == true && SPREE_DUDE == other)
			time = 10.0;
		else
			time = BLACKHOLE_EXIT_TIME;

		// reset railgun sniper frames
		other->client->refire_frames = 0;

		VortexRemovePlayerSummonables(other);
		V_RestoreMorphed(other, 50); // un-morph

		other->flags |= FL_WORMHOLE;
		other->movetype = MOVETYPE_NOCLIP;
		other->svflags |= SVF_NOCLIENT;
		other->client->wormhole_time = level.time + BLACKHOLE_EXIT_TIME; // must exit wormhole by this time

		self->nextthink = level.time + FRAMETIME; // close immediately
	}
}
Beispiel #4
0
void minisentry_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	V_Touch(self, other, plane, surf);

	//4.2 if this is a player-monster (morph), then we should be looking at the client/player
	if (PM_MonsterHasPilot(other))
		other = other->activator;

	if (other && other->inuse && (other == self->creator) && (level.time > self->random))
	{
		safe_cprintf(self->creator, PRINT_HIGH, "Rotating sentry gun 45 degrees.\n");

		VectorCopy(self->move_angles, self->s.angles); // reset angles to default
		self->s.angles[YAW]+=45;
		ValidateAngles(self->s.angles);
		VectorCopy(self->s.angles, self->move_angles); // update default angles
		self->random = level.time + 1;
		self->nextthink = level.time + 2;
	}
}
Beispiel #5
0
void UpdateChaseCam (edict_t *ent)
{
	int			i;
	edict_t		*old, *targ;
	vec3_t		start, goal;
	vec3_t		angles, forward, right;
	trace_t		tr;
	qboolean	eyecam=false;
	
	if (!ent->client->chase_target)
		return;
	if (!G_IsSpectator(ent))
		return;

	//gi.dprintf("updating chase for %s\n", ent->client->pers.netname);

	// is our chase target no longer valid?
	if (!IsValidChaseTarget(ent->client->chase_target))
	{
		old = ent->client->chase_target;
		ChaseNext(ent); // try to find a new chase target
		if (ent->client->chase_target == old) 
		{
			// switch out of chase-cam mode
			ent->client->chase_target = NULL;
			ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
			ent->client->ps.pmove.pm_flags &= ~PMF_DUCKED; // quit ducked.
			return;
		}
	}

	
	targ = ent->client->chase_target;

	if (PM_MonsterHasPilot(targ))
		targ = targ->owner;

	VectorCopy(targ->s.origin, start);

	// use client's viewing angle
	if (targ->client)
		VectorCopy(targ->client->v_angle, angles);
	// use pilot's viewing angle
	/*
	else if (PM_MonsterHasPilot(targ))
	{
		VectorCopy(targ->owner->s.origin, start);
		VectorCopy(targ->owner->client->v_angle, angles);
	}
	*/
	// use non-client's angles
	else
		VectorCopy(targ->s.angles, angles);

	if (ent->client->chasecam_mode)
		eyecam = true;

	// if we're chasing a non-client entity that has a valid enemy
	// within our sights, then modify our viewing pitch
	if (eyecam && !targ->client && G_ValidTarget(targ, targ->enemy, true) 
		&& infov(targ, targ->enemy, 90))
	{
		VectorSubtract(targ->enemy->s.origin, targ->s.origin, forward);
		vectoangles(forward, forward);
		angles[PITCH] = forward[PITCH];
		//gi.dprintf("pitch %d\n", (int)forward[PITCH]);
	}

	if (!eyecam)
	{
		if (angles[PITCH] > 56)
			angles[PITCH] = 56;
		if (angles[PITCH] < -56)
			angles[PITCH] = -56;
	}

	AngleVectors (angles, forward, right, NULL);
	VectorNormalize(forward);

	if (eyecam)
	{
		// save current player fov
		float fov = ent->client->ps.fov;

		if (targ->viewheight)
			start[2] += targ->viewheight;
		else
			start[2] = targ->absmax[2]-8;
		VectorMA(start, targ->maxs[1]+16, forward, start);
		// update HUD
		if (targ->client)
			ent->client->ps = targ->client->ps;
		else
			ent->client->ps.gunindex = 0;
		// restore player's fov (don't use target's fov)
		ent->client->ps.fov = fov;
	}
	else
	{
		ent->client->ps.gunindex = 0;

		// special conditions for upside-down minisentry
		if (targ->owner && (targ->mtype == M_MINISENTRY) 
			&& (targ->owner->style == SENTRY_FLIPPED))
		{
			start[2] = targ->absmin[2]-16;
		}
		else
		{
			if (targ->viewheight)
				start[2] += targ->viewheight;
			else
				start[2] = targ->absmax[2]-8;
			VectorMA(start, targ->mins[1]-16, forward, start);
		}
	}

	// jump animation lifts
	if (!targ->groundentity)
		start[2] += 16;
	tr = gi.trace(targ->s.origin, NULL, NULL, start, targ, MASK_SOLID);
	VectorCopy(tr.endpos, start);
	if (tr.fraction < 1)
	{
		if (eyecam)
			VectorMA(start, -12, forward, start);
		else
			VectorMA(start, 12, forward, start);
	}
	VectorCopy(start, goal);

	// pad for floors and ceilings
	VectorCopy(goal, start);
	start[2] += 6;
	tr = gi.trace(goal, vec3_origin, vec3_origin, start, targ, MASK_SOLID);
	if (tr.fraction < 1) {
		VectorCopy(tr.endpos, goal);
		goal[2] -= 6;
	}

	VectorCopy(goal, start);
	start[2] -= 6;
	tr = gi.trace(goal, vec3_origin, vec3_origin, start, targ, MASK_SOLID);
	if (tr.fraction < 1) {
		VectorCopy(tr.endpos, goal);
		goal[2] += 6;
	}

	if (targ->deadflag)
		ent->client->ps.pmove.pm_type = PM_DEAD;
	else
		ent->client->ps.pmove.pm_type = PM_FREEZE;

	VectorCopy(goal, ent->s.origin);
	for (i=0 ; i<3 ; i++) {
		ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(angles[i] - ent->client->resp.cmd_angles[i]);
	}


	if (targ->deadflag) 
	{
		ent->client->ps.viewangles[ROLL] = 40;
		ent->client->ps.viewangles[PITCH] = -15;
		if (targ->client)
			ent->client->ps.viewangles[YAW] = targ->client->killer_yaw;
		else
			ent->client->ps.viewangles[YAW] = 0;
	} 
	else 
	{
		VectorCopy(angles, ent->client->ps.viewangles);
		VectorCopy(angles, ent->client->v_angle);
	}

	ent->viewheight = 0;
	ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
	gi.linkentity(ent);
}
Beispiel #6
0
void PlayerID_SetStats (edict_t *player, edict_t *target, qboolean chasecam)
{
	int		health, armor=0, ammo=0, lvl=0;
	float	dist;
	char	name[24], buf[100];
	int		team_status=0;

	dist = entdist(player, target);
	health = target->health;
	
	team_status = OnSameTeam(player, target);

	if (target->client)
	{
		sprintf(name, target->client->pers.netname);
		armor = target->client->pers.inventory[body_armor_index];
		ammo = target->client->pers.inventory[target->client->ammo_index];
		lvl = target->myskills.level;
	}
	else 
	{
		name[0] = 0;

		// name
		if (PM_MonsterHasPilot(target))
			strcat(name, target->owner->client->pers.netname);
		else if (target->mtype)
			strcat(name, V_GetMonsterName(target));
		else
			strcat(name, target->classname);

		// armor
		if (target->monsterinfo.power_armor_type)
			armor = target->monsterinfo.power_armor_power;
		
		// ammo
		if (target->mtype && (target->mtype == M_SENTRY || target->mtype == M_AUTOCANNON))
			ammo = target->light_level;
		
		// level
		if (target->monsterinfo.level > 0)
			lvl = target->monsterinfo.level;
	}

	// initialize the string by terminating it, required by strcat()
	buf[0] = 0;

	if (chasecam)
		strcat(buf, va("Chasing "));

	// build the string
	strcat(buf, va("%s ", name));
	if (team_status > 1)
		V_SetColorText(buf);

	strcat(buf, va("(%d) ", lvl));

	if (!chasecam)
	{
		// newbies get a very basic free ID
		if (player->myskills.abilities[ID].current_level < 1)
		{
			if (M_IgnoreInferiorTarget(target, player) && !team_status)
				strcat(buf, "is ignoring you");
		}
		else
		{
			strcat(buf, va("@ %.0f", dist));
			strcat(buf, va(": %dh", health));
			if (armor)
				strcat(buf, va("/%da", armor));
			if (ammo)
				strcat(buf, va("/%d", ammo));
		}
	}

	// set stat to the configstring's index
	// this is the index to the string we just made
	player->client->ps.stats[STAT_CHASE] = CS_GENERAL + 1;

	gi.WriteByte (13);//svc_configstring
	gi.WriteShort (CS_GENERAL + 1);
	gi.WriteString (buf);// put the string in the configstring list
	gi.unicast (player, false);// announce to this player only
}
Beispiel #7
0
/*
===============
G_CheckChaseStats
===============
*/
void G_CheckChaseStats (edict_t *ent)
{
	int i;
	gclient_t *cl;

	//GHz START
	// set stats for non-client targets
	if (ent->client->chase_target && !ent->client->chase_target->client)
	{
		// player-monster chase stats
		if (PM_MonsterHasPilot(ent->client->chase_target))
		{
			// use stats of the monster's owner
			memcpy(ent->client->ps.stats, ent->client->chase_target->owner->client->ps.stats, 
				sizeof(ent->client->ps.stats));
			G_SetSpectatorStats(ent);

			// set a configstring to the player's name
			//gi.configstring (CS_GENERAL+(ent-g_edicts-1), 
			//	va("Chasing %s", ent->client->chase_target->owner->client->pers.netname));
			// set stat to the configstring's index
			//ent->client->ps.stats[STAT_CHASE] = CS_GENERAL+(ent-g_edicts-1);
		}
		else
		{
			if (ent->client->chase_target->health <= 999)
				ent->client->ps.stats[STAT_HEALTH] = ent->client->chase_target->health;
			else
				ent->client->ps.stats[STAT_HEALTH] = 666;

			if (ent->client->chase_target->monsterinfo.power_armor_power)
			{
				ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex("i_powershield");
				ent->client->ps.stats[STAT_ARMOR] = ent->client->chase_target->monsterinfo.power_armor_power;
			}
			else
			{
				ent->client->ps.stats[STAT_ARMOR_ICON] = 0;
				ent->client->ps.stats[STAT_ARMOR] = 0;
			}
			// monsters don't have ammo
			ent->client->ps.stats[STAT_AMMO_ICON] = 0;
			ent->client->ps.stats[STAT_AMMO] = 0;
			// set a configstring to the monster's classname
			//if (ent->client->chase_target->mtype)
			//	gi.configstring (CS_GENERAL+(ent-g_edicts-1), va("Chasing %s (%d)", 
			//		V_GetMonsterName(ent->client->chase_target), ent->client->chase_target->monsterinfo.level));
			//else
			//	gi.configstring (CS_GENERAL+(ent-g_edicts-1), va("Chasing %s", ent->client->chase_target->classname));
			// set stat to the configstring's index
			//ent->client->ps.stats[STAT_CHASE] = CS_GENERAL+(ent-g_edicts-1);
		}
		return; // since this player has a chase target, it must be a spectator which can't be chased!
	}
	//GHz END
	for (i = 1; i <= maxclients->value; i++) {
		cl = g_edicts[i].client;
		if (!g_edicts[i].inuse || cl->chase_target != ent)
			continue;
		if (ent->client->pers.weapon)
			ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
		memcpy(cl->ps.stats, ent->client->ps.stats, sizeof(cl->ps.stats));
		G_SetSpectatorStats(g_edicts + i);
	}
}