ServerEntity_t *Server_FindRadius(MathVector3f_t origin, float radius)
{
	int		i,j;
	ServerEntity_t *eEntity, *eChain;
	MathVector3f_t	eorg;

	eChain = sv.edicts;

	eEntity = NEXT_EDICT(sv.edicts);
	for(i = 1; i < sv.num_edicts; i++,eEntity = NEXT_EDICT(eEntity))
	{
		if(eEntity->free && eEntity->Physics.iSolid == SOLID_NOT)
			continue;

		for(j = 0; j < 3; j++)
			eorg[j] = origin[j]-(eEntity->v.origin[j]+(eEntity->v.mins[j]+eEntity->v.maxs[j])*0.5f);

		if(Math_Length(eorg) > radius)
			continue;

		eEntity->v.chain	= eChain;
		eChain				= eEntity;
	}

	return eChain;
}
Beispiel #2
0
/*
** SV_RunNQNewmis
**
** sv_player will be valid
*/
void SV_RunNQNewmis (void)
{
    edict_t	*ent;
    double save_frametime;
    int i, pl;

    pl = EDICT_TO_PROG(sv_player);
    ent = NEXT_EDICT(sv.edicts);
    for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
    {
        if (!ent->inuse)
            continue;
        if (ent->lastruntime || ent->v.owner != pl)
            continue;
        if (ent->v.movetype != MOVETYPE_FLY &&
                ent->v.movetype != MOVETYPE_FLYMISSILE &&
                ent->v.movetype != MOVETYPE_BOUNCE)
            continue;
        if (ent->v.solid != SOLID_BBOX && ent->v.solid != SOLID_TRIGGER)
            continue;

        save_frametime = sv_frametime;
        sv_frametime = 0.05;
        SV_RunEntity (ent);
        sv_frametime = save_frametime;
        return;
    }
}
static void AddAllEntsToPmove (void)
{
	int			e;
	edict_t		*check;
	int			i;
	physent_t	*pe;
	int			pl;

	pl = EDICT_TO_PROG(sv_player);
	check = NEXT_EDICT(sv.edicts);
	for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.owner == pl)
			continue;
		if (check->v.solid == SOLID_BSP
			|| check->v.solid == SOLID_BBOX
			|| check->v.solid == SOLID_SLIDEBOX)
		{
			if (check == sv_player)
				continue;

			for (i = 0; i < 3; i++)
			{
				if (check->v.absmin[i] > pmove_maxs[i]
						|| check->v.absmax[i] < pmove_mins[i])
					break;
			}

			if (i != 3)
				continue;

			pe = &pmove.physents[pmove.numphysent];

			VectorCopy (check->v.origin, pe->origin);
			VectorCopy (check->v.angles, pe->angles);
			pmove.physents[pmove.numphysent].info = e;

			if (check->v.solid == SOLID_BSP)
				pe->model = sv.models[(int)(check->v.modelindex)];
			else
			{
				pe->model = NULL;
				VectorCopy (check->v.mins, pe->mins);
				VectorCopy (check->v.maxs, pe->maxs);
			}

			if (++pmove.numphysent == MAX_PHYSENTS)
				break;
		}
	}
}
/*
================
R_ShowBoundingBoxes -- johnfitz

draw bounding boxes -- the server-side boxes, not the renderer cullboxes
================
*/
void R_ShowBoundingBoxes (void)
{
	extern		edict_t *sv_player;
	vec3_t		mins,maxs;
	edict_t		*ed;
	int			i;

	if (!r_showbboxes.value || cl.maxclients > 1 || !r_drawentities.value || !sv.active)
		return;

	glDisable (GL_DEPTH_TEST);
	glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
	GL_PolygonOffset (OFFSET_SHOWTRIS);
	glDisable (GL_TEXTURE_2D);
	glDisable (GL_CULL_FACE);
	glColor3f (1,1,1);

	for (i=0, ed=NEXT_EDICT(sv.edicts) ; i<sv.num_edicts ; i++, ed=NEXT_EDICT(ed))
	{
		if (ed == sv_player)
			continue; //don't draw player's own bbox

//		if (r_showbboxes.value != 2)
//			if (!SV_VisibleToClient (sv_player, ed, sv.worldmodel))
//				continue; //don't draw if not in pvs

		if (ed->v.mins[0] == ed->v.maxs[0] && ed->v.mins[1] == ed->v.maxs[1] && ed->v.mins[2] == ed->v.maxs[2])
		{
			//point entity
			R_EmitWirePoint (ed->v.origin);
		}
		else
		{
			//box entity
			VectorAdd (ed->v.mins, ed->v.origin, mins);
			VectorAdd (ed->v.maxs, ed->v.origin, maxs);
			R_EmitWireBox (mins, maxs);
		}
	}

	glColor3f (1,1,1);
	glEnable (GL_TEXTURE_2D);
	glEnable (GL_CULL_FACE);
	glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	GL_PolygonOffset (OFFSET_NONE);
	glEnable (GL_DEPTH_TEST);

	Sbar_Changed (); //so we don't get dots collecting on the statusbar
}
Beispiel #5
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
	int		i;
	edict_t	*ent;

// let the progs know that a new frame has started
	pr_global_struct->self = ((int)EDICT_TO_PROG(sv.edicts));
	pr_global_struct->other = ((int)EDICT_TO_PROG(sv.edicts));
	pr_global_struct->time = sv.time;
	PR_ExecuteProgram (pr_global_struct->StartFrame);

//SV_CheckAllEnts ();

//
// treat each object in turn
//
	ent = sv.edicts;
	for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
	{
		if (ent->free)
			continue;

		if (pr_global_struct->force_retouch)
		{
			SV_LinkEdict (ent, true);	// force retouch even for stationary
		}

		if (i > 0 && i <= svs.maxclients)
			SV_Physics_Client (ent, i);
		else if (ent->v.movetype == MOVETYPE_PUSH)
			SV_Physics_Pusher (ent);
		else if (ent->v.movetype == MOVETYPE_FAKEPUSH)
			SV_Physics_FakePusher (ent);
		else if (ent->v.movetype == MOVETYPE_NONE)
			SV_Physics_None (ent);
#ifdef QUAKE2
		else if (ent->v.movetype == MOVETYPE_FOLLOW)
			SV_Physics_Follow (ent);
#endif
		else if (ent->v.movetype == MOVETYPE_NOCLIP)
			SV_Physics_Noclip (ent);
		else if (ent->v.movetype == MOVETYPE_STEP)
			SV_Physics_Step (ent);
		else if (ent->v.movetype == MOVETYPE_TOSS 
		|| ent->v.movetype == MOVETYPE_BOUNCE
#ifdef QUAKE2
		|| ent->v.movetype == MOVETYPE_BOUNCEMISSILE
#endif
		|| ent->v.movetype == MOVETYPE_FLY
		|| ent->v.movetype == MOVETYPE_FLYMISSILE)
			SV_Physics_Toss (ent);
		else
			Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);			
	}
	
	if (pr_global_struct->force_retouch)
		pr_global_struct->force_retouch--;	

	sv.time += host_frametime;
}
Beispiel #6
0
/*
================
SV_CheckAllEnts
================
*/
void SV_CheckAllEnts(void)
{
    int e;
    edict_t *check;

// see if any solid entities are inside the final position
    check = NEXT_EDICT(sv.edicts);
    for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT(check)) {
	if (check->free)
	    continue;
	if (check->v.movetype == MOVETYPE_PUSH
	    || check->v.movetype == MOVETYPE_NONE
	    || check->v.movetype == MOVETYPE_NOCLIP)
	    continue;

	if (SV_TestEntityPosition(check))
	    Con_Printf("entity in invalid position\n");
    }
}
Beispiel #7
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
    int		i;
    edict_t	*ent;

    if (sv.state != ss_game)
        return;

    if (sv.old_time)
    {
        // don't bother running a frame if sv_mintic seconds haven't passed
        sv_frametime = sv.time - sv.old_time;
        if (sv_frametime < sv_mintic.value)
            return;
        if (sv_frametime > sv_maxtic.value)
            sv_frametime = sv_maxtic.value;
        sv.old_time = sv.time;
    }
    else
        sv_frametime = 0.1;		// initialization frame

    if (pr_nqprogs)
        NQP_Reset ();

    PR_GLOBAL(frametime) = sv_frametime;

    SV_ProgStartFrame ();

