⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pr_cmds.c

📁 quake1 dos源代码最新版本
💻 C
📖 第 1 页 / 共 5 页
字号:

	for (i=0 ; i<MAX_SOUNDS ; i++)
	{
		if (!sv.sound_precache[i])
		{
			sv.sound_precache[i] = s;
			return;
		}
		if (!strcmp(sv.sound_precache[i], s))
			return;
	}
	PR_RunError ("PF_precache_sound: overflow");
}

void PF_precache_model (void)
{
	char	*s;
	int		i;

	if (sv.state != ss_loading)
		PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");

	s = G_STRING(OFS_PARM0);
	G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
	PR_CheckEmptyString (s);

	for (i=0 ; i<MAX_MODELS ; i++)
	{
		if (!sv.model_precache[i])
		{
			sv.model_precache[i] = s;
			sv.models[i] = Mod_ForName (s, true);
			return;
		}
		if (!strcmp(sv.model_precache[i], s))
			return;
	}
	PR_RunError ("PF_precache_model: overflow");
}


void PF_coredump (void)
{
	ED_PrintEdicts ();
}

void PF_traceon (void)
{
	pr_trace = true;
}

void PF_traceoff (void)
{
	pr_trace = false;
}

void PF_eprint (void)
{
	ED_PrintNum (G_EDICTNUM(OFS_PARM0));
}

/*
===============
PF_walkmove

float(float yaw, float dist) walkmove
===============
*/
void PF_walkmove (void)
{
	edict_t	*ent;
	float	yaw, dist;
	vec3_t	move;
	dfunction_t	*oldf;
	int 	oldself;

	ent = PROG_TO_EDICT(pr_global_struct->self);
	yaw = G_FLOAT(OFS_PARM0);
	dist = G_FLOAT(OFS_PARM1);

	if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
	{
		G_FLOAT(OFS_RETURN) = 0;
		return;
	}

	yaw = yaw*M_PI*2 / 360;

	move[0] = cos(yaw)*dist;
	move[1] = sin(yaw)*dist;
	move[2] = 0;

// save program state, because SV_movestep may call other progs
	oldf = pr_xfunction;
	oldself = pr_global_struct->self;

	G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);


// restore program state
	pr_xfunction = oldf;
	pr_global_struct->self = oldself;
}

/*
===============
PF_droptofloor

void() droptofloor
===============
*/
void PF_droptofloor (void)
{
	edict_t		*ent;
	vec3_t		end;
	trace_t		trace;

	ent = PROG_TO_EDICT(pr_global_struct->self);

	VectorCopy (ent->v.origin, end);
	end[2] -= 256;

	trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);

	if (trace.fraction == 1 || trace.allsolid)
		G_FLOAT(OFS_RETURN) = 0;
	else
	{
		VectorCopy (trace.endpos, ent->v.origin);
		SV_LinkEdict (ent, false);
		ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
		ent->v.groundentity = EDICT_TO_PROG(trace.ent);
		G_FLOAT(OFS_RETURN) = 1;
	}
}

/*
===============
PF_lightstyle

void(float style, string value) lightstyle
===============
*/
void PF_lightstyle (void)
{
	int		style;
	char	*val;
	client_t	*client;
	int			j;

	style = G_FLOAT(OFS_PARM0);
	val = G_STRING(OFS_PARM1);

// change the string in sv
	sv.lightstyles[style] = val;

// send message to all clients on this server
	if (sv.state != ss_active)
		return;

	for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
		if (client->active || client->spawned)
		{
			MSG_WriteChar (&client->message, svc_lightstyle);
			MSG_WriteChar (&client->message,style);
			MSG_WriteString (&client->message, val);
		}
}

void PF_rint (void)
{
	float	f;
	f = G_FLOAT(OFS_PARM0);
	if (f > 0)
		G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
	else
		G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
}
void PF_floor (void)
{
	G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
}
void PF_ceil (void)
{
	G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
}


