quakeforge/libs/gamecode/builtins/pr_cmds.c

641 lines
12 KiB
C
Raw Normal View History

/*
pr_cmds.c
(description)
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include <stdlib.h>
#include "QF/clip_hull.h"
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/msg.h"
#include "QF/va.h"
#include "QF/progs.h"
#include "QF/zone.h"
#include "QF/mathlib.h"
#include "QF/console.h"
#if 0
#include "compat.h"
#include "crudefile.h"
#include "server.h"
#include "sv_pr_cmds.h"
#include "sv_progs.h"
#include "world.h"
#endif
#define RETURN_EDICT(p, e) ((p)->pr_globals[OFS_RETURN].integer_var = EDICT_TO_PROG(p, e))
#define RETURN_STRING(p, s) ((p)->pr_globals[OFS_RETURN].integer_var = PR_SetString((p), s))
/*
BUILT-IN FUNCTIONS
*/
const char *
PF_VarString (progs_t *pr, int first)
{
int i;
int len;
char *out;
for (len = 0, i = first; i < pr->pr_argc; i++)
len += strlen (G_STRING (pr, (OFS_PARM0 + i * 3)));
out = Hunk_TempAlloc (len + 1);
for (i = first; i < pr->pr_argc; i++)
strcat (out, G_STRING (pr, (OFS_PARM0 + i * 3)));
return out;
}
/*
PF_normalize
vector normalize(vector)
*/
void
PF_normalize (progs_t *pr)
{
float *value1;
vec3_t newvalue;
float new;
value1 = G_VECTOR (pr, OFS_PARM0);
new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] * value1[2];
new = sqrt (new);
if (new == 0)
newvalue[0] = newvalue[1] = newvalue[2] = 0;
else {
new = 1 / new;
newvalue[0] = value1[0] * new;
newvalue[1] = value1[1] * new;
newvalue[2] = value1[2] * new;
}
VectorCopy (newvalue, G_VECTOR (pr, OFS_RETURN));
}
/*
PF_vlen
scalar vlen(vector)
*/
void
PF_vlen (progs_t *pr)
{
float *value1;
float new;
value1 = G_VECTOR (pr, OFS_PARM0);
new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] * value1[2];
new = sqrt (new);
G_FLOAT (pr, OFS_RETURN) = new;
}
/*
PF_vectoyaw
float vectoyaw(vector)
*/
void
PF_vectoyaw (progs_t *pr)
{
float *value1;
float yaw;
value1 = G_VECTOR (pr, OFS_PARM0);
if (value1[1] == 0 && value1[0] == 0)
yaw = 0;
else {
yaw = (int) (atan2 (value1[1], value1[0]) * 180 / M_PI);
if (yaw < 0)
yaw += 360;
}
G_FLOAT (pr, OFS_RETURN) = yaw;
}
/*
PF_vectoangles
vector vectoangles(vector)
*/
void
PF_vectoangles (progs_t *pr)
{
float *value1;
float forward;
float yaw, pitch;
value1 = G_VECTOR (pr, OFS_PARM0);
if (value1[1] == 0 && value1[0] == 0) {
yaw = 0;
if (value1[2] > 0)
pitch = 90;
else
pitch = 270;
} else {
yaw = (int) (atan2 (value1[1], value1[0]) * 180 / M_PI);
if (yaw < 0)
yaw += 360;
forward = sqrt (value1[0] * value1[0] + value1[1] * value1[1]);
pitch = (int) (atan2 (value1[2], forward) * 180 / M_PI);
if (pitch < 0)
pitch += 360;
}
G_FLOAT (pr, OFS_RETURN + 0) = pitch;
G_FLOAT (pr, OFS_RETURN + 1) = yaw;
G_FLOAT (pr, OFS_RETURN + 2) = 0;
}
/*
PF_Random
Returns a number from 0<= num < 1
random()
*/
void
PF_random (progs_t *pr)
{
float num;
num = (rand () & 0x7fff) / ((float) 0x7fff);
G_FLOAT (pr, OFS_RETURN) = num;
}
/*
PF_break
break()
*/
void
PF_break (progs_t *pr)
{
Con_Printf ("break statement\n");
*(int *) -4 = 0; // dump to debugger
// PR_RunError (pr, "break statement");
}
#if 0
/*
PF_localcmd
Sends text to the host's execution buffer
localcmd (string)
*/
void
PF_localcmd (progs_t *pr)
{
const char *str;
str = G_STRING (pr, OFS_PARM0);
Cbuf_AddText (str);
}
#endif
/*
PF_cvar
float cvar (string)
*/
void
PF_cvar (progs_t *pr)
{
const char *str;
str = G_STRING (pr, OFS_PARM0);
G_FLOAT (pr, OFS_RETURN) = Cvar_VariableValue (str);
}
/*
PF_cvar_set
float cvar (string)
*/
void
PF_cvar_set (progs_t *pr)
{
const char *var_name, *val;
cvar_t *var;
var_name = G_STRING (pr, OFS_PARM0);
val = G_STRING (pr, OFS_PARM1);
var = Cvar_FindVar (var_name);
if (!var)
var = Cvar_FindAlias (var_name);
if (!var) {
// FIXME: make Con_DPrint?
Con_Printf ("PF_cvar_set: variable %s not found\n", var_name);
return;
}
Cvar_Set (var, val);
}
char pr_string_temp[128];
void
PF_ftos (progs_t *pr)
{
float v;
int i; // 1999-07-25 FTOS fix by Maddes
v = G_FLOAT (pr, OFS_PARM0);
if (v == (int) v)
snprintf (pr_string_temp, sizeof (pr_string_temp), "%d", (int) v);
else
// 1999-07-25 FTOS fix by Maddes start
{
snprintf (pr_string_temp, sizeof (pr_string_temp), "%1f", v);
for (i = strlen (pr_string_temp) - 1;
i > 0 && pr_string_temp[i] == '0' && pr_string_temp[i - 1] != '.';
i--) {
pr_string_temp[i] = 0;
}
}
// 1999-07-25 FTOS fix by Maddes end
G_INT (pr, OFS_RETURN) = PR_SetString (pr, pr_string_temp);
}
void
PF_fabs (progs_t *pr)
{
float v;
v = G_FLOAT (pr, OFS_PARM0);
G_FLOAT (pr, OFS_RETURN) = fabs (v);
}
void
PF_vtos (progs_t *pr)
{
snprintf (pr_string_temp, sizeof (pr_string_temp), "'%5.1f %5.1f %5.1f'",
G_VECTOR (pr, OFS_PARM0)[0], G_VECTOR (pr, OFS_PARM0)[1],
G_VECTOR (pr, OFS_PARM0)[2]);
G_INT (pr, OFS_RETURN) = PR_SetString (pr, pr_string_temp);
}
// entity (entity start, .string field, string match) find = #5;
void
PF_Find (progs_t *pr)
{
int e;
int f;
const char *s, *t;
edict_t *ed;
e = G_EDICTNUM (pr, OFS_PARM0);
f = G_INT (pr, OFS_PARM1);
s = G_STRING (pr, OFS_PARM2);
if (!s)
PR_RunError (pr, "PF_Find: bad search string");
for (e++; e < *pr->num_edicts; e++) {
ed = EDICT_NUM (pr, e);
if (ed->free)
continue;
t = E_STRING (pr, ed, f);
if (!t)
continue;
if (!strcmp (t, s)) {
RETURN_EDICT (pr, ed);
return;
}
}
RETURN_EDICT (pr, *pr->edicts);
}
void
PF_coredump (progs_t *pr)
{
ED_PrintEdicts (pr, "");
}
void
PF_traceon (progs_t *pr)
{
pr->pr_trace = true;
}
void
PF_traceoff (progs_t *pr)
{
pr->pr_trace = false;
}
void
PF_eprint (progs_t *pr)
{
ED_PrintNum (pr, G_EDICTNUM (pr, OFS_PARM0));
}
/*
PF_dprint
*/
void
PF_dprint (progs_t *pr)
{
Con_Printf ("%s", PF_VarString (pr, 0));
}
void
PF_rint (progs_t *pr)
{
float f;
f = G_FLOAT (pr, OFS_PARM0);
if (f > 0)
G_FLOAT (pr, OFS_RETURN) = (int) (f + 0.5);
else
G_FLOAT (pr, OFS_RETURN) = (int) (f - 0.5);
}
void
PF_floor (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = floor (G_FLOAT (pr, OFS_PARM0));
}
void
PF_ceil (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = ceil (G_FLOAT (pr, OFS_PARM0));
}
/*
PF_nextent
entity nextent(entity)
*/
void
PF_nextent (progs_t *pr)
{
int i;
edict_t *ent;
i = G_EDICTNUM (pr, OFS_PARM0);
while (1) {
i++;
if (i == *pr->num_edicts) {
RETURN_EDICT (pr, *pr->edicts);
return;
}
ent = EDICT_NUM (pr, i);
if (!ent->free) {
RETURN_EDICT (pr, ent);
return;
}
}
}
/*
PF_stof
float(string s) stof
*/
void
PF_stof (progs_t *pr)
{
const char *s;
s = G_STRING (pr, OFS_PARM0);
G_FLOAT (pr, OFS_RETURN) = atof (s);
}
/*
PF_strlen
float(string s) strlen
*/
void
PF_strlen (progs_t *pr)
{
const char *s;
s = G_STRING (pr, OFS_PARM0);
G_FLOAT (pr, OFS_RETURN) = strlen(s);
}
/*
PF_charcount
float(string char, string s) charcount
*/
void
PF_charcount (progs_t *pr)
{
const char *s;
char goal;
int count;
goal = (G_STRING (pr, OFS_PARM0))[0];
if (goal == '\0')
G_FLOAT (pr, OFS_RETURN) = 0;
count = 0;
s = G_STRING (pr, OFS_PARM1);
while (*s) {
if (*s == goal)
count++;
s++;
}
G_FLOAT (pr, OFS_RETURN) = count;
}
#if 0
/*
PF_cfopen
float(string path, string mode) cfopen
*/
void
PF_cfopen (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = CF_Open (G_STRING (pr, OFS_PARM0), G_STRING (pr, OFS_PARM1));
}
/*
PF_cfclose
void (float desc) cfclose
*/
void
PF_cfclose (progs_t *pr)
{
CF_Close ((int) G_FLOAT (pr, OFS_PARM0));
}
/*
PF_cfread
string (float desc) cfread
*/
void
PF_cfread (progs_t *pr)
{
RETURN_STRING (pr, CF_Read((int) G_FLOAT (pr, OFS_PARM0)));
}
/*
PF_cfwrite
float (float desc, string buf) cfwrite
*/
void
PF_cfwrite (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = CF_Write((int) G_FLOAT(pr, OFS_PARM0), G_STRING (pr, OFS_PARM1));
}
/*
PF_cfeof
float () cfeof
*/
void
PF_cfeof (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = CF_EOF ((int) G_FLOAT(pr, OFS_PARM0));
}
/*
PF_cfquota
float () cfquota
*/
void
PF_cfquota (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = CF_Quota();
}
#endif
static vec_t
calc_dist (vec3_t p, vec3_t n, vec3_t *offsets)
{
vec_t d = DotProduct (p, n);
vec3_t s, v;
int i;
VectorScale (n, d, s);
for (i = 0; i < 3; i++)
if (s[i] < 0)
v[i] = offsets[0][i];
else
v[i] = offsets[1][i];
VectorAdd (p, v, v);
return DotProduct (v, n);
}
void
PF_Fixme (progs_t *pr)
{
PR_RunError (pr, "unimplemented bulitin");
}
void
PF_checkbuiltin (progs_t *pr)
{
G_FUNCTION (pr, OFS_RETURN) = -PR_FindBuiltin (pr, G_STRING (pr, OFS_PARM0));
}
void
PF_getbuiltin (progs_t *pr)
{
int i;
const char *name;
name = G_STRING (pr, OFS_PARM0);
i = PR_FindBuiltin (pr, name);
if (!i)
PR_RunError (pr, "PF_getfunction: function '%s' not found!\n", name);
G_FUNCTION (pr, OFS_RETURN) = -i;
}
void
PR_Cmds_Init (progs_t *pr)
{
PR_AddBuiltin (pr, "break", PF_break, 6); // void() break = #6
PR_AddBuiltin (pr, "random", PF_random, 7); // float() random = #7
PR_AddBuiltin (pr, "normalize", PF_normalize, 9); // vector(vector v) normalize = #9
PR_AddBuiltin (pr, "vlen", PF_vlen, 12); // float(vector v) vlen = #12
PR_AddBuiltin (pr, "vectoyaw", PF_vectoyaw, 13); // float(vector v) vectoyaw = #13
PR_AddBuiltin (pr, "find", PF_Find, 18); // entity(entity start, .string fld, string match) find = #18
PR_AddBuiltin (pr, "dprint", PF_dprint, 25); // void(string s) dprint = #25
PR_AddBuiltin (pr, "ftos", PF_ftos, 26); // void(string s) ftos = #26
PR_AddBuiltin (pr, "vtos", PF_vtos, 27); // void(string s) vtos = #27
PR_AddBuiltin (pr, "coredump", PF_coredump, 28); // void() coredump = #28
PR_AddBuiltin (pr, "traceon", PF_traceon, 29); // void() traceon = #29
PR_AddBuiltin (pr, "traceoff", PF_traceoff, 30); // void() traceoff = #30
PR_AddBuiltin (pr, "eprint", PF_eprint, 31); // void(entity e) = #31 debug print an entire entity
PR_AddBuiltin (pr, "rint", PF_rint, 36); // float(float v) rint = #36
PR_AddBuiltin (pr, "floor", PF_floor, 37); // float(float v) floor = #37
PR_AddBuiltin (pr, "ceil", PF_ceil, 38); // float(float v) ceil = #38
PR_AddBuiltin (pr, "fabs", PF_fabs, 43); // float(float f) fabs = #43
PR_AddBuiltin (pr, "cvar", PF_cvar, 45); // float(string s) cvar = #45
#if 0
PR_AddBuiltin (pr, "localcmd", PF_localcmd, 46); // void(string s) localcmd = #46
#endif
PR_AddBuiltin (pr, "nextent", PF_nextent, 47); // entity(entity e) nextent = #47
PR_AddBuiltin (pr, "vectoangles", PF_vectoangles, 51); // vector(vector v) vectoangles = #51
PR_AddBuiltin (pr, "cvar_set", PF_cvar_set, 72); // void(string var, string val) cvar_set = #72
PR_AddBuiltin (pr, "stof", PF_stof, 81); // float(string s) stof = #81
PR_AddBuiltin (pr, "strlen", PF_strlen, 100); // = #100
PR_AddBuiltin (pr, "charcount", PF_charcount, 101); // = #101
#if 0
PR_AddBuiltin (pr, "cfopen", PF_cfopen, 103); // float (string path, string mode) cfopen = #103
PR_AddBuiltin (pr, "cfclose", PF_cfclose, 104); // void (float desc) cfclose = #104
PR_AddBuiltin (pr, "cfread", PF_cfread, 105); // string (float desc) cfread = #105
PR_AddBuiltin (pr, "cfwrite", PF_cfwrite, 106); // float (float desc, string buf) cfwrite = #106
PR_AddBuiltin (pr, "cfeof", PF_cfeof, 107); // float (float desc) cfeof = #107
PR_AddBuiltin (pr, "cfquota", PF_cfquota, 108); // float () cfquota = #108
#endif
};