//
// treat each object in turn
// even the world gets a chance to think
//
    ent = sv.edicts;
    for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
    {
        if (!ent->inuse)
            continue;

        if (PR_GLOBAL(force_retouch))
            SV_LinkEdict (ent, true);	// force retouch even for stationary

        if (i > 0 && i <= MAX_CLIENTS)
            continue;		// clients are run directly from packets

        SV_RunEntity (ent);
        SV_RunNewmis ();
    }

    if (PR_GLOBAL(force_retouch))
        PR_GLOBAL(force_retouch)--;

    SV_RunBots ();
}
/*	draw bounding boxes -- the server-side boxes, not the renderer cullboxes
*/
void Video_ShowBoundingBoxes(void)
{
	extern ServerEntity_t	*sv_player;
	MathVector3f_t			mins, maxs;
	ClientEntity_t			*clEntity;
	ServerEntity_t			*ed;
	int						i;

	if (!r_showbboxes.value || (cl.maxclients > 1) || !r_drawentities.value || (!sv.active && !g_state.embedded))
		return;

	VideoLayer_Disable(VIDEO_DEPTH_TEST | VIDEO_TEXTURE_2D);
	VideoLayer_Enable(VIDEO_BLEND);

	for (i=0, ed=NEXT_EDICT(sv.edicts) ; i<sv.num_edicts ; i++, ed=NEXT_EDICT(ed))
	{
		if(ed == sv_player && !chase_active.value)
			continue;

		glColor3f(1,1,1);

		R_EmitWirePoint (ed->v.origin);

		Math_VectorAdd(ed->v.mins,ed->v.origin,mins);
		Math_VectorAdd(ed->v.maxs,ed->v.origin,maxs);

		glColor4f(0, 0.5f, 0, 0.5f);

		R_EmitWireBox(mins,maxs, 1, 1, 1);
	}

	// Cycle through client-side entities.
	for (i = 0, clEntity = cl_entities; i < cl.num_entities; i++, clEntity++)
		Video_DrawClientBoundingBox(clEntity);
	for (i = 0, clEntity = cl_temp_entities; i < cl_numvisedicts; i++, clEntity++)
		Video_DrawClientBoundingBox(clEntity);

	VideoLayer_Disable(VIDEO_BLEND);
	VideoLayer_Enable(VIDEO_TEXTURE_2D | VIDEO_DEPTH_TEST);
}
Beispiel #9
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
	int		i;
	edict_t	*ent;
	static double	old_time;

// don't bother running a frame if sys_ticrate seconds haven't passed
	host_frametime = realtime - old_time;
	if (host_frametime < sv_mintic.value)
		return;
	if (host_frametime > sv_maxtic.value)
		host_frametime = sv_maxtic.value;
	old_time = realtime;

	pr_global_struct->frametime = host_frametime;

	SV_ProgStartFrame ();

//
// treat each object in turn
// even the world gets a chance to think
//
	ent = sv.edicts;
	for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
	{
		if (ent->free)
			continue;

		if (pr_global_struct->force_retouch)
			SV_LinkEdict (ent, true);	// force retouch even for stationary

		if (i > 0 && i <= MAX_CLIENTS)
			continue;		// clients are run directly from packets

		SV_RunEntity (ent);
		SV_RunNewmis ();
	}
	
	if (pr_global_struct->force_retouch)
		pr_global_struct->force_retouch--;	
}
Beispiel #10
0
/*
============
SV_Push

============
*/
qboolean SV_Push (edict_t *pusher, vec3_t move)
{
	int			i, e;
	edict_t		*check, *block;
	vec3_t		mins, maxs;
	vec3_t		pushorig;
	int			num_moved;
	edict_t		*moved_edict[MAX_EDICTS];
	vec3_t		moved_from[MAX_EDICTS];

	for (i=0 ; i<3 ; i++)
	{
		mins[i] = pusher->v.absmin[i] + move[i];
		maxs[i] = pusher->v.absmax[i] + move[i];
	}

	VectorCopy (pusher->v.origin, pushorig);
	
// move the pusher to it's final position

	VectorAdd (pusher->v.origin, move, pusher->v.origin);
	SV_LinkEdict (pusher, false);

// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH
		|| check->v.movetype == MOVETYPE_NONE
		|| check->v.movetype == MOVETYPE_NOCLIP)
			continue;

		pusher->v.solid = SOLID_NOT;
		block = SV_TestEntityPosition (check);
		pusher->v.solid = SOLID_BSP;
		if (block)
			continue;

	// if the entity is standing on the pusher, it will definately be moved
		if ( ! ( ((int)check->v.flags & FL_ONGROUND)
		&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
		{
			if ( check->v.absmin[0] >= maxs[0]
			|| check->v.absmin[1] >= maxs[1]
			|| check->v.absmin[2] >= maxs[2]
			|| check->v.absmax[0] <= mins[0]
			|| check->v.absmax[1] <= mins[1]
			|| check->v.absmax[2] <= mins[2] )
				continue;

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

		VectorCopy (check->v.origin, moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

		// try moving the contacted entity 
		VectorAdd (check->v.origin, move, check->v.origin);
		block = SV_TestEntityPosition (check);
		if (!block)
		{	// pushed ok
			SV_LinkEdict (check, false);
			continue;
		}

		// if it is ok to leave in the old position, do it
		VectorSubtract (check->v.origin, move, check->v.origin);
		block = SV_TestEntityPosition (check);
		if (!block)
		{
			num_moved--;
			continue;
		}

	// if it is still inside the pusher, block
		if (check->v.mins[0] == check->v.maxs[0])
		{
			SV_LinkEdict (check, false);
			continue;
		}
		if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
		{	// corpse
			check->v.mins[0] = check->v.mins[1] = 0;
			VectorCopy (check->v.mins, check->v.maxs);
			SV_LinkEdict (check, false);
			continue;
		}
		
		VectorCopy (pushorig, pusher->v.origin);
		SV_LinkEdict (pusher, false);

		// if the pusher has a "blocked" function, call it
		// otherwise, just stay in place until the obstacle is gone
		if (pusher->v.blocked)
		{
			pr_global_struct->self = EDICT_TO_PROG(pusher);
			pr_global_struct->other = EDICT_TO_PROG(check);
			PR_ExecuteProgram (pusher->v.blocked);
		}
		
	// move back any entities we already moved
		for (i=0 ; i<num_moved ; i++)
		{
			VectorCopy (moved_from[i], moved_edict[i]->v.origin);
			SV_LinkEdict (moved_edict[i], false);
		}
		return false;
	}

	return true;
}
// [18/5/2013] TODO: Merge with SV_PushMove ~hogsy
static void Server_PushRotate(edict_t *pusher,float movetime)
{
	int		i,e,num_moved,slaves_moved;
	edict_t	*check,*block,*moved_edict[MAX_EDICTS],*ground,*slave,*master;
	vec3_t	move,a,amove,entorig,pushorig,moved_from[MAX_EDICTS],org,org2,forward,right,up;
	bool	bMoveIt;

	for (i = 0; i < 3; i++)
		amove[i] = pusher->v.avelocity[i] * movetime;

	Math_VectorNegate(amove,a);
	Math_AngleVectors(a,forward,right,up);

	Math_VectorCopy(pusher->v.angles,pushorig);

	// move the pusher to it's final position
	Math_VectorAdd(pusher->v.angles,amove,pusher->v.angles);

	pusher->v.ltime += movetime;
	SV_LinkEdict (pusher, false);

	slaves_moved = 0;
	master = pusher;
	while(master->v.aiment)
	{
		slave = PROG_TO_EDICT(master->v.aiment);

		slaves_moved++;
		Math_VectorCopy (slave->v.angles, moved_from[MAX_EDICTS - slaves_moved]);
		moved_edict[MAX_EDICTS - slaves_moved] = slave;

		if (slave->v.movedir[PITCH])
			slave->v.angles[PITCH] = master->v.angles[PITCH];
		else
			slave->v.angles[PITCH] += slave->v.avelocity[PITCH] * movetime;

		if (slave->v.movedir[YAW])
			slave->v.angles[YAW] = master->v.angles[YAW];
		else
			slave->v.angles[YAW] += slave->v.avelocity[YAW] * movetime;

		if (slave->v.movedir[ROLL])
			slave->v.angles[ROLL] = master->v.angles[ROLL];
		else
			slave->v.angles[ROLL] += slave->v.avelocity[ROLL] * movetime;

		slave->v.ltime = master->v.ltime;
		SV_LinkEdict(slave,false);

		master = slave;
	}

	// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
			continue;

		// if the entity is standing on the pusher, it will definitely be moved
		bMoveIt = false;
		ground = check->v.groundentity;
		if(check->v.flags & FL_ONGROUND)
		{
			if (ground == pusher)
				bMoveIt = true;
			else
			{
				for (i = 0; i < slaves_moved; i++)
				{
					if (ground == moved_edict[MAX_EDICTS - i - 1])
					{
						bMoveIt = true;
						break;
					}
				}
			}
		}

		if(!bMoveIt)
		{
			if(	check->v.absmin[0] >= pusher->v.absmax[0]
			||	check->v.absmin[1] >= pusher->v.absmax[1]
			||	check->v.absmin[2] >= pusher->v.absmax[2]
			||	check->v.absmax[0] <= pusher->v.absmin[0]
			||	check->v.absmax[1] <= pusher->v.absmin[1]
			||	check->v.absmax[2] <= pusher->v.absmin[2])
			{
				for (i = 0; i < slaves_moved; i++)
				{
					slave = moved_edict[MAX_EDICTS-i-1];
					if( check->v.absmin[0] >= slave->v.absmax[0]
					||	check->v.absmin[1] >= slave->v.absmax[1]
					||	check->v.absmin[2] >= slave->v.absmax[2]
					||	check->v.absmax[0] <= slave->v.absmin[0]
					||	check->v.absmax[1] <= slave->v.absmin[1]
					||	check->v.absmax[2] <= slave->v.absmin[2] )
						continue;
				}
				if (i == slaves_moved)
					continue;
			}

			// See if the ent's bbox is inside the pusher's final position
			if(!SV_TestEntityPosition(check))
				continue;
		}

		// remove the onground flag for non-players
		if(check->v.movetype != MOVETYPE_WALK)
			check->v.flags = check->v.flags & ~FL_ONGROUND;

		Math_VectorCopy(check->v.origin,entorig);
		Math_VectorCopy(check->v.origin,moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

		// calculate destination position
		Math_VectorSubtract(check->v.origin,pusher->v.origin,org);
		org2[0] = Math_DotProduct(org,forward);
		org2[1] = -Math_DotProduct(org,right);
		org2[2] = Math_DotProduct(org,up);
		Math_VectorSubtract (org2,org,move);

		// try moving the contacted entity
		pusher->Physics.iSolid = SOLID_NOT;
		SV_PushEntity (check, move);
	//@@TODO: do we ever want to do anybody's angles?  maybe just yaw???
		if(check->monster.iType != 1)
		{
#if 0
			vec3_t	vYaw;
			
			vYaw[YAW] = Math_AngleMod(pusher->v.angles[YAW]+check->v.angles[YAW]);

			Con_Printf("%i %i\n",(int)check->v.angles[YAW],(int)vYaw[YAW]);
			//check->v.angles[YAW] = vYaw[YAW];
			//check->v.angles[YAW] = Math_AngleMod(vYaw[YAW]);
#endif
			// move back any entities we already moved
			for (i = 0; i < num_moved; i++)
			{
				Math_VectorAdd(moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
				moved_edict[i]->v.angles[YAW] += amove[YAW]/2.0f;

				SV_LinkEdict(moved_edict[i],false);
			}
		}

		pusher->Physics.iSolid = SOLID_BSP;

		// If it is still inside the pusher, block
		block = SV_TestEntityPosition (check);
		if (block)
		{
			// fail the move
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->Physics.iSolid == SOLID_NOT || check->Physics.iSolid == SOLID_TRIGGER)
			{
				// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				Math_VectorCopy(check->v.mins,check->v.maxs);
				continue;
			}

			Math_VectorCopy(entorig,check->v.origin);
			SV_LinkEdict(check,true);

			Math_VectorCopy(pushorig,pusher->v.angles);
			SV_LinkEdict(pusher,false);
			pusher->v.ltime -= movetime;

			for(i = 0; i < slaves_moved; i++)
			{
				slave = moved_edict[MAX_EDICTS - i - 1];
				Math_VectorCopy(moved_from[MAX_EDICTS - i - 1], slave->v.angles);
				SV_LinkEdict(slave,false);
				slave->v.ltime -= movetime;
			}

			// if the pusher has a "blocked" function, call it
			// otherwise, just stay in place until the obstacle is gone
			if (pusher->v.blocked)
				pusher->v.blocked(pusher,check);

			// move back any entities we already moved
			for (i = 0; i < num_moved; i++)
			{
				Math_VectorCopy (moved_from[i], moved_edict[i]->v.origin);
			//@@TODO:: see above
			//	if (!((int)moved_edict[i]->v.flags & (FL_CLIENT | FL_MONSTER)))
				Math_VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
				moved_edict[i]->v.angles[YAW] -= amove[YAW];

				SV_LinkEdict(moved_edict[i],false);
			}
			return;
		}
	}
}
void SV_PushMove (edict_t *pusher, float movetime)
{
	int			i, e;
	edict_t		*check, *block;
	vec3_t		mins, maxs, move;
	vec3_t		entorig, pushorig;
	int			num_moved;
	edict_t		**moved_edict; //johnfitz -- dynamically allocate
	vec3_t		*moved_from; //johnfitz -- dynamically allocate
	int			mark; //johnfitz

	if(!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
	{
		pusher->v.ltime += movetime;
		return;
	}

	for (i=0 ; i<3 ; i++)
	{
		move[i] = pusher->v.velocity[i] * movetime;
		mins[i] = pusher->v.absmin[i] + move[i];
		maxs[i] = pusher->v.absmax[i] + move[i];
	}

	Math_VectorCopy (pusher->v.origin, pushorig);

// move the pusher to it's final position

	Math_VectorAdd (pusher->v.origin, move, pusher->v.origin);
	pusher->v.ltime += movetime;
	SV_LinkEdict(pusher,false);

	//johnfitz -- dynamically allocate
	mark = Hunk_LowMark ();
	moved_edict = (edict_t**)Hunk_Alloc(sv.num_edicts*sizeof(edict_t*));
	moved_from	= (vec3_t(*))Hunk_Alloc (sv.num_edicts*sizeof(vec3_t));
	//johnfitz

// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH
		|| check->v.movetype == MOVETYPE_NONE
		|| check->v.movetype == MOVETYPE_NOCLIP)
			continue;

	// if the entity is standing on the pusher, it will definately be moved
		if(!((check->v.flags & FL_ONGROUND)	&& check->v.groundentity == pusher))
		{
			if ( check->v.absmin[0] >= maxs[0]
			|| check->v.absmin[1] >= maxs[1]
			|| check->v.absmin[2] >= maxs[2]
			|| check->v.absmax[0] <= mins[0]
			|| check->v.absmax[1] <= mins[1]
			|| check->v.absmax[2] <= mins[2] )
				continue;

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

	// remove the onground flag for non-players
		if (check->v.movetype != MOVETYPE_WALK)
			check->v.flags = check->v.flags & ~FL_ONGROUND;

		Math_VectorCopy(check->v.origin,entorig);
		Math_VectorCopy(check->v.origin,moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

		// try moving the contacted entity
		pusher->Physics.iSolid = SOLID_NOT;
		SV_PushEntity (check, move);
		pusher->Physics.iSolid = SOLID_BSP;

	// if it is still inside the pusher, block
		block = SV_TestEntityPosition (check);
		if (block)
		{	// fail the move
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->Physics.iSolid == SOLID_NOT || check->Physics.iSolid == SOLID_TRIGGER)
			{	// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				Math_VectorCopy(check->v.mins,check->v.maxs);
				continue;
			}

			Math_VectorCopy(entorig,check->v.origin);
			SV_LinkEdict(check,true);

			Math_VectorCopy(pushorig,pusher->v.origin);
			SV_LinkEdict(pusher,false);
			pusher->v.ltime -= movetime;

			// if the pusher has a "blocked" function, call it
			// otherwise, just stay in place until the obstacle is gone
			if(pusher->v.blocked)
			{
				pr_global_struct.self	= EDICT_TO_PROG(pusher);
				pr_global_struct.eOther	= check;

				pusher->v.blocked(pusher,check);
			}

		// move back any entities we already moved
			for (i=0 ; i<num_moved ; i++)
			{
				Math_VectorCopy(moved_from[i],moved_edict[i]->v.origin);
				SV_LinkEdict (moved_edict[i], false);
			}
			Hunk_FreeToLowMark (mark); //johnfitz
			return;
		}
	}

	Hunk_FreeToLowMark (mark); //johnfitz
}
void Physics_ServerFrame(void)
{
	int		i;
	edict_t	*eEntity;

	// Let the progs know that a new frame has started
	pr_global_struct.self	= EDICT_TO_PROG(sv.edicts);
	pr_global_struct.eOther	= sv.edicts;

	// TODO: should we pass the time to this? ~hogsy
	Game->Server_StartFrame();

	// Treat each object in turn
	eEntity = sv.edicts;
	for(i = 0; i < sv.num_edicts; i++,eEntity = NEXT_EDICT(eEntity))
	{
		if(eEntity->free)
			continue;

		if(pr_global_struct.force_retouch)
			SV_LinkEdict(eEntity,true);	// Force retouch even for stationary

		// [11/7/2013] Cleaned this up and gave it its own function ~hogsy
		Game->Server_EntityFrame(eEntity);

		if(i > 0 && i <= svs.maxclients)
			SV_Physics_Client(eEntity,i);
		else
		{
			switch(eEntity->v.movetype)
			{
			case MOVETYPE_NONE:
				Server_RunThink(eEntity);
				break;
			case MOVETYPE_PUSH:
				SV_Physics_Pusher(eEntity);
				break;
			case MOVETYPE_NOCLIP:
				Physics_NoClip(eEntity);
				break;
			case MOVETYPE_WALK:
			case MOVETYPE_STEP:
				Game->Physics_CheckVelocity(eEntity);
				Game->Physics_SetGravity(eEntity);

				Physics_AddFriction(eEntity,eEntity->v.velocity,eEntity->v.origin);

				SV_WalkMove(eEntity);
				SV_LinkEdict(eEntity,true);

				Server_RunThink(eEntity);
				break;
			case MOVETYPE_TOSS:
			case MOVETYPE_BOUNCE:
			case MOVETYPE_FLY:
			case MOVETYPE_FLYMISSILE:
			case MOVETYPE_FLYBOUNCE:
				Physics_Toss(eEntity);
				break;
			default:
				Con_Warning("Bad movetype set for entity! (%s)",eEntity->v.cClassname);
			}
		}
	}

	if(pr_global_struct.force_retouch)
		pr_global_struct.force_retouch--;

	sv.time += host_frametime;
}
Beispiel #14
0
/*
============
SV_PushMove

============
*/
void SV_PushMove (edict_t *pusher, float movetime)
{
	int			i, e;
	edict_t		*check, *block;
	vec3_t		mins, maxs, move;
	vec3_t		entorig, pushorig;
	int			num_moved;
	edict_t		*moved_edict[MAX_EDICTS];
	vec3_t		moved_from[MAX_EDICTS];

	if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
	{
		pusher->v.ltime += movetime;
		return;
	}

	for (i=0 ; i<3 ; i++)
	{
		move[i] = pusher->v.velocity[i] * movetime;
		mins[i] = pusher->v.absmin[i] + move[i];
		maxs[i] = pusher->v.absmax[i] + move[i];
	}

	VectorCopy (pusher->v.origin, pushorig);
	
// move the pusher to it's final position
	VectorAdd (pusher->v.origin, move, pusher->v.origin);
	pusher->v.ltime += movetime;
	SV_LinkEdict (pusher, false);

// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH
		|| check->v.movetype == MOVETYPE_NONE
		|| check->v.movetype == MOVETYPE_FOLLOW // Nehahra
		|| check->v.movetype == MOVETYPE_NOCLIP)
			continue;

	// if the entity is standing on the pusher, it will definately be moved
		if ( ! ( ((int)check->v.flags & FL_ONGROUND)
		&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
		{
			if ( check->v.absmin[0] >= maxs[0]
			|| check->v.absmin[1] >= maxs[1]
			|| check->v.absmin[2] >= maxs[2]
			|| check->v.absmax[0] <= mins[0]
			|| check->v.absmax[1] <= mins[1]
			|| check->v.absmax[2] <= mins[2] )
				continue;

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

	// remove the onground flag for non-players
		if (check->v.movetype != MOVETYPE_WALK)
			check->v.flags = (int)check->v.flags & ~FL_ONGROUND;

		VectorCopy (check->v.origin, entorig);
		VectorCopy (check->v.origin, moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

		// only check for types that can block
		if (pusher->v.solid == SOLID_BSP // everything that blocks: bsp models, map brushes, doors, plats etc.
		|| pusher->v.solid == SOLID_BBOX // normally boxes
		|| pusher->v.solid == SOLID_SLIDEBOX) // normally monsters
		{	// store out the previous solid value because we're going to change it next
			float savepushervsolid = pusher->v.solid;

			// try moving the contacted entity
			pusher->v.solid = SOLID_NOT;
			SV_PushEntity (check, move);
			// restore from the stored solid
			pusher->v.solid = savepushervsolid;

			// if it is still inside the pusher, block
			block = SV_TestEntityPosition (check);
		}
		else
		{	// not blocked
			block = NULL;
		}

		if (block)
		{	// fail the move
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
			{	// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				VectorCopy (check->v.mins, check->v.maxs);
				continue;
			}

			VectorCopy (entorig, check->v.origin);
			SV_LinkEdict (check, true);

			VectorCopy (pushorig, pusher->v.origin);
			SV_LinkEdict (pusher, false);
			pusher->v.ltime -= movetime;

		// if the pusher has a "blocked" function, call it
		// otherwise, just stay in place until the obstacle is gone
			if (pusher->v.blocked)
			{
				pr_global_struct->self = EDICT_TO_PROG(pusher);
				pr_global_struct->other = EDICT_TO_PROG(check);
				PR_ExecuteProgram (pusher->v.blocked);
			}

		// move back any entities we already moved
			for (i=0 ; i<num_moved ; i++)
			{
				VectorCopy (moved_from[i], moved_edict[i]->v.origin);
				SV_LinkEdict (moved_edict[i], false);
			}
			return;
		}
	}
}
Beispiel #15
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
	int	i;
	int		entity_cap; // For sv_freezenonclients
	edict_t	*ent;

// let the progs know that a new frame has started
	pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
	pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
	pr_global_struct->time = sv.time;
	PR_ExecuteProgram (pr_global_struct->StartFrame);

//SV_CheckAllEnts ();

//
// treat each object in turn
//
	ent = sv.edicts;
	if (sv.frozen)
		entity_cap = svs.maxclients + 1; // Only run physics on clients and the world
	else
		entity_cap = sv.num_edicts;

	for (i=0 ; i<entity_cap ; i++, ent = NEXT_EDICT(ent))
//	for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
	{
		if (ent->free)
			continue;

		if (pr_global_struct->force_retouch)
		{
			SV_LinkEdict (ent, true);	// force retouch even for stationary
		}

		if (i > 0 && i <= svs.maxclients)
			SV_Physics_Client (ent, i);
		else if (ent->v.movetype == MOVETYPE_PUSH)
			SV_Physics_Pusher (ent);
		else if (ent->v.movetype == MOVETYPE_NONE)
			SV_Physics_None (ent);
		else if (ent->v.movetype == MOVETYPE_FOLLOW) // Nehahra
			SV_Physics_Follow (ent);
		else if (ent->v.movetype == MOVETYPE_NOCLIP)
			SV_Physics_Noclip (ent);
		else if (ent->v.movetype == MOVETYPE_STEP)
			SV_Physics_Step (ent);
		else if (ent->v.movetype == MOVETYPE_WALK) // Nehahra
		{
			if (!SV_RunThink (ent))
				return;
			if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
				SV_AddGravity (ent);
			SV_CheckStuck (ent);
			SV_WalkMove (ent);
		}
		else if (ent->v.movetype == MOVETYPE_TOSS 
		|| ent->v.movetype == MOVETYPE_BOUNCE
		|| ent->v.movetype == MOVETYPE_FLY
		|| ent->v.movetype == MOVETYPE_FLYMISSILE)
			SV_Physics_Toss (ent);
		else
			Host_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);			
	}
	
	if (pr_global_struct->force_retouch)
		pr_global_struct->force_retouch--;	

	if (!sv.frozen)
		sv.time += host_frametime;
}
Beispiel #16
0
/*
============
SV_PushMove

============
*/
void SV_PushMove (edict_t *pusher, float movetime)
{
	int			i, e;
	edict_t		*check, *block;
	vec3_t		mins, maxs, move;
	vec3_t		entorig, pushorig;
	int			num_moved;
	edict_t		*moved_edict[MAX_EDICTS];
	vec3_t		moved_from[MAX_EDICTS];
	float		solid_backup; //movetype_push error fix - Eradicator

	if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
	{
		pusher->v.ltime += movetime;
		return;
	}

	for (i=0 ; i<3 ; i++)
	{
		move[i] = pusher->v.velocity[i] * movetime;
		mins[i] = pusher->v.absmin[i] + move[i];
		maxs[i] = pusher->v.absmax[i] + move[i];
	}

	VectorCopy (pusher->v.origin, pushorig);
	
// move the pusher to it's final position

	VectorAdd (pusher->v.origin, move, pusher->v.origin);
	pusher->v.ltime += movetime;
	SV_LinkEdict (pusher, false);


// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH
		|| check->v.movetype == MOVETYPE_NONE
#ifdef QUAKE2
		|| check->v.movetype == MOVETYPE_FOLLOW
#endif
		|| check->v.movetype == MOVETYPE_NOCLIP)
			continue;

	// if the entity is standing on the pusher, it will definately be moved
		if ( ! ( ((int)check->v.flags & FL_ONGROUND)
		&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
		{
			if ( check->v.absmin[0] >= maxs[0]
			|| check->v.absmin[1] >= maxs[1]
			|| check->v.absmin[2] >= maxs[2]
			|| check->v.absmax[0] <= mins[0]
			|| check->v.absmax[1] <= mins[1]
			|| check->v.absmax[2] <= mins[2] )
				continue;

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

	// remove the onground flag for non-players
		if (check->v.movetype != MOVETYPE_WALK)
			check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
		
		VectorCopy (check->v.origin, entorig);
		VectorCopy (check->v.origin, moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

		//START - movetype_push error fix - Eradicator
		solid_backup = pusher->v.solid;
		if ( solid_backup == SOLID_BSP
		  || solid_backup == SOLID_BBOX
		  || solid_backup == SOLID_SLIDEBOX )
		{
		//END - movetype_push error fix - Eradicator

		// try moving the contacted entity 
		pusher->v.solid = SOLID_NOT;
		SV_PushEntity (check, move);
		//pusher->v.solid = SOLID_BSP; //Old
		pusher->v.solid = solid_backup; //movetype_push error fix - Eradicator

	// if it is still inside the pusher, block
		block = SV_TestEntityPosition (check);
		} //movetype_push error fix - Eradicator
		else
			block = NULL;

		if (block)
		{	// fail the move
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
			{	// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				VectorCopy (check->v.mins, check->v.maxs);
				continue;
			}
			
			VectorCopy (entorig, check->v.origin);
			SV_LinkEdict (check, true);

			VectorCopy (pushorig, pusher->v.origin);
			SV_LinkEdict (pusher, false);
			pusher->v.ltime -= movetime;

			// if the pusher has a "blocked" function, call it
			// otherwise, just stay in place until the obstacle is gone
			if (pusher->v.blocked)
			{
				pr_global_struct->self = ((int)EDICT_TO_PROG(pusher));
				pr_global_struct->other = ((int)EDICT_TO_PROG(check));
				PR_ExecuteProgram (pusher->v.blocked);
			}
			
		// move back any entities we already moved
			for (i=0 ; i<num_moved ; i++)
			{
				VectorCopy (moved_from[i], moved_edict[i]->v.origin);
				SV_LinkEdict (moved_edict[i], false);
			}
			return;
		}	
	}

	
}
Beispiel #17
0
/*
============
SV_PushMove

============
*/
void SV_PushMove (edict_t *pusher, float movetime)
{
	int			i, e;
	edict_t		*check, *block;
	vec3_t		mins, maxs, move;
	vec3_t		entorig, pushorig;
	int			num_moved;
// 2001-09-20 Configurable entity limits by Maddes  start
/*
	edict_t		*moved_edict[MAX_EDICTS];
	vec3_t		moved_from[MAX_EDICTS];
*/
// 2001-09-20 Configurable entity limits by Maddes  end
	float		solid_backup;		// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes

	if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
	{
		pusher->v.ltime += movetime;
		return;
	}

// 2001-09-20 Configurable entity limits by Maddes  start
// FIXME: is this really necessary
	memset (moved_edict, 0, sv.max_edicts*sizeof(edict_t *));
	memset (moved_from, 0, sv.max_edicts*sizeof(vec3_t));
// 2001-09-20 Configurable entity limits by Maddes  end

	for (i=0 ; i<3 ; i++)
	{
		move[i] = pusher->v.velocity[i] * movetime;
		mins[i] = pusher->v.absmin[i] + move[i];
		maxs[i] = pusher->v.absmax[i] + move[i];
	}

	VectorCopy (pusher->v.origin, pushorig);

// move the pusher to it's final position

	VectorAdd (pusher->v.origin, move, pusher->v.origin);
	pusher->v.ltime += movetime;
	SV_LinkEdict (pusher, false);


// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH
		|| check->v.movetype == MOVETYPE_NONE
		|| check->v.movetype == MOVETYPE_FOLLOW
		|| check->v.movetype == MOVETYPE_NOCLIP)
			continue;

	// if the entity is standing on the pusher, it will definately be moved
		if ( ! ( ((int)check->v.flags & FL_ONGROUND)
		&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
		{
			if ( check->v.absmin[0] >= maxs[0]
			|| check->v.absmin[1] >= maxs[1]
			|| check->v.absmin[2] >= maxs[2]
			|| check->v.absmax[0] <= mins[0]
			|| check->v.absmax[1] <= mins[1]
			|| check->v.absmax[2] <= mins[2] )
				continue;

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

	// remove the onground flag for non-players
		if (check->v.movetype != MOVETYPE_WALK)
			check->v.flags = (int)check->v.flags & ~FL_ONGROUND;

		VectorCopy (check->v.origin, entorig);
		VectorCopy (check->v.origin, moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes  start
		solid_backup = pusher->v.solid;
		if ( solid_backup == SOLID_BSP		// everything that blocks: bsp models==map brushes==doors,plats,etc.
		|| solid_backup == SOLID_BBOX		// normally boxes
		|| solid_backup == SOLID_SLIDEBOX )	// normally monsters
		{
// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes  end
			// try moving the contacted entity
			pusher->v.solid = SOLID_NOT;
			SV_PushEntity (check, move);
// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes  start
//			pusher->v.solid = SOLID_BSP;
			pusher->v.solid = solid_backup;
// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes  end

			// if it is still inside the pusher, block
// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes  start
			block = SV_TestEntityPosition (check);
		}
		else
			block = NULL;
// 1999-10-07 MOVETYPE_PUSH fix by LordHavoc/Maddes  end

		if (block)
		{	// fail the move
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
			{	// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				VectorCopy (check->v.mins, check->v.maxs);
				continue;
			}

			VectorCopy (entorig, check->v.origin);
			SV_LinkEdict (check, true);

			VectorCopy (pushorig, pusher->v.origin);
			SV_LinkEdict (pusher, false);
			pusher->v.ltime -= movetime;

			// if the pusher has a "blocked" function, call it
			// otherwise, just stay in place until the obstacle is gone
			if (pusher->v.blocked)
			{
				pr_global_struct->self = EDICT_TO_PROG(pusher);
				pr_global_struct->other = EDICT_TO_PROG(check);
				PR_ExecuteProgram (pusher->v.blocked);
			}

		// move back any entities we already moved
			for (i=0 ; i<num_moved ; i++)
			{
				VectorCopy (moved_from[i], moved_edict[i]->v.origin);
				SV_LinkEdict (moved_edict[i], false);
			}
			return;
		}
	}


}
Beispiel #18
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
	int		i;
	edict_t	*ent;

// 2000-04-30 NVS HANDSHAKE SRV<->CL/QC<->CL by Maddes  start
	eval_t	*val;

	// let the QuakeC code know the NVS versions of the server and clients
	if (pr_field_nvs_svc)
	{
		// set world/server
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  start
//		val = GetEdictFieldValue(sv.edicts, "nvs_svc");
		val = GETEDICTFIELDVALUE(sv.edicts, pr_field_nvs_svc);
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  end
		if (val)
		{
			val->_float = nvs_current_ssvc->value;
		}

		// set clients
		ent = NEXT_EDICT(sv.edicts);	// set to first not-world entity (=1st client)
		for (i=1 ; i<=svs.maxclients && i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
		{
			if (ent->free)
				continue;

			if (!svs.clients[i-1].active)
				continue;		// unconnected slot

// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  start
//			val = GetEdictFieldValue(ent, "nvs_svc");
			val = GETEDICTFIELDVALUE(ent, pr_field_nvs_svc);
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  end
			if (val)
			{
				val->_float = svs.clients[i-1].nvs_csvc;
			}
		}
	}
// 2000-04-30 NVS HANDSHAKE SRV<->CL/QC<->CL by Maddes  end

// let the progs know that a new frame has started
	pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
	pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
	pr_global_struct->time = sv.time;
	PR_ExecuteProgram (pr_global_struct->StartFrame);

//SV_CheckAllEnts ();

//
// treat each object in turn
//
	ent = sv.edicts;
	for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
	{
		if (ent->free)
			continue;

		if (pr_global_struct->force_retouch)
		{
			SV_LinkEdict (ent, true);	// force retouch even for stationary
		}

		if (i > 0 && i <= svs.maxclients)
			SV_Physics_Client (ent, i);
		else if (ent->v.movetype == MOVETYPE_PUSH)
			SV_Physics_Pusher (ent);
		else if (ent->v.movetype == MOVETYPE_NONE)
			SV_Physics_None (ent);
		else if (ent->v.movetype == MOVETYPE_FOLLOW)
			SV_Physics_Follow (ent);
		else if (ent->v.movetype == MOVETYPE_NOCLIP)
			SV_Physics_Noclip (ent);
		else if (ent->v.movetype == MOVETYPE_STEP)
			SV_Physics_Step (ent);
		else if (ent->v.movetype == MOVETYPE_TOSS
		|| ent->v.movetype == MOVETYPE_BOUNCE
		|| ent->v.movetype == MOVETYPE_BOUNCEMISSILE
		|| ent->v.movetype == MOVETYPE_FLY
		|| ent->v.movetype == MOVETYPE_FLYMISSILE)
			SV_Physics_Toss (ent);
		else
			Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);
	}

// 2000-01-02 EndFrame function by Maddes/FrikaC  start
	if (pr_func_endframe)
	{
		// let the progs know that a new frame has ended
		pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
		pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
		pr_global_struct->time = sv.time;
		PR_ExecuteProgram (pr_func_endframe);
	}
// 2000-01-02 EndFrame function by Maddes/FrikaC  end

	if (pr_global_struct->force_retouch)
		pr_global_struct->force_retouch--;

	sv.time += host_frametime;
}
Beispiel #19
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
	int			i;
	edict_t		*ent;

// let the progs know that a new frame has started
#ifdef HEXEN2_SUPPORT
	edict_t		*ent2;
	vec3_t		oldOrigin, oldAngle;
	int			originMoved, c;
#endif

	PR_GLOBAL(self) = EDICT_TO_PROG(sv.edicts);
	PR_GLOBAL(other) = EDICT_TO_PROG(sv.edicts);
	PR_GLOBAL(time) = sv.time;
	PR_ExecuteProgram (PR_GLOBAL(StartFrame));

//SV_CheckAllEnts ();

// treat each object in turn
	ent = sv.edicts;
	for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
	{
		if (ent->free)
			continue;

	#ifndef RQM_SV_ONLY
		if (!isDedicated && ((i+1) % 100 == 0))
			S_ExtraUpdateTime (); // BJP: Improve sound when many entities
	#endif

	#ifdef HEXEN2_SUPPORT
		if (hexen2)
		{
			ent2 = PROG_TO_EDICT (ent->v.movechain);
			if (ent2 != sv.edicts)
			{
				VectorCopy (ent->v.origin, oldOrigin);
				VectorCopy (ent->v.angles, oldAngle);
			}
		}
	#endif

		if (pr_global_ptrs.force_retouch && *pr_global_ptrs.force_retouch)
			SV_LinkEdict (ent, true);	// force retouch even for stationary

		if (i > 0 && i <= svs.maxclients)
			SV_Physics_Client (ent, i);
		else if (ent->v.movetype == MOVETYPE_PUSH)
			SV_Physics_Pusher (ent);
		else if (ent->v.movetype == MOVETYPE_NONE)
			SV_Physics_None (ent);
		else if (ent->v.movetype == MOVETYPE_NOCLIP)
			SV_Physics_Noclip (ent);
		else if (ent->v.movetype == MOVETYPE_STEP)
			SV_Physics_Step (ent);
	#ifdef HEXEN2_SUPPORT
		else if	((hexen2) && (ent->v.movetype == MOVETYPE_PUSHPULL))
			SV_Physics_Step (ent);
	#endif
		else if (ent->v.movetype == MOVETYPE_TOSS 
		|| ent->v.movetype == MOVETYPE_BOUNCE
	#ifdef HEXEN2_SUPPORT
		|| ((hexen2) && ((ent->v.movetype == MOVETYPE_BOUNCEMISSILE) || (ent->v.movetype == MOVETYPE_SWIM)))
	#endif
		|| ent->v.movetype == MOVETYPE_FLY
		|| ent->v.movetype == MOVETYPE_FLYMISSILE)
			SV_Physics_Toss (ent);
		else
			Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);			

	#ifdef HEXEN2_SUPPORT
		if ((hexen2) && (ent2 != sv.edicts))
		{
			originMoved = !VectorCompare(ent->v.origin, oldOrigin);
			if (originMoved || !VectorCompare(ent->v.angles, oldAngle))
			{
				VectorSubtract(ent->v.origin, oldOrigin, oldOrigin);
				VectorSubtract(ent->v.angles, oldAngle, oldAngle);

				for (c=0; c<10; c++)
				{   // chain a max of 10 objects
					if (ent2->free) break;

					VectorAdd(oldOrigin, ent2->v.origin, ent2->v.origin);
					if ((int) ent2->v.flags & FL_MOVECHAIN_ANGLE)
					{
						VectorAdd(oldAngle, ent2->v.angles, ent2->v.angles);
					}

					if (originMoved && ent2->v.chainmoved)
					{	// callback function
						*pr_global_ptrs.self = EDICT_TO_PROG(ent2);
						*pr_global_ptrs.other = EDICT_TO_PROG(ent);
						PR_ExecuteProgram(ent2->v.chainmoved);
					}

					ent2 = PROG_TO_EDICT( ent2->v.movechain );
					if (ent2 == sv.edicts) break;

				}
			}
		}
	#endif
	}
	
	if (pr_global_ptrs.force_retouch && *pr_global_ptrs.force_retouch)
		PR_GLOBAL(force_retouch)--;

	sv.time += host_frametime;
}
Beispiel #20
0
/*
============
SV_PushRotate
============
*/
void SV_PushRotate (edict_t *pusher, float movetime)
{
	int			i, e, t, num_moved, slaves_moved;
	edict_t		*check, *block, *ground, *master, *slave;
	edict_t		*moved_edict[MAX_EDICTS];
	vec3_t		moved_from[MAX_EDICTS];
	vec3_t		move, a, amove, mins, maxs, move2, move3, testmove;
	vec3_t		entorig, pushorig, pushorigangles;
	vec3_t		org, org2, check_center;
	vec3_t		forward, right, up;
	qboolean	moveit;

	for (i=0 ; i<3 ; i++)
	{
		amove[i] = pusher->v.avelocity[i] * movetime;
		move[i] = pusher->v.velocity[i] * movetime;
		mins[i] = pusher->v.absmin[i] + move[i];
		maxs[i] = pusher->v.absmax[i] + move[i];
	}

	VectorSubtract (vec3_origin, amove, a);
	AngleVectors (a, forward, right, up);

	VectorCopy (pusher->v.origin, pushorig);
	VectorCopy (pusher->v.angles, pushorigangles);
	
// move the pusher to it's final position

	VectorAdd (pusher->v.origin, move, pusher->v.origin);
	VectorAdd (pusher->v.angles, amove, pusher->v.angles);

	pusher->v.ltime += movetime;
	SV_LinkEdict (pusher, false);

	master = pusher;
	slaves_moved = 0;

// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || 
		    check->v.movetype == MOVETYPE_FOLLOW || check->v.movetype == MOVETYPE_NOCLIP)
			continue;

		// if the entity is standing on the pusher, it will definitely be moved
		moveit = false;
		ground = PROG_TO_EDICT(check->v.groundentity);
		if ((int)check->v.flags & FL_ONGROUND)
		{
			if (ground == pusher)
			{
				moveit = true;
			}
			else
			{
				for (i=0; i<slaves_moved; i++)
				{
					if (ground == moved_edict[MAX_EDICTS - i - 1])
					{
						moveit = true;
						break;
					}
				}
			}
		}

		if (!moveit)
		{
			if ( check->v.absmin[0] >= maxs[0] || check->v.absmin[1] >= maxs[1] ||
				 check->v.absmin[2] >= maxs[2] || check->v.absmax[0] <= mins[0] ||
			     check->v.absmax[1] <= mins[1] || check->v.absmax[2] <= mins[2] )
			{
				for (i=0; i<slaves_moved; i++)
				{
					slave = moved_edict[MAX_EDICTS - i - 1];
					if ( check->v.absmin[0] >= slave->v.absmax[0]
					|| check->v.absmin[1] >= slave->v.absmax[1]
					|| check->v.absmin[2] >= slave->v.absmax[2]
					|| check->v.absmax[0] <= slave->v.absmin[0]
					|| check->v.absmax[1] <= slave->v.absmin[1]
					|| check->v.absmax[2] <= slave->v.absmin[2] )
						continue;
				}
				if (i == slaves_moved)
					continue;
			}

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

		// remove the onground flag for non-players
		if (check->v.movetype != MOVETYPE_WALK)
			check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
		
		VectorCopy (check->v.origin, entorig);
		VectorCopy (check->v.origin, moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

//put check in first move spot
		VectorAdd (check->v.origin, move, check->v.origin);
//Use center of model, like in QUAKE!!!!  Our origins are on the bottom!!!
		for (i=0 ; i<3 ; i++)
			check_center[i] = (check->v.absmin[i] + check->v.absmax[i])/2;
// calculate destination position
		VectorSubtract (check_center, pusher->v.origin, org);
//put check back
		VectorSubtract (check->v.origin, move, check->v.origin);
		org2[0] = DotProduct (org, forward);
		org2[1] = -DotProduct (org, right);
		org2[2] = DotProduct (org, up);
		VectorSubtract (org2, org, move2);

		//Add all moves together
		VectorAdd(move,move2,move3);

		// try moving the contacted entity 
		for( t = 0; t < 13; t++)
		{
			switch(t)
			{
				case 0:
				//try x, y and z
					VectorCopy(move3,testmove);
					break;
				case 1:
				//Try xy only
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=move3[0];
					testmove[1]=move3[1];
					testmove[2]=0;
					break;
				case 2:
				//Try z only
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=0;
					testmove[1]=0;
					testmove[2]=move3[2];
					break;
				case 3:
				//Try none
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=0;
					testmove[1]=0;
					testmove[2]=0;
					break;
				case 4:
				//Try xy in opposite dir
					testmove[0]=move3[0]*-1;
					testmove[1]=move3[1]*-1;
					testmove[2]=move3[2];
					break;
				case 5:
				//Try z in opposite dir
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=move3[0];
					testmove[1]=move3[1];
					testmove[2]=move3[2]*-1;
					break;
				case 6:
				//Try xyz in opposite dir
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=move3[0]*-1;
					testmove[1]=move3[1]*-1;
					testmove[2]=move3[2]*-1;
					break;
				case 7:
				//Try move3 times 2
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					VectorScale(move3,2,testmove);
					break;
				case 8:
				//Try normalized org
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					VectorScale(org,movetime,org);//movetime*20?
					VectorCopy(org,testmove);
					break;
				case 9:
				//Try normalized org z * 3 only
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=0;
					testmove[1]=0;
					testmove[2]=org[2]*3;//was: +org[2]*(fastfabs(org[1])+fastfabs(org[2]));
					break;
				case 10:
				//Try normalized org xy * 2 only
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=org[0]*2;//was: +org[0]*fastfabs(org[2]);
					testmove[1]=org[1]*2;//was: +org[1]*fastfabs(org[2]);
					testmove[2]=0;
					break;
				case 11:
				//Try xy in opposite org dir
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=org[0]*-2;
					testmove[1]=org[1]*-2;
					testmove[2]=org[2];
					break;
				case 12:
				//Try z in opposite dir
					VectorSubtract(check->v.origin,testmove,check->v.origin);
					testmove[0]=org[0];
					testmove[1]=org[1];
					testmove[2]=org[2]*-3;
					break;
			}

			if(t!=3)
			{
				//THIS IS VERY BAD BAD HACK...
				pusher->v.solid = SOLID_NOT;
				SV_PushEntity (check, move3);
				//@@TODO: do we ever want to do anybody's angles?  maybe just yaw???
				//		if (!((int)check->v.flags & (FL_CLIENT | FL_MONSTER)))
				//			VectorAdd (check->v.angles, amove, check->v.angles);
				check->v.angles[YAW] += amove[YAW];
				pusher->v.solid = SOLID_BSP;
			}
			// if it is still inside the pusher, block
			block = SV_TestEntityPosition (check);
			if(!block)
				break;
		}

		if (block)
		{	// fail the move
			//			Con_DPrintf("Check blocked\n");
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
			{	// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				VectorCopy (check->v.mins, check->v.maxs);
				continue;
			}
			
			VectorCopy (entorig, check->v.origin);
			SV_LinkEdict (check, true);
			
			VectorCopy (pushorig, pusher->v.origin);
			VectorCopy (pushorigangles, pusher->v.angles);
			SV_LinkEdict (pusher, false);
			pusher->v.ltime -= movetime;
			
			for (i=0; i<slaves_moved; i++)
			{
				slave = moved_edict[MAX_EDICTS - i - 1];
				VectorCopy (moved_from[MAX_EDICTS - i - 1], slave->v.angles);
				SV_LinkEdict (slave, false);
				slave->v.ltime -= movetime;
			}
			
			// if the pusher has a "blocked" function, call it
			// otherwise, just stay in place until the obstacle is gone
			if (pusher->v.blocked)
			{
				*pr_global_ptrs.self = EDICT_TO_PROG(pusher);
				*pr_global_ptrs.other = EDICT_TO_PROG(check);
				PR_ExecuteProgram (pusher->v.blocked);
			}
			
			// move back any entities we already moved
			for (i=0 ; i<num_moved ; i++)
			{
				VectorCopy (moved_from[i], moved_edict[i]->v.origin);
				//@@TODO:: see above
				//				if (!((int)moved_edict[i]->v.flags & (FL_CLIENT | FL_MONSTER)))
				//					VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
				moved_edict[i]->v.angles[YAW] -= amove[YAW];
				
				SV_LinkEdict (moved_edict[i], false);
			}
			return;
		}
	}
}
Beispiel #21
0
/*
============
SV_PushRotate

============
*/
void SV_PushRotate (edict_t *pusher, float movetime)
{
	int			i, e;
	edict_t		*check, *block;
	vec3_t		move, a, amove;
	vec3_t		entorig, pushorig;
	int			num_moved;
	edict_t		*moved_edict[MAX_EDICTS];
	vec3_t		moved_from[MAX_EDICTS];
	vec3_t		org, org2;
	vec3_t		forward, right, up;

	if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2])
	{
		pusher->v.ltime += movetime;
		return;
	}

	for (i=0 ; i<3 ; i++)
		amove[i] = pusher->v.avelocity[i] * movetime;

	VectorSubtract (vec3_origin, amove, a);
	AngleVectors (a, forward, right, up);

	VectorCopy (pusher->v.angles, pushorig);
	
// move the pusher to it's final position

	VectorAdd (pusher->v.angles, amove, pusher->v.angles);
	pusher->v.ltime += movetime;
	SV_LinkEdict (pusher, false);


// see if any solid entities are inside the final position
	num_moved = 0;
	check = NEXT_EDICT(sv.edicts);
	for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
	{
		if (check->free)
			continue;
		if (check->v.movetype == MOVETYPE_PUSH
		|| check->v.movetype == MOVETYPE_NONE
#ifdef QUAKE2
		|| check->v.movetype == MOVETYPE_FOLLOW
#endif
		|| check->v.movetype == MOVETYPE_NOCLIP)
			continue;

	// if the entity is standing on the pusher, it will definately be moved
		if ( ! ( ((int)check->v.flags & FL_ONGROUND)
		&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
		{
			if ( check->v.absmin[0] >= pusher->v.absmax[0]
			|| check->v.absmin[1] >= pusher->v.absmax[1]
			|| check->v.absmin[2] >= pusher->v.absmax[2]
			|| check->v.absmax[0] <= pusher->v.absmin[0]
			|| check->v.absmax[1] <= pusher->v.absmin[1]
			|| check->v.absmax[2] <= pusher->v.absmin[2] )
				continue;

		// see if the ent's bbox is inside the pusher's final position
			if (!SV_TestEntityPosition (check))
				continue;
		}

	// remove the onground flag for non-players
		if (check->v.movetype != MOVETYPE_WALK)
			check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
		
		VectorCopy (check->v.origin, entorig);
		VectorCopy (check->v.origin, moved_from[num_moved]);
		moved_edict[num_moved] = check;
		num_moved++;

		// calculate destination position
		VectorSubtract (check->v.origin, pusher->v.origin, org);
		org2[0] = DotProduct (org, forward);
		org2[1] = -DotProduct (org, right);
		org2[2] = DotProduct (org, up);
		VectorSubtract (org2, org, move);

		// try moving the contacted entity 
		pusher->v.solid = SOLID_NOT;
		SV_PushEntity (check, move);
		pusher->v.solid = SOLID_BSP;

	// if it is still inside the pusher, block
		block = SV_TestEntityPosition (check);
		if (block)
		{	// fail the move
			if (check->v.mins[0] == check->v.maxs[0])
				continue;
			if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
			{	// corpse
				check->v.mins[0] = check->v.mins[1] = 0;
				VectorCopy (check->v.mins, check->v.maxs);
				continue;
			}
			
			VectorCopy (entorig, check->v.origin);
			SV_LinkEdict (check, true);

			VectorCopy (pushorig, pusher->v.angles);
			SV_LinkEdict (pusher, false);
			pusher->v.ltime -= movetime;

			// if the pusher has a "blocked" function, call it
			// otherwise, just stay in place until the obstacle is gone
			if (pusher->v.blocked)
			{
				pr_global_struct->self = ((int)EDICT_TO_PROG(pusher));
				pr_global_struct->other = ((int)EDICT_TO_PROG(check));
				PR_ExecuteProgram (pusher->v.blocked);
			}
			
		// move back any entities we already moved
			for (i=0 ; i<num_moved ; i++)
			{
				VectorCopy (moved_from[i], moved_edict[i]->v.origin);
				VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
				SV_LinkEdict (moved_edict[i], false);
			}
			return;
		}
		else
		{
			VectorAdd (check->v.angles, amove, check->v.angles);
		}
	}

	
}
Beispiel #22
0
/*
================
SV_Physics

================
*/
void SV_Physics (void)
{
    int		i;
    static double	old_time;
    byte *ent_global_ptr = (byte *) sv.edicts;

    DEBUGPRINT(PHYSICS,MEDIUM) printf("GAJA: In Physics parallel\n");

    // don't bother running a frame if sys_ticrate seconds haven't passed
    host_frametime = realtime - old_time;
    if (host_frametime < sv_mintic.value)
        return;
    if (host_frametime > sv_maxtic.value)
        host_frametime = sv_maxtic.value;
    old_time = realtime;

    pr_global_struct->frametime = host_frametime;

    SV_ProgStartFrame ();

    //
    // treat each object in turn
    // even the world gets a chance to think
    //

    if (pr_global_struct->force_retouch)
    {
        // GAJA: RUN SERIAL
        edict_t *ent;
        ent = sv.edicts;
        for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
        {
            if (ent->free)
                continue;

            SV_LinkEdict (ent, true); // force retouch even for stationary

            if (i > 0 && i <= MAX_CLIENTS)
                continue;   // clients are run directly from packets

            SV_RunEntity (ent);
            SV_RunNewmis ();
        }
    }
    else
    {
        // GAJA: RUN PARALLEL
        omp_set_num_threads(NoThreads);

        #pragma omp parallel for schedule(dynamic,1) private(i) shared(svs, sv, sv_areanodes, pr_global_struct, realtime, movevars) 
        for (i=0 ; i<sv.num_edicts ; i++)
        {
            edict_t *ent = (edict_t *) (ent_global_ptr + pr_edict_size * i);

            if (ent->free || i <= MAX_CLIENTS)
                continue;

            DEBUGPRINT(PHYSICS,HIGH) printf("Thread= %d\t\tBefore Transaction\n", omp_get_thread_num());

            inTransaction = true;

            // ~+~+~+~+~+
            // StartTransaction
            LOCK(global_lock)
            TRANSACTION

                //if (pr_global_struct->force_retouch)
                //    SV_LinkEdict (ent, true);	// force retouch even for stationary

                //if (i > MAX_CLIENTS)	// don't run client entities (clients are run directly from packets)
 			    //{
                SV_RunEntity (ent);
                SV_RunNewmis ();
                //}

            TRANSACTION_END 
            UNLOCK(global_lock)
            // EndTransaction

            inTransaction = false;

            DEBUGPRINT(PHYSICS,HIGH) printf("Thread= %d\t\tAfter Transaction\n", omp_get_thread_num());


            // send messages and packets generated during transaction
            FlushTMOutput();
        } // end for

    } //end if


    if (pr_global_struct->force_retouch)
        pr_global_struct->force_retouch--;	
}