/*
=============
PF_checkbottom
=============
*/
void PF_checkbottom (void)
{
	edict_t	*ent;

	ent = G_EDICT(OFS_PARM0);

	G_FLOAT(OFS_RETURN) = SV_CheckBottom (ent);
}

/*
=============
PF_pointcontents
=============
*/
void PF_pointcontents (void)
{
	float	*v;

	v = G_VECTOR(OFS_PARM0);

	G_FLOAT(OFS_RETURN) = SV_PointContents (v);
}

/*
=============
PF_nextent

entity nextent(entity)
=============
*/
void PF_nextent (void)
{
	int		i;
	edict_t	*ent;

	i = G_EDICTNUM(OFS_PARM0);
	while (1)
	{
		i++;
		if (i == sv.num_edicts)
		{
			RETURN_EDICT(sv.edicts);
			return;
		}
		ent = EDICT_NUM(i);
		if (!ent->free)
		{
			RETURN_EDICT(ent);
			return;
		}
	}
}

/*
=============
PF_aim

Pick a vector for the player to shoot along
vector aim(entity, missilespeed)
=============
*/
cvar_t	*sv_aim;

void PF_aim (void)
{
	edict_t	*ent, *check, *bestent;
	vec3_t	start, dir, end, bestdir;
	int		i, j;
	trace_t	tr;
	float	dist, bestdist;
//	float	speed;	// 2001-12-10 Reduced compiler warnings by Jeff Ford

	ent = G_EDICT(OFS_PARM0);
//	speed = G_FLOAT(OFS_PARM1);	// 2001-12-10 Reduced compiler warnings by Jeff Ford

	VectorCopy (ent->v.origin, start);
	start[2] += 20;

// try sending a trace straight
	VectorCopy (pr_global_struct->v_forward, dir);
	VectorMA (start, 2048, dir, end);
	tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
	if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
	&& (!teamplay->value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
	{
		VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
		return;
	}


// try all possible entities
	VectorCopy (dir, bestdir);
	bestdist = sv_aim->value;
	bestent = NULL;

	check = NEXT_EDICT(sv.edicts);
	for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
	{
		if (check->v.takedamage != DAMAGE_AIM)
			continue;
		if (check == ent)
			continue;
		if (teamplay->value && ent->v.team > 0 && ent->v.team == check->v.team)
			continue;	// don't aim at teammate
		for (j=0 ; j<3 ; j++)
			end[j] = check->v.origin[j]
			+ 0.5*(check->v.mins[j] + check->v.maxs[j]);
		VectorSubtract (end, start, dir);
		VectorNormalize (dir);
		dist = DotProduct (dir, pr_global_struct->v_forward);
		if (dist < bestdist)
			continue;	// to far to turn
		tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
		if (tr.ent == check)
		{	// can shoot at this one
			bestdist = dist;
			bestent = check;
		}
	}

	if (bestent)
	{
		VectorSubtract (bestent->v.origin, ent->v.origin, dir);
		dist = DotProduct (dir, pr_global_struct->v_forward);
		VectorScale (pr_global_struct->v_forward, dist, end);
		end[2] = dir[2];
		VectorNormalize (end);
		VectorCopy (end, G_VECTOR(OFS_RETURN));
	}
	else
	{
		VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
	}
}

/*
==============
PF_changeyaw

This was a major timewaster in progs, so it was converted to C
==============
*/
void PF_changeyaw (void)
{
	edict_t		*ent;
	float		ideal, current, move, speed;

	ent = PROG_TO_EDICT(pr_global_struct->self);
	current = anglemod( ent->v.angles[1] );
	ideal = ent->v.ideal_yaw;
	speed = ent->v.yaw_speed;

	if (current == ideal)
		return;
	move = ideal - current;
	if (ideal > current)
	{
		if (move >= 180)
			move = move - 360;
	}
	else
	{
		if (move <= -180)
			move = move + 360;
	}
	if (move > 0)
	{
		if (move > speed)
			move = speed;
	}
	else
	{
		if (move < -speed)
			move = -speed;
	}

	ent->v.angles[1] = anglemod (current + move);
}

//#ifdef QUAKE2	// 2001-09-16 Quake 2 builtin functions by id/Maddes
/*
==============
PF_changepitch
==============
*/
void PF_changepitch (void)
{
	edict_t		*ent;
	float		ideal, current, move, speed;
	eval_t		*val;	// 2001-09-16 PF_changepitch entity check by LordHavoc

	ent = G_EDICT(OFS_PARM0);
	current = anglemod( ent->v.angles[0] );
#ifdef QUAKE2	// 2001-09-16 PF_changepitch entity check by LordHavoc
	ideal = ent->v.idealpitch;
	speed = ent->v.pitch_speed;
// 2001-09-16 PF_changepitch entity check by LordHavoc  start
#else
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  start
//	val = GetEdictFieldValue(ent, "idealpitch");
	val = GETEDICTFIELDVALUE(ent, pr_field_idealpitch);
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  end
	if (val)
		ideal = val->_float;
	else
	{
		PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
		return;
	}
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  start
//	val = GetEdictFieldValue(ent, "pitch_speed");
	val = GETEDICTFIELDVALUE(ent, pr_field_pitch_speed);
// 2001-11-15 Better GetEdictFieldValue performance by LordHavoc/Maddes  end
	if (val)
		speed = val->_float;
	else
	{
		PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
		return;
	}
#endif
// 2001-09-16 PF_changepitch entity check by LordHavoc  end

	if (current == ideal)
		return;
	move = ideal - current;
	if (ideal > current)
	{
		if (move >= 180)
			move = move - 360;
	}
	else
	{
		if (move <= -180)
			move = move + 360;
	}
	if (move > 0)
	{
		if (move > speed)
			move = speed;
	}
	else
	{
		if (move < -speed)
			move = -speed;
	}

	ent->v.angles[0] = anglemod (current + move);
}
//#endif	// 2001-09-16 Quake 2 builtin functions by id/Maddes

/*
===============================================================================

MESSAGE WRITING

===============================================================================
*/

// 2000-05-02 NVS SVC by Maddes  start
/*
#define	MSG_BROADCAST	0		// unreliable to all
#define	MSG_ONE			1		// reliable to one (msg_entity)
#define	MSG_ALL			2		// reliable to all
#define	MSG_INIT		3		// write to the init string
*/
// 2000-05-02 NVS SVC by Maddes  end

sizebuf_t *WriteDest (void)
{
	int		entnum;
	int		dest;
	edict_t	*ent;

	dest = G_FLOAT(OFS_PARM0);
	switch (dest)
	{
	case MSG_BROADCAST:
		return &sv.datagram;

	case MSG_ONE:
		ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
		entnum = NUM_FOR_EDICT(ent);
		if (entnum < 1 || entnum > svs.maxclients)
			PR_RunError ("WriteDest: not a client");
		return &svs.clients[entnum-1].message;

	case MSG_ALL:
		return &sv.reliable_datagram;

	case MSG_INIT:
		return &sv.signon;

	default:
		PR_RunError ("WriteDest: bad destination");
		break;
	}

	return NULL;
}

void PF_WriteByte (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteByte (G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}

void PF_WriteChar (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteChar (G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}

void PF_WriteShort (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteShort (G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}

void PF_WriteLong (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteLong (G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}

void PF_WriteAngle (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteAngle (G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}

void PF_WriteCoord (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteCoord (G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}

void PF_WriteString (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteString (G_FLOAT(OFS_PARM0), G_STRING(OFS_PARM1), NULL);
	}
	else
	{
// 2000-05-02 NVS SVC by Maddes  end
		MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
	}			// 2000-05-02 NVS SVC by Maddes
}


void PF_WriteEntity (void)
{
// 2000-05-02 NVS SVC by Maddes  start
	if (sv.nvs_msgwrites)
	{
		NVS_WriteShort (G_FLOAT(OFS_PARM0), G_EDICTNUM(OFS_PARM1), NULL);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -