コード例 #1
0
ファイル: cg_demos_effects.c プロジェクト: entdark/q3mme
void demoEffectMove( void ) {
	float *origin, *angles, *size, *color;
	demoEffectParent_t *parent;
	if (!demo.effect.active)
		return;

	parent = demo.effect.active;
	if (!parent->locked ) {
		origin = parent->origin;
		angles = parent->angles;
		color = parent->color;
		size = &parent->size;
	} else {
		demoEffectPoint_t * point = demoEffectPointSynch( parent, demo.play.time );
		if ( !point || point->time != demo.play.time || demo.play.fraction) 
			return;
		origin = point->origin;
		angles = point->angles;
		color = point->color;
		size = &point->size;
	}

	if (demo.cmd.buttons & BUTTON_ATTACK) {
		vec3_t moveAngles;
		/* First clear some related values */
		if (!(demo.oldcmd.buttons & BUTTON_ATTACK)) {
			VectorClear( parent->velocity );
		}
		if (demo.cmd.upmove > 0) {
			angles[ROLL] -= demo.cmd.angles[YAW];
			AnglesNormalize180( angles );
			return;
		}
		VectorAdd( angles, demo.cmdDeltaAngles, angles );
		AnglesNormalize180( angles );
		VectorCopy( angles, moveAngles );
		moveAngles[ROLL] = 0;
		demoMovePoint( origin, parent->velocity, moveAngles );
	} else if (demo.cmd.upmove > 0) {
		*size -= demo.serverDeltaTime * 700 * demo.cmdDeltaAngles[YAW];
		if (*size < 0)
			*size = 0;
	} else if ( (demo.cmd.upmove < 0) || (demo.cmd.forwardmove < 0) || (demo.cmd.rightmove < 0)  ) {
		vec3_t moveAngles;
		VectorCopy( angles, moveAngles );
		moveAngles[ROLL] = 0;
		demoMoveDirection( origin, moveAngles );
	}

}
コード例 #2
0
ファイル: cg_demos_move.c プロジェクト: entdark/q3mme
void demoMoveAddDeltaAngles( vec3_t angles ) {
	if (demo.cmd.buttons & BUTTON_NEGATIVE) {
		angles[ROLL] -= demo.cmdDeltaAngles[YAW];
	} else {
		VectorAdd( angles, demo.cmdDeltaAngles, angles);
	}
	AnglesNormalize180( angles );
}
コード例 #3
0
ファイル: cg_demos_move.c プロジェクト: entdark/q3mme
void demoMoveChaseDirect( void ) {
	if (demo.chase.locked)
		return;
	if (!(demo.oldcmd.buttons & BUTTON_ATTACK)) {
		VectorClear( demo.chase.velocity );
	}
	VectorAdd( demo.chase.angles, demo.cmdDeltaAngles, demo.chase.angles );
	AnglesNormalize180( demo.chase.angles );
	demoMovePoint( demo.chase.origin, demo.chase.velocity, demo.chase.angles );
}
コード例 #4
0
ファイル: cg_demos_move.c プロジェクト: entdark/q3mme
void demoMoveChase(void) {
	float *origin;
	float *distance;
	float *angles;
	int	*target;

	if (demo.chase.locked) {
		demoChasePoint_t * point = chasePointSynch( demo.play.time );
		if ( point && point->time == demo.play.time && !demo.play.fraction) {
			origin = point->origin;
			angles = point->angles;
			distance = &point->distance;
			target = &point->target;
		} else
			return;
	} else {
		origin = demo.chase.origin;
		angles = demo.chase.angles;
		distance = &demo.chase.distance;
		target = &demo.chase.target;
	}
	if (demo.cmd.buttons & BUTTON_ATTACK) {
		/* First clear some related values */
		if (!(demo.oldcmd.buttons & BUTTON_ATTACK)) {
			VectorClear( demo.chase.velocity );
		}
		VectorAdd( angles, demo.cmdDeltaAngles, angles );
		AnglesNormalize180( angles );
		demoMovePoint( origin, demo.chase.velocity, angles );
	} else if (demo.cmd.buttons & BUTTON_AFFIRMATIVE && !(demo.oldcmd.buttons & BUTTON_AFFIRMATIVE)) {
		VectorCopy( demo.viewOrigin, origin );
		VectorCopy( demo.viewAngles, angles );
		CG_DemosAddLog("Chase position synced to current view");
	} else if ( demo.cmd.upmove > 0) {
		*distance -= demo.serverDeltaTime * 700 * demo.cmdDeltaAngles[YAW];
		if (*distance < 0)
			*distance = 0;
	} else if ( (demo.cmd.upmove < 0) || (demo.cmd.forwardmove < 0) || (demo.cmd.rightmove < 0)  ) {
		demoMoveDirection( origin, angles );
	} else if (demo.cmd.rightmove < 0) {
		int shift;
		demo.chase.timeShift -= demo.serverDeltaTime * 1000 * demo.cmdDeltaAngles[YAW];
		shift = (int)demo.chase.timeShift;
		demo.chase.timeShift -= shift;
		chasePointShift( shift );
	}
}
コード例 #5
0
ファイル: cg_demos_move.c プロジェクト: entdark/q3mme
void demoChaseCommand_f(void) {
	const char *cmd = CG_Argv(1);
	if (!Q_stricmp(cmd, "lock")) {
		demo.chase.locked = !demo.chase.locked;
		if (demo.chase.locked) 
			CG_DemosAddLog("Chase view locked");
		else 
			CG_DemosAddLog("Chase view unlocked");
	} else if (!Q_stricmp(cmd, "add")) {
		if (chasePointAdd( demo.play.time, demo.chase.angles, demo.chase.distance, demo.chase.target, demo.chase.origin )) {
			CG_DemosAddLog("Added chase point" );
		} else {
			CG_DemosAddLog("Failed to add chase point" );
		}
	} else if (!Q_stricmp(cmd, "del")) {
		if (chasePointDel( demo.play.time) ) {
			CG_DemosAddLog("Deleted chase chase point" );
		} else {
			CG_DemosAddLog("Failed to add delete chase point" );
		}
	} else if (!Q_stricmp(cmd, "start")) { 
		demo.chase.start = demo.play.time;
		if (demo.chase.start > demo.chase.end)
			demo.chase.start = demo.chase.end;
		if (demo.chase.end == demo.chase.start)
			CG_DemosAddLog( "Cleared chase selection");
		else
			CG_DemosAddLog( "Chase selection start at %d.%03d", demo.chase.start / 1000, demo.chase.start % 1000 );
	} else if (!Q_stricmp(cmd, "end")) { 
		demo.chase.end = demo.play.time;
		if (demo.chase.end < demo.chase.start)
			demo.chase.end = demo.chase.start;
		if (demo.chase.end == demo.chase.start)
			CG_DemosAddLog( "Cleared chase selection");
		else
			CG_DemosAddLog( "Chase selection end at %d.%03d", demo.chase.end / 1000, demo.chase.end % 1000 );
	} else if (!Q_stricmp(cmd, "next")) {
		demoChasePoint_t *point = chasePointSynch( demo.play.time );
		if ( demo.cmd.upmove > 0) {
			if ( demo.chase.locked ) {
				CG_DemosAddLog( "Can't change target when locked");
			} else {
				chaseNextTarget( &demo.chase.target );
			}
			return;
		}
		if (!point)
			return;
		if (point->next)
			point = point->next;
		demo.play.time = point->time;
		demo.play.fraction = 0;
	} else if (!Q_stricmp(cmd, "prev")) {
		demoChasePoint_t *point = chasePointSynch( demo.play.time );
		if ( demo.cmd.upmove > 0 ) {
			if ( demo.chase.locked ) {
				CG_DemosAddLog( "Can't change target when locked");
			} else {
				chasePrevTarget( &demo.chase.target );
			}
			return;
		}
		if (!point)
			return;
		if (point->prev)
			point = point->prev;
		demo.play.time = point->time;
		demo.play.fraction = 0;
	} else if (!Q_stricmp(cmd, "clear")) {
		chaseClear();
	} else if (!Q_stricmp(cmd, "targetPrev")) {
		chasePrevTarget( &demo.chase.target );
	} else if (!Q_stricmp(cmd, "targetNext")) {
		chaseNextTarget( &demo.chase.target );
	} else if (!Q_stricmp(cmd, "target")) {
		float *angles, *origin, *distance;
		int *target;
		if (demo.chase.locked) {
			demoChasePoint_t *point = chasePointSynch( demo.play.time );
			if (!point || point->time != demo.play.time || demo.play.fraction ) {
				Com_Printf("Can't synch when not synched to a point\n");
				return;
			}
			origin = point->origin;
			angles = point->angles;
			target = &point->target;
			distance = &point->distance;
		} else {
			origin = demo.chase.origin;
			angles = demo.chase.angles;
			target = &demo.chase.target;
			distance = &demo.chase.distance;
		}
		if ( demo.cmd.buttons & BUTTON_ATTACK ) {
			if (*target>=0) {
				CG_DemosAddLog("Cleared target %d", *target );
				*target = -1;
			} else {
				vec3_t forward;
				AngleVectors( demo.viewAngles, forward, 0, 0 );
				*target = demoHitEntities( demo.viewOrigin, forward );
				if (*target >= 0) {
					vec3_t targetAngles;
					chaseEntityOrigin( &cg_entities[*target], origin);
					*distance = VectorDistance( demo.viewOrigin, origin );
					VectorSubtract( origin, demo.viewOrigin, forward );
					vectoangles( forward, targetAngles );
					angles[PITCH] = targetAngles[PITCH];
					angles[YAW] = targetAngles[YAW];
					CG_DemosAddLog("Target set to %d", *target );
				} else {
					CG_DemosAddLog("Unable to hit any target" );
				}
			}
		} else {
			CG_DemosAddLog( "Chase synched to current view" );
			*target = -1;
			*distance = 128;
			VectorCopy( demo.viewOrigin, origin );
			VectorCopy( demo.viewAngles, angles );
		}
	} else if (!Q_stricmp(cmd, "pos")) {
		float *oldOrigin;
		if (demo.chase.locked) {
			demoChasePoint_t *point = chasePointSynch( demo.play.time );
			if (!point || point->time != demo.play.time || demo.play.fraction ) {
				Com_Printf("Can't change position when not synched to a point\n");
				return;
			}
			oldOrigin = point->origin;
		} else {
			oldOrigin = demo.chase.origin;
		}
		demoCommandValue( CG_Argv(2), oldOrigin );
		demoCommandValue( CG_Argv(3), oldOrigin+1 );
		demoCommandValue( CG_Argv(4), oldOrigin+2 );
	} else if (!Q_stricmp(cmd, "angles")) {
		float *oldAngles;
		if (demo.chase.locked) {
			demoChasePoint_t *point = chasePointSynch( demo.play.time );
			if (!point || point->time != demo.play.time || demo.play.fraction ) {
				Com_Printf("Can't change angles when not synched to a point\n");
				return;
			}
			oldAngles = point->angles;
		} else {
			oldAngles = demo.chase.angles;
		}
		demoCommandValue( CG_Argv(2), oldAngles );
		demoCommandValue( CG_Argv(3), oldAngles+1 );
		demoCommandValue( CG_Argv(4), oldAngles+2 );
		AnglesNormalize180( oldAngles );
	} else if (!Q_stricmp(cmd, "dist") || !Q_stricmp(cmd, "distance")) {
		if (demo.chase.locked) {
			demoChasePoint_t *point = chasePointSynch( demo.play.time );
			if (!point || point->time != demo.play.time || demo.play.fraction ) {
				Com_Printf("Can't change distance when not synched to a point\n");
				return;
			}
			demoCommandValue( CG_Argv(2), &point->distance );
		} else {
			demoCommandValue( CG_Argv(2), &demo.chase.distance );
		}
	} else if (!Q_stricmp(cmd, "shift")) {
		int shift = 1000 * atof(CG_Argv(2));
		demo.chase.shiftWarn = 0;
		if (chasePointShift( shift )) {
			CG_DemosAddLog( "Shifted %d.%03d seconds", shift / 1000, shift % 1000);
		}
	} else {
		Com_Printf("chase usage:\n" );
		Com_Printf("chase add/del, add/del a chase point at current viewpoint and time.\n" );
		Com_Printf("chase clear, clear all chase points. (Use with caution...)\n" );
		Com_Printf("chase lock, lock the view to chase track or free moving.\n" );
		Com_Printf("chase target, Clear/Set the target currently being aimed at.\n" );
		Com_Printf("chase targetNext/Prev, Go the next or previous player.\n" );
		Com_Printf("chase shift time, move time indexes of chase points by certain amount.\n" );
		Com_Printf("chase next/prev, go to time index of next or previous point.\n" );
		Com_Printf("chase start/end, current time with be set as start/end of selection.\n" );
		Com_Printf("chase pos/angles (a)0 (a)0 (a)0, Directly control position/angles, optional a before number to add to current value\n" );
	}
}
コード例 #6
0
/*
 * Tests whether the player entity ent is visible from the point origin.
 */
qboolean SV_IsPlayerVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame, sharedEntity_t *ent, vec3_t diff) {
	int      i,contents_mask,goal_ent,viewer_clnum,ent_clnum,tries;
	trace_t   tr;
	vec3_t   start,end,dir,entangles,angles,temp,forward;
	sharedEntity_t *viewer_ent;
	client_t *viewer_cl;
//	client_t *ent_cl;
	playerState_t *viewer_ps, *ent_ps;
	float pitch;

	viewer_clnum = frame->ps.clientNum; // get the client number of the viewer
	ent_clnum = ent->s.clientNum; // get the client number of the other player

	if (viewer_clnum == ent_clnum) { // in case the viewer is the player entity
		return qtrue; // we don't need to hide us from ourselves
	}

	viewer_ps = &frame->ps;
	ent_ps = SV_GameClientNum(ent_clnum);

	if (viewer_ps->pm_type != PM_NORMAL) { // if the viewer is dead or spectating
		return qtrue; // let every entity be visible
	}

	if (ent_ps->pm_type != PM_NORMAL || (ent->s.weapon == WP_NONE)) { // if the player entity is dead or spectating
		return qtrue;
	}

	viewer_cl = svs.clients+viewer_clnum; // get the client of the viewer
//	ent_cl = svs.clients+ent_clnum; // get the client of the other player

//	if (viewer_clnum > ent_clnum) { // if viewer_clnum > ent_clnum, we have already tested whether ent_clnum is able to see viewer_clnum.
//		if (ent_cl->tracetimer[viewer_clnum] > sv.time) return qtrue; // and we could assume symmetry of SV_IsPlayerVisibleFromPoint
//	}

	if (viewer_cl->tracetimer[ent_clnum] > sv.time+MEMORY+10) { // if the sv.time has been reset
		viewer_cl->tracetimer[ent_clnum] = sv.time; // reset the tracetimer
	} else if (viewer_cl->tracetimer[ent_clnum] > (sv.time+MEMORY-10)) { // if we have recently seen this entity, we are lazy and assume it is still visible
		// Com_Printf(va("client: %i, seen: %i\n", ent_clnum, viewer_cl->tracetimer[ent_clnum]));
		return qtrue;
	}

	goal_ent = SV_NumForGentity(ent); // this might always be the same as ent_clnum
	viewer_ent = SV_GentityNum(viewer_clnum);
	contents_mask = CONTENTS_SOLID;// |CONTENTS_BODY will work for doors, but also for windows  |CONTENTS_PLAYERCLIP|CONTENTS_SOLID|CONTENTS_MOVER|CONTENTS_PLAYERCLIP

//	if (seen->v.movetype == MOVETYPE_PUSH ) { //don't cull doors and plats :(
//		return false;
//	}

//	if (sv_antiwallhack.value == 1)    //1 only check player models, 2 = check all ents
//	if (strcmp(pr_strings + seen->v.classname, "player"))
//	return qfalse;

	// get camera origin (according to \cg_drawdebug 1)
	start[0] = origin[0];
	start[1] = origin[1];
	start[2] = origin[2]+3.0f;
	VectorCopy(viewer_ps->viewangles, angles);
	AnglesNormalize180(angles);
	pitch = angles[PITCH];
	angles[PITCH] = 0;
	angles[ROLL] = 0;
	AngleVectors(angles, forward, NULL, NULL);
	VectorScale(forward, (pitch/3.5f), temp);
	VectorAdd( start, temp, start);

	// if there is sufficient distance between viewer and player entity, check if player entity is within viewer's field of vision
	VectorSubtract(ent->r.currentOrigin, start, dir);
//	VectorAdd(ent->r.currentOrigin,dir,diff);// fill diff
	VectorCopy(viewer_ent->s.pos.trBase,diff);// fill diff
	vectoangles(dir, entangles);
	dir[2]=0; // pretend, players are on the same level (the height should no be taken into account)
	if (VectorLength(dir) > 1024) {// if it is not within close range (x,y-wise, not z-wise)
		if (!InFieldOfVision(viewer_ps->viewangles, 60.f, entangles, ent_clnum)) {// If the player entity is not in the field of vision of the viewer
//			 Com_Printf( va("behind: %i  vorg: %f,%f,%f  vang: %f,%f,%f  eorg: %f,%f,%f  dir: %f,%f,%f  eang: %f,%f,%f  ent: %i\n", viewer_clnum,origin[0],origin[1],origin[2],viewer_ps->viewangles[0],viewer_ps->viewangles[1],viewer_ps->viewangles[2],ent->r.currentOrigin[0],ent->r.currentOrigin[1],ent->r.currentOrigin[2],dir[0],dir[1],dir[2],entangles[0],entangles[1],entangles[2],ent_clnum));
			return qtrue; // if the player entity is behind the viewer, abstain from any computations (and transmit the entity to hear sounds)
//		} else {
//			 Com_Printf( va("front: %i  vorg: %f,%f,%f  vang: %f,%f,%f  eorg: %f,%f,%f  dir: %f,%f,%f  eang: %f,%f,%f  ent: %i\n", viewer_clnum,origin[0],origin[1],origin[2],viewer_ps->viewangles[0],viewer_ps->viewangles[1],viewer_ps->viewangles[2],ent->r.currentOrigin[0],ent->r.currentOrigin[1],ent->r.currentOrigin[2],dir[0],dir[1],dir[2],entangles[0],entangles[1],entangles[2],ent_clnum));
		}
	}

	// aim straight at the head of the entity from our eyes
	end[0] = ent->r.currentOrigin[0];
	end[1] = ent->r.currentOrigin[1];
	end[2] = ent->r.currentOrigin[2]+ent->r.maxs[2];// "+3.0f" doesn't do it. "+ent->r.maxs[2]" is at the top of the BBox
	VectorCopy(ent_ps->viewangles, angles);
	AnglesNormalize180(angles);
	pitch = angles[PITCH];
	angles[PITCH] = 0;
	angles[ROLL] = 0;
	AngleVectors(angles, forward, NULL, NULL);
	VectorScale(forward, (pitch/3.5f), temp);
	VectorAdd( end, temp, end);



	memset (&tr, 0, sizeof(tr));
	tr.fraction = 1;

	// check the head
	SV_Trace(&tr, start, NULL, NULL, end, viewer_clnum, contents_mask, qfalse);
	// Com_Printf(va("client: %i, trace: %f\n", ent->s.clientNum, tr.fraction));
	if (tr.fraction == 1 || tr.entityNum==goal_ent) {// tr.fraction == 1 || if there is a line of sight to the entity
		viewer_cl->tracetimer[ent_clnum] = sv.time + MEMORY;// update the trace timer so the entity will be visible the next 200 time units
		return qtrue;// and signal the entity is visible
	}
	// Com_Printf(va("origin(%f %f %f) min(%f %f %f) max(%f %f %f)\n", start[0], start[1], start[2], mins[0],mins[1],mins[2],maxs[0],maxs[1],maxs[2]));

	// check the last good offset
	VectorAdd(ent->r.currentOrigin,viewer_cl->lasttrace[ent_clnum],end);
	SV_Trace(&tr, start, NULL, NULL, end, viewer_clnum, contents_mask, qfalse);
	// Com_Printf(va("client: %i, trace: %f\n", ent->s.clientNum, tr.fraction));
	if (tr.fraction == 1 || tr.entityNum==goal_ent) {// tr.fraction == 1 || if there is a line of sight to the entity
		viewer_cl->tracetimer[ent_clnum] = sv.time + MEMORY;// update the trace timer so the entity will be visible the next 200 time units
		return qtrue;// and signal the entity is visible
	}

	// random
	tries = (viewer_cl->tracetimer[ent_clnum]+(MEMORY*20) > sv.time)?8:2;// if we have seen an entity recently, we try hard to locate it again
	for (i=0; i<tries; i++) {// Even if the head is not visible, other body parts might be. Let's check a few randomly selected points
		end[0] = ent->r.currentOrigin[0] + offsetrandom(ent->r.mins[0], ent->r.maxs[0]);
		end[1] = ent->r.currentOrigin[1] + offsetrandom(ent->r.mins[1], ent->r.maxs[1]);
		end[2] = ent->r.currentOrigin[2] + offsetrandom(ent->r.mins[2], ent->r.maxs[2]+3.f);

		SV_Trace(&tr, start, NULL, NULL, end, viewer_clnum, contents_mask, qfalse);
		if (tr.fraction == 1 || tr.entityNum==goal_ent) {//  if there is a line of sight to the entity
			// Com_Printf(va("found ent in %i hits\n", i));
			viewer_cl->tracetimer[ent_clnum] = sv.time + MEMORY;// update the trace timer so the entity will be visible the next 200 time units
			VectorSubtract(end, ent->r.currentOrigin, viewer_cl->lasttrace[ent_clnum]);// remember the offset
			return qtrue;// and signal the entity is visible
		}
	}

	viewer_cl->lasttrace[ent_clnum][0] = offsetrandom(ent->r.mins[0], ent->r.maxs[0]);
	viewer_cl->lasttrace[ent_clnum][1] = offsetrandom(ent->r.mins[1], ent->r.maxs[1]);
	viewer_cl->lasttrace[ent_clnum][2] = offsetrandom(ent->r.mins[2], ent->r.maxs[2]+3.f);

	return (viewer_cl->tracetimer[ent_clnum] > sv.time);// returns true if the entity was visible within the last 200 time units
}