X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=pr_cmds.c;h=23edb617d31057d66a177123746b7abf3b8fcbc1;hp=2d08e4de3427f6dc054cbfe0cb29de378982a62d;hb=ac0f5054e02d4a5b855c5125f989b39770002a7a;hpb=417a0533c615db47efdb5a44679e9093309b0549 diff --git a/pr_cmds.c b/pr_cmds.c index 2d08e4de..23edb617 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -23,8 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default cvar_t pr_zone_min_strings = {0, "pr_zone_min_strings", "64"}; -mempool_t *pr_strings_mempool; - // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print #define STRINGTEMP_BUFFERS 16 #define STRINGTEMP_LENGTH 4096 @@ -39,7 +37,7 @@ static char *PR_GetTempString(void) return s; } -#define RETURN_EDICT(e) (G_INT(OFS_RETURN) = EDICT_TO_PROG(e)) +#define RETURN_EDICT(e) (PRVM_G_INT(OFS_RETURN) = PRVM_EDICT_TO_PROG(e)) #define PF_WARNING(s) do{Con_Printf(s);PR_PrintState();return;}while(0) #define PF_ERROR(s) do{Host_Error(s);return;}while(0) @@ -62,7 +60,7 @@ void PF_VarString(int first, char *out, int outlength) outend = out + outlength - 1; for (i = first;i < pr_argc && out < outend;i++) { - s = G_STRING((OFS_PARM0+i*3)); + s = PRVM_G_STRING((OFS_PARM0+i*3)); while (out < outend && *s) *out++ = *s++; } @@ -70,9 +68,12 @@ void PF_VarString(int first, char *out, int outlength) } char *ENGINE_EXTENSIONS = +"DP_BUTTONCHAT " +"DP_BUTTONUSE " "DP_CL_LOADSKY " "DP_CON_SET " "DP_CON_SETA " +"DP_CON_STARTMAP " "DP_EF_ADDITIVE " "DP_EF_BLUE " "DP_EF_FLAME " @@ -83,6 +84,7 @@ char *ENGINE_EXTENSIONS = "DP_EF_RED " "DP_EF_STARDUST " "DP_ENT_ALPHA " +"DP_ENT_COLORMOD " "DP_ENT_CUSTOMCOLORMAP " "DP_ENT_EXTERIORMODELTOCLIENT " "DP_ENT_GLOW " @@ -96,6 +98,7 @@ char *ENGINE_EXTENSIONS = "DP_GFX_SKYBOX " "DP_HALFLIFE_MAP " "DP_HALFLIFE_MAP_CVAR " +"DP_HALFLIFE_SPRITE " "DP_INPUTBUTTONS " "DP_LITSPRITES " "DP_LITSUPPORT " @@ -125,6 +128,8 @@ char *ENGINE_EXTENSIONS = "DP_QC_TRACE_MOVETYPE_WORLDONLY " "DP_QC_VECTORVECTORS " "DP_QUAKE2_MODEL " +"DP_QUAKE2_SPRITE " +"DP_QUAKE3_MAP " "DP_QUAKE3_MODEL " "DP_REGISTERCVAR " "DP_SND_DIRECTIONLESSATTNNONE " @@ -133,12 +138,16 @@ char *ENGINE_EXTENSIONS = "DP_SND_STEREOWAV " "DP_SOLIDCORPSE " "DP_SPRITE32 " +"DP_SV_BOTCLIENT " +"DP_SV_CLIENTCOLORS " +"DP_SV_CLIENTNAME " "DP_SV_DRAWONLYTOCLIENT " "DP_SV_DROPCLIENT " "DP_SV_EFFECT " "DP_SV_NODRAWTOCLIENT " "DP_SV_PING " "DP_SV_PLAYERPHYSICS " +"DP_SV_PRECACHEANYTIME " "DP_SV_PUNCHVECTOR " "DP_SV_ROTATINGBMODEL " "DP_SV_SETCOLOR " @@ -162,11 +171,13 @@ char *ENGINE_EXTENSIONS = "NEH_CMD_PLAY2 " "NEH_RESTOREGAME " "NXQ_GFX_LETTERBOX " +"PRYDON_CLIENTCURSOR " "TENEBRAE_GFX_DLIGHTS " "TW_SV_STEPCONTROL " +"NEXUIZ_PLAYERMODEL " ; -qboolean checkextension(char *name) +qboolean checkextension(const char *name) { int len; char *e, *start; @@ -198,7 +209,7 @@ checkextension(extensionname) */ void PF_checkextension (void) { - G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = checkextension(PRVM_G_STRING(OFS_PARM0)); } /* @@ -213,12 +224,12 @@ error(value) */ void PF_error (void) { - edict_t *ed; + prvm_edict_t *ed; char string[STRINGTEMP_LENGTH]; PF_VarString(0, string, sizeof(string)); - Con_Printf("======SERVER ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), string); - ed = PROG_TO_EDICT(pr_global_struct->self); + Con_Printf("======SERVER ERROR in %s:\n%s\n", PRVM_GetString(pr_xfunction->s_name), string); + ed = PRVM_PROG_TO_EDICT(prog->globals.server->self); ED_Print(ed); PF_ERROR("Program error"); @@ -236,12 +247,12 @@ objerror(value) */ void PF_objerror (void) { - edict_t *ed; + prvm_edict_t *ed; char string[STRINGTEMP_LENGTH]; PF_VarString(0, string, sizeof(string)); - Con_Printf("======OBJECT ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), string); - ed = PROG_TO_EDICT(pr_global_struct->self); + Con_Printf("======OBJECT ERROR in %s:\n%s\n", PRVM_GetString(pr_xfunction->s_name), string); + ed = PRVM_PROG_TO_EDICT(prog->globals.server->self); ED_Print(ed); ED_Free (ed); } @@ -257,7 +268,7 @@ makevectors(vector) */ void PF_makevectors (void) { - AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up); + AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up); } /* @@ -270,8 +281,8 @@ vectorvectors(vector, vector) */ void PF_vectorvectors (void) { - VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward); - VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up); + VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward); + VectorVectors(prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up); } /* @@ -285,21 +296,21 @@ setorigin (entity, origin) */ void PF_setorigin (void) { - edict_t *e; + prvm_edict_t *e; float *org; - e = G_EDICT(OFS_PARM0); - if (e == sv.edicts) + e = PRVM_G_EDICT(OFS_PARM0); + if (e == prog->edicts) PF_WARNING("setorigin: can not modify world entity\n"); - if (e->e->free) + if (e->priv.server->free) PF_WARNING("setorigin: can not modify free entity\n"); - org = G_VECTOR(OFS_PARM1); - VectorCopy (org, e->v->origin); + org = PRVM_G_VECTOR(OFS_PARM1); + VectorCopy (org, e->fields.server->origin); SV_LinkEdict (e, false); } -void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) +void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate) { int i; @@ -308,9 +319,9 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) PF_ERROR("SetMinMaxSize: backwards mins/maxs\n"); // set derived values - VectorCopy (min, e->v->mins); - VectorCopy (max, e->v->maxs); - VectorSubtract (max, min, e->v->size); + VectorCopy (min, e->fields.server->mins); + VectorCopy (max, e->fields.server->maxs); + VectorSubtract (max, min, e->fields.server->size); SV_LinkEdict (e, false); } @@ -327,16 +338,16 @@ setsize (entity, minvector, maxvector) */ void PF_setsize (void) { - edict_t *e; + prvm_edict_t *e; float *min, *max; - e = G_EDICT(OFS_PARM0); - if (e == sv.edicts) + e = PRVM_G_EDICT(OFS_PARM0); + if (e == prog->edicts) PF_WARNING("setsize: can not modify world entity\n"); - if (e->e->free) + if (e->priv.server->free) PF_WARNING("setsize: can not modify free entity\n"); - min = G_VECTOR(OFS_PARM1); - max = G_VECTOR(OFS_PARM2); + min = PRVM_G_VECTOR(OFS_PARM1); + max = PRVM_G_VECTOR(OFS_PARM2); SetMinMaxSize (e, min, max, false); } @@ -348,36 +359,31 @@ PF_setmodel setmodel(entity, model) ================= */ +static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16}; void PF_setmodel (void) { - edict_t *e; - char *m, **check; + prvm_edict_t *e; model_t *mod; int i; - e = G_EDICT(OFS_PARM0); - if (e == sv.edicts) + e = PRVM_G_EDICT(OFS_PARM0); + if (e == prog->edicts) PF_WARNING("setmodel: can not modify world entity\n"); - if (e->e->free) + if (e->priv.server->free) PF_WARNING("setmodel: can not modify free entity\n"); - m = G_STRING(OFS_PARM1); - -// check to see if model was properly precached - for (i=0, check = sv.model_precache ; *check ; i++, check++) - if (!strcmp(*check, m)) - break; - - if (!*check) - PF_WARNING(va("setmodel: no precache for model \"%s\"\n", m)); - + i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1); + e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]); + e->fields.server->modelindex = i; - e->v->model = PR_SetString(*check); - e->v->modelindex = i; - - mod = sv.models[ (int)e->v->modelindex]; + mod = sv.models[i]; if (mod) - SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true); + { + if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer) + SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true); + else + SetMinMaxSize (e, quakemins, quakemaxs, true); + } else SetMinMaxSize (e, vec3_origin, vec3_origin, true); } @@ -413,7 +419,7 @@ void PF_sprint (void) int entnum; char string[STRINGTEMP_LENGTH]; - entnum = G_EDICTNUM(OFS_PARM0); + entnum = PRVM_G_EDICTNUM(OFS_PARM0); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) { @@ -422,8 +428,6 @@ void PF_sprint (void) } client = svs.clients + entnum-1; - if (!client->netconnection) - return; PF_VarString(1, string, sizeof(string)); MSG_WriteChar(&client->message,svc_print); MSG_WriteString(&client->message, string); @@ -445,7 +449,7 @@ void PF_centerprint (void) int entnum; char string[STRINGTEMP_LENGTH]; - entnum = G_EDICTNUM(OFS_PARM0); + entnum = PRVM_G_EDICTNUM(OFS_PARM0); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) { @@ -454,8 +458,6 @@ void PF_centerprint (void) } client = svs.clients + entnum-1; - if (!client->netconnection) - return; PF_VarString(1, string, sizeof(string)); MSG_WriteChar(&client->message,svc_centerprint); MSG_WriteString(&client->message, string); @@ -475,7 +477,7 @@ void PF_normalize (void) vec3_t newvalue; float new; - value1 = G_VECTOR(OFS_PARM0); + value1 = PRVM_G_VECTOR(OFS_PARM0); new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; new = sqrt(new); @@ -490,7 +492,7 @@ void PF_normalize (void) newvalue[2] = value1[2] * new; } - VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); + VectorCopy (newvalue, PRVM_G_VECTOR(OFS_RETURN)); } /* @@ -505,12 +507,12 @@ void PF_vlen (void) float *value1; float new; - value1 = G_VECTOR(OFS_PARM0); + value1 = PRVM_G_VECTOR(OFS_PARM0); new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; new = sqrt(new); - G_FLOAT(OFS_RETURN) = new; + PRVM_G_FLOAT(OFS_RETURN) = new; } /* @@ -525,7 +527,7 @@ void PF_vectoyaw (void) float *value1; float yaw; - value1 = G_VECTOR(OFS_PARM0); + value1 = PRVM_G_VECTOR(OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) yaw = 0; @@ -536,7 +538,7 @@ void PF_vectoyaw (void) yaw += 360; } - G_FLOAT(OFS_RETURN) = yaw; + PRVM_G_FLOAT(OFS_RETURN) = yaw; } @@ -551,7 +553,7 @@ void PF_vectoangles (void) { double value1[3], forward, yaw, pitch; - VectorCopy(G_VECTOR(OFS_PARM0), value1); + VectorCopy(PRVM_G_VECTOR(OFS_PARM0), value1); if (value1[1] == 0 && value1[0] == 0) { @@ -581,7 +583,7 @@ void PF_vectoangles (void) pitch += 360; } - VectorSet(G_VECTOR(OFS_RETURN), pitch, yaw, 0); + VectorSet(PRVM_G_VECTOR(OFS_RETURN), pitch, yaw, 0); } /* @@ -595,11 +597,7 @@ random() */ void PF_random (void) { - float num; - - num = (rand ()&0x7fff) / ((float)0x7fff); - - G_FLOAT(OFS_RETURN) = num; + PRVM_G_FLOAT(OFS_RETURN) = lhrandom(0, 1); } /* @@ -615,10 +613,10 @@ void PF_particle (void) float color; float count; - org = G_VECTOR(OFS_PARM0); - dir = G_VECTOR(OFS_PARM1); - color = G_FLOAT(OFS_PARM2); - count = G_FLOAT(OFS_PARM3); + org = PRVM_G_VECTOR(OFS_PARM0); + dir = PRVM_G_VECTOR(OFS_PARM1); + color = PRVM_G_FLOAT(OFS_PARM2); + count = PRVM_G_FLOAT(OFS_PARM3); SV_StartParticle (org, dir, color, count); } @@ -631,27 +629,20 @@ PF_ambientsound */ void PF_ambientsound (void) { - char **check; - char *samp; + const char *samp; float *pos; float vol, attenuation; int soundnum, large; - pos = G_VECTOR (OFS_PARM0); - samp = G_STRING(OFS_PARM1); - vol = G_FLOAT(OFS_PARM2); - attenuation = G_FLOAT(OFS_PARM3); + pos = PRVM_G_VECTOR (OFS_PARM0); + samp = PRVM_G_STRING(OFS_PARM1); + vol = PRVM_G_FLOAT(OFS_PARM2); + attenuation = PRVM_G_FLOAT(OFS_PARM3); // check to see if samp was properly precached - for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++) - if (!strcmp(*check,samp)) - break; - - if (!*check) - { - Con_Printf("no precache: %s\n", samp); + soundnum = SV_SoundIndex(samp, 1); + if (!soundnum) return; - } large = false; if (soundnum >= 256) @@ -693,17 +684,17 @@ Larger attenuations will drop off. */ void PF_sound (void) { - char *sample; + const char *sample; int channel; - edict_t *entity; + prvm_edict_t *entity; int volume; float attenuation; - entity = G_EDICT(OFS_PARM0); - channel = G_FLOAT(OFS_PARM1); - sample = G_STRING(OFS_PARM2); - volume = G_FLOAT(OFS_PARM3) * 255; - attenuation = G_FLOAT(OFS_PARM4); + entity = PRVM_G_EDICT(OFS_PARM0); + channel = PRVM_G_FLOAT(OFS_PARM1); + sample = PRVM_G_STRING(OFS_PARM2); + volume = PRVM_G_FLOAT(OFS_PARM3) * 255; + attenuation = PRVM_G_FLOAT(OFS_PARM4); if (volume < 0 || volume > 255) PF_WARNING("SV_StartSound: volume must be in range 0-1\n"); @@ -745,29 +736,29 @@ void PF_traceline (void) float *v1, *v2; trace_t trace; int move; - edict_t *ent; + prvm_edict_t *ent; pr_xfunction->builtinsprofile += 30; - v1 = G_VECTOR(OFS_PARM0); - v2 = G_VECTOR(OFS_PARM1); - move = G_FLOAT(OFS_PARM2); - ent = G_EDICT(OFS_PARM3); + v1 = PRVM_G_VECTOR(OFS_PARM0); + v2 = PRVM_G_VECTOR(OFS_PARM1); + move = PRVM_G_FLOAT(OFS_PARM2); + ent = PRVM_G_EDICT(OFS_PARM3); trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent); - pr_global_struct->trace_allsolid = trace.allsolid; - pr_global_struct->trace_startsolid = trace.startsolid; - pr_global_struct->trace_fraction = trace.fraction; - pr_global_struct->trace_inwater = trace.inwater; - pr_global_struct->trace_inopen = trace.inopen; - VectorCopy (trace.endpos, pr_global_struct->trace_endpos); - VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + prog->globals.server->trace_allsolid = trace.allsolid; + prog->globals.server->trace_startsolid = trace.startsolid; + prog->globals.server->trace_fraction = trace.fraction; + prog->globals.server->trace_inwater = trace.inwater; + prog->globals.server->trace_inopen = trace.inopen; + VectorCopy (trace.endpos, prog->globals.server->trace_endpos); + VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal); + prog->globals.server->trace_plane_dist = trace.plane.dist; if (trace.ent) - pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts); // FIXME: add trace_endcontents } @@ -789,61 +780,61 @@ void PF_tracebox (void) float *v1, *v2, *m1, *m2; trace_t trace; int move; - edict_t *ent; + prvm_edict_t *ent; pr_xfunction->builtinsprofile += 30; - v1 = G_VECTOR(OFS_PARM0); - m1 = G_VECTOR(OFS_PARM1); - m2 = G_VECTOR(OFS_PARM2); - v2 = G_VECTOR(OFS_PARM3); - move = G_FLOAT(OFS_PARM4); - ent = G_EDICT(OFS_PARM5); + v1 = PRVM_G_VECTOR(OFS_PARM0); + m1 = PRVM_G_VECTOR(OFS_PARM1); + m2 = PRVM_G_VECTOR(OFS_PARM2); + v2 = PRVM_G_VECTOR(OFS_PARM3); + move = PRVM_G_FLOAT(OFS_PARM4); + ent = PRVM_G_EDICT(OFS_PARM5); trace = SV_Move (v1, m1, m2, v2, move, ent); - pr_global_struct->trace_allsolid = trace.allsolid; - pr_global_struct->trace_startsolid = trace.startsolid; - pr_global_struct->trace_fraction = trace.fraction; - pr_global_struct->trace_inwater = trace.inwater; - pr_global_struct->trace_inopen = trace.inopen; - VectorCopy (trace.endpos, pr_global_struct->trace_endpos); - VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + prog->globals.server->trace_allsolid = trace.allsolid; + prog->globals.server->trace_startsolid = trace.startsolid; + prog->globals.server->trace_fraction = trace.fraction; + prog->globals.server->trace_inwater = trace.inwater; + prog->globals.server->trace_inopen = trace.inopen; + VectorCopy (trace.endpos, prog->globals.server->trace_endpos); + VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal); + prog->globals.server->trace_plane_dist = trace.plane.dist; if (trace.ent) - pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts); } -extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore); -void PF_TraceToss (void) +extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore); +void PF_tracetoss (void) { trace_t trace; - edict_t *ent; - edict_t *ignore; + prvm_edict_t *ent; + prvm_edict_t *ignore; pr_xfunction->builtinsprofile += 600; - ent = G_EDICT(OFS_PARM0); - if (ent == sv.edicts) + ent = PRVM_G_EDICT(OFS_PARM0); + if (ent == prog->edicts) PF_WARNING("tracetoss: can not use world entity\n"); - ignore = G_EDICT(OFS_PARM1); + ignore = PRVM_G_EDICT(OFS_PARM1); trace = SV_Trace_Toss (ent, ignore); - pr_global_struct->trace_allsolid = trace.allsolid; - pr_global_struct->trace_startsolid = trace.startsolid; - pr_global_struct->trace_fraction = trace.fraction; - pr_global_struct->trace_inwater = trace.inwater; - pr_global_struct->trace_inopen = trace.inopen; - VectorCopy (trace.endpos, pr_global_struct->trace_endpos); - VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + prog->globals.server->trace_allsolid = trace.allsolid; + prog->globals.server->trace_startsolid = trace.startsolid; + prog->globals.server->trace_fraction = trace.fraction; + prog->globals.server->trace_inwater = trace.inwater; + prog->globals.server->trace_inopen = trace.inopen; + VectorCopy (trace.endpos, prog->globals.server->trace_endpos); + VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal); + prog->globals.server->trace_plane_dist = trace.plane.dist; if (trace.ent) - pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts); } @@ -869,7 +860,7 @@ qbyte checkpvs[MAX_MAP_LEAFS/8]; int PF_newcheckclient (int check) { int i; - edict_t *ent; + prvm_edict_t *ent; vec3_t org; // cycle to the next one @@ -888,16 +879,16 @@ int PF_newcheckclient (int check) if (i == svs.maxclients+1) i = 1; // look up the client's edict - ent = EDICT_NUM(i); + ent = PRVM_EDICT_NUM(i); // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop) - if (i != check && (ent->e->free || ent->v->health <= 0 || ((int)ent->v->flags & FL_NOTARGET))) + if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET))) continue; // found a valid client (possibly the same one again) break; } // get the PVS for the entity - VectorAdd(ent->v->origin, ent->v->view_ofs, org); + VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org); checkpvsbytes = 0; if (sv.worldmodel && sv.worldmodel->brush.FatPVS) checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs)); @@ -923,7 +914,7 @@ name checkclient () int c_invis, c_notvis; void PF_checkclient (void) { - edict_t *ent, *self; + prvm_edict_t *ent, *self; vec3_t view; // find a new check if on a new frame @@ -934,20 +925,20 @@ void PF_checkclient (void) } // return check if it might be visible - ent = EDICT_NUM(sv.lastcheck); - if (ent->e->free || ent->v->health <= 0) + ent = PRVM_EDICT_NUM(sv.lastcheck); + if (ent->priv.server->free || ent->fields.server->health <= 0) { - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); return; } // if current entity can't possibly see the check entity, return 0 - self = PROG_TO_EDICT(pr_global_struct->self); - VectorAdd(self->v->origin, self->v->view_ofs, view); + self = PRVM_PROG_TO_EDICT(prog->globals.server->self); + VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view); if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view)) { c_notvis++; - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); return; } @@ -971,20 +962,20 @@ stuffcmd (clientent, value) void PF_stuffcmd (void) { int entnum; - char *str; + const char *str; client_t *old; - entnum = G_EDICTNUM(OFS_PARM0); + entnum = PRVM_G_EDICTNUM(OFS_PARM0); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) { Con_Print("Can't stuffcmd to a non-client\n"); return; } - str = G_STRING(OFS_PARM1); + str = PRVM_G_STRING(OFS_PARM1); old = host_client; - if ((host_client = svs.clients + entnum-1) && host_client->netconnection) - Host_ClientCommands ("%s", str); + host_client = svs.clients + entnum-1; + Host_ClientCommands ("%s", str); host_client = old; } @@ -999,7 +990,7 @@ localcmd (string) */ void PF_localcmd (void) { - Cbuf_AddText(G_STRING(OFS_PARM0)); + Cbuf_AddText(PRVM_G_STRING(OFS_PARM0)); } /* @@ -1011,7 +1002,7 @@ float cvar (string) */ void PF_cvar (void) { - G_FLOAT(OFS_RETURN) = Cvar_VariableValue(G_STRING(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0)); } /* @@ -1023,7 +1014,7 @@ float cvar (string) */ void PF_cvar_set (void) { - Cvar_Set(G_STRING(OFS_PARM0), G_STRING(OFS_PARM1)); + Cvar_Set(PRVM_G_STRING(OFS_PARM0), PRVM_G_STRING(OFS_PARM1)); } /* @@ -1037,25 +1028,25 @@ findradius (origin, radius) */ void PF_findradius (void) { - edict_t *ent, *chain; + prvm_edict_t *ent, *chain; vec_t radius, radius2; vec3_t org, eorg, mins, maxs; int i; int numtouchedicts; - edict_t *touchedicts[MAX_EDICTS]; + prvm_edict_t *touchedicts[MAX_EDICTS]; - chain = (edict_t *)sv.edicts; + chain = (prvm_edict_t *)prog->edicts; - VectorCopy(G_VECTOR(OFS_PARM0), org); - radius = G_FLOAT(OFS_PARM1); + VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org); + radius = PRVM_G_FLOAT(OFS_PARM1); radius2 = radius * radius; - mins[0] = org[0] - radius; - mins[1] = org[1] - radius; - mins[2] = org[2] - radius; - maxs[0] = org[0] + radius; - maxs[1] = org[1] + radius; - maxs[2] = org[2] + radius; + mins[0] = org[0] - (radius + 1); + mins[1] = org[1] - (radius + 1); + mins[2] = org[2] - (radius + 1); + maxs[0] = org[0] + (radius + 1); + maxs[1] = org[1] + (radius + 1); + maxs[2] = org[2] + (radius + 1); numtouchedicts = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts); if (numtouchedicts > MAX_EDICTS) { @@ -1067,15 +1058,25 @@ void PF_findradius (void) { ent = touchedicts[i]; pr_xfunction->builtinsprofile++; + // Quake did not return non-solid entities but darkplaces does + // (note: this is the reason you can't blow up fallen zombies) + if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer) + continue; // LordHavoc: compare against bounding box rather than center so it // doesn't miss large objects, and use DotProduct instead of Length // for a major speedup - eorg[0] = (org[0] - ent->v->origin[0]) - bound(ent->v->mins[0], (org[0] - ent->v->origin[0]), ent->v->maxs[0]); - eorg[1] = (org[1] - ent->v->origin[1]) - bound(ent->v->mins[1], (org[1] - ent->v->origin[1]), ent->v->maxs[1]); - eorg[2] = (org[2] - ent->v->origin[2]) - bound(ent->v->mins[2], (org[2] - ent->v->origin[2]), ent->v->maxs[2]); + VectorSubtract(org, ent->fields.server->origin, eorg); + if (sv_gameplayfix_findradiusdistancetobox.integer) + { + eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]); + eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]); + eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]); + } + else + VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg); if (DotProduct(eorg, eorg) < radius2) { - ent->v->chain = EDICT_TO_PROG(chain); + ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain); chain = ent; } } @@ -1103,42 +1104,42 @@ void PF_ftos (void) { float v; char *s; - v = G_FLOAT(OFS_PARM0); + v = PRVM_G_FLOAT(OFS_PARM0); s = PR_GetTempString(); if ((float)((int)v) == v) sprintf(s, "%i", (int)v); else sprintf(s, "%f", v); - G_INT(OFS_RETURN) = PR_SetString(s); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } void PF_fabs (void) { float v; - v = G_FLOAT(OFS_PARM0); - G_FLOAT(OFS_RETURN) = fabs(v); + v = PRVM_G_FLOAT(OFS_PARM0); + PRVM_G_FLOAT(OFS_RETURN) = fabs(v); } void PF_vtos (void) { char *s; s = PR_GetTempString(); - sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); - G_INT(OFS_RETURN) = PR_SetString(s); + sprintf (s, "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } void PF_etos (void) { char *s; s = PR_GetTempString(); - sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0)); - G_INT(OFS_RETURN) = PR_SetString(s); + sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } void PF_Spawn (void) { - edict_t *ed; + prvm_edict_t *ed; pr_xfunction->builtinsprofile += 20; ed = ED_Alloc(); RETURN_EDICT(ed); @@ -1146,16 +1147,16 @@ void PF_Spawn (void) void PF_Remove (void) { - edict_t *ed; + prvm_edict_t *ed; pr_xfunction->builtinsprofile += 20; - ed = G_EDICT(OFS_PARM0); - if (ed == sv.edicts) + ed = PRVM_G_EDICT(OFS_PARM0); + if (ed == prog->edicts) PF_WARNING("remove: tried to remove world\n"); - if (NUM_FOR_EDICT(ed) <= svs.maxclients) + if (PRVM_NUM_FOR_EDICT(ed) <= svs.maxclients) PF_WARNING("remove: tried to remove a client\n"); // LordHavoc: not an error because id1 progs did this in some cases (killtarget removes entities, even if they are already removed in some cases...) - if (ed->e->free && developer.integer) + if (ed->priv.server->free && developer.integer) PF_WARNING("remove: tried to remove an entity that was already removed\n"); ED_Free (ed); } @@ -1166,23 +1167,23 @@ void PF_Find (void) { int e; int f; - char *s, *t; - edict_t *ed; + const char *s, *t; + prvm_edict_t *ed; - e = G_EDICTNUM(OFS_PARM0); - f = G_INT(OFS_PARM1); - s = G_STRING(OFS_PARM2); + e = PRVM_G_EDICTNUM(OFS_PARM0); + f = PRVM_G_INT(OFS_PARM1); + s = PRVM_G_STRING(OFS_PARM2); if (!s || !s[0]) { - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); return; } - for (e++ ; e < sv.num_edicts ; e++) + for (e++ ; e < prog->num_edicts ; e++) { pr_xfunction->builtinsprofile++; - ed = EDICT_NUM(e); - if (ed->e->free) + ed = PRVM_EDICT_NUM(e); + if (ed->priv.server->free) continue; t = E_STRING(ed,f); if (!t) @@ -1194,7 +1195,7 @@ void PF_Find (void) } } - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); } // LordHavoc: added this for searching float, int, and entity reference fields @@ -1203,17 +1204,17 @@ void PF_FindFloat (void) int e; int f; float s; - edict_t *ed; + prvm_edict_t *ed; - e = G_EDICTNUM(OFS_PARM0); - f = G_INT(OFS_PARM1); - s = G_FLOAT(OFS_PARM2); + e = PRVM_G_EDICTNUM(OFS_PARM0); + f = PRVM_G_INT(OFS_PARM1); + s = PRVM_G_FLOAT(OFS_PARM2); - for (e++ ; e < sv.num_edicts ; e++) + for (e++ ; e < prog->num_edicts ; e++) { pr_xfunction->builtinsprofile++; - ed = EDICT_NUM(e); - if (ed->e->free) + ed = PRVM_EDICT_NUM(e); + if (ed->priv.server->free) continue; if (E_FLOAT(ed,f) == s) { @@ -1222,7 +1223,7 @@ void PF_FindFloat (void) } } - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); } // chained search for strings in entity fields @@ -1231,24 +1232,24 @@ void PF_findchain (void) { int i; int f; - char *s, *t; - edict_t *ent, *chain; + const char *s, *t; + prvm_edict_t *ent, *chain; - chain = (edict_t *)sv.edicts; + chain = (prvm_edict_t *)prog->edicts; - f = G_INT(OFS_PARM0); - s = G_STRING(OFS_PARM1); + f = PRVM_G_INT(OFS_PARM0); + s = PRVM_G_STRING(OFS_PARM1); if (!s || !s[0]) { - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); return; } - ent = NEXT_EDICT(sv.edicts); - for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent)) + ent = PRVM_NEXT_EDICT(prog->edicts); + for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) { pr_xfunction->builtinsprofile++; - if (ent->e->free) + if (ent->priv.server->free) continue; t = E_STRING(ent,f); if (!t) @@ -1256,7 +1257,7 @@ void PF_findchain (void) if (strcmp(t,s)) continue; - ent->v->chain = EDICT_TO_PROG(chain); + ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain); chain = ent; } @@ -1270,23 +1271,23 @@ void PF_findchainfloat (void) int i; int f; float s; - edict_t *ent, *chain; + prvm_edict_t *ent, *chain; - chain = (edict_t *)sv.edicts; + chain = (prvm_edict_t *)prog->edicts; - f = G_INT(OFS_PARM0); - s = G_FLOAT(OFS_PARM1); + f = PRVM_G_INT(OFS_PARM0); + s = PRVM_G_FLOAT(OFS_PARM1); - ent = NEXT_EDICT(sv.edicts); - for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent)) + ent = PRVM_NEXT_EDICT(prog->edicts); + for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) { pr_xfunction->builtinsprofile++; - if (ent->e->free) + if (ent->priv.server->free) continue; if (E_FLOAT(ent,f) != s) continue; - ent->v->chain = EDICT_TO_PROG(chain); + ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain); chain = ent; } @@ -1299,17 +1300,17 @@ void PF_findflags (void) int e; int f; int s; - edict_t *ed; + prvm_edict_t *ed; - e = G_EDICTNUM(OFS_PARM0); - f = G_INT(OFS_PARM1); - s = (int)G_FLOAT(OFS_PARM2); + e = PRVM_G_EDICTNUM(OFS_PARM0); + f = PRVM_G_INT(OFS_PARM1); + s = (int)PRVM_G_FLOAT(OFS_PARM2); - for (e++ ; e < sv.num_edicts ; e++) + for (e++ ; e < prog->num_edicts ; e++) { pr_xfunction->builtinsprofile++; - ed = EDICT_NUM(e); - if (ed->e->free) + ed = PRVM_EDICT_NUM(e); + if (ed->priv.server->free) continue; if ((int)E_FLOAT(ed,f) & s) { @@ -1318,7 +1319,7 @@ void PF_findflags (void) } } - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); } // LordHavoc: chained search for flags in float fields @@ -1327,93 +1328,45 @@ void PF_findchainflags (void) int i; int f; int s; - edict_t *ent, *chain; + prvm_edict_t *ent, *chain; - chain = (edict_t *)sv.edicts; + chain = (prvm_edict_t *)prog->edicts; - f = G_INT(OFS_PARM0); - s = (int)G_FLOAT(OFS_PARM1); + f = PRVM_G_INT(OFS_PARM0); + s = (int)PRVM_G_FLOAT(OFS_PARM1); - ent = NEXT_EDICT(sv.edicts); - for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent)) + ent = PRVM_NEXT_EDICT(prog->edicts); + for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) { pr_xfunction->builtinsprofile++; - if (ent->e->free) + if (ent->priv.server->free) continue; if (!((int)E_FLOAT(ent,f) & s)) continue; - ent->v->chain = EDICT_TO_PROG(chain); + ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain); chain = ent; } RETURN_EDICT(chain); } -void PR_CheckEmptyString (char *s) -{ - if (s[0] <= ' ') - PF_ERROR("Bad string"); -} - void PF_precache_file (void) { // precache_file is only used to copy files with qcc, it does nothing - G_INT(OFS_RETURN) = G_INT(OFS_PARM0); + PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); } + void PF_precache_sound (void) { - char *s; - int i; - int limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_SOUNDS); - - if (sv.state != ss_loading) - PF_ERROR("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 ; ibrush.ishlbsp && ((!s) || (!s[0]))) - return; - G_INT(OFS_RETURN) = G_INT(OFS_PARM0); - PR_CheckEmptyString (s); - - for (i = 0;i < limit;i++) - { - if (!sv.model_precache[i]) - { - sv.model_precache[i] = s; - sv.models[i] = Mod_ForName (s, true, false, false); - return; - } - if (!strcmp(sv.model_precache[i], s)) - return; - } - PF_ERROR("PF_precache_model: overflow"); + SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2); + PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); } @@ -1434,7 +1387,7 @@ void PF_traceoff (void) void PF_eprint (void) { - ED_PrintNum (G_EDICTNUM(OFS_PARM0)); + ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0)); } /* @@ -1446,24 +1399,24 @@ float(float yaw, float dist) walkmove */ void PF_walkmove (void) { - edict_t *ent; + prvm_edict_t *ent; float yaw, dist; vec3_t move; mfunction_t *oldf; int oldself; // assume failure if it returns early - G_FLOAT(OFS_RETURN) = 0; - - ent = PROG_TO_EDICT(pr_global_struct->self); - if (ent == sv.edicts) + PRVM_G_FLOAT(OFS_RETURN) = 0; + + ent = PRVM_PROG_TO_EDICT(prog->globals.server->self); + if (ent == prog->edicts) PF_WARNING("walkmove: can not modify world entity\n"); - if (ent->e->free) + if (ent->priv.server->free) PF_WARNING("walkmove: can not modify free entity\n"); - yaw = G_FLOAT(OFS_PARM0); - dist = G_FLOAT(OFS_PARM1); + yaw = PRVM_G_FLOAT(OFS_PARM0); + dist = PRVM_G_FLOAT(OFS_PARM1); - if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) + if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) return; yaw = yaw*M_PI*2 / 360; @@ -1474,14 +1427,14 @@ void PF_walkmove (void) // save program state, because SV_movestep may call other progs oldf = pr_xfunction; - oldself = pr_global_struct->self; + oldself = prog->globals.server->self; - G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true); + PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true); // restore program state pr_xfunction = oldf; - pr_global_struct->self = oldself; + prog->globals.server->self = oldself; } /* @@ -1493,33 +1446,33 @@ void() droptofloor */ void PF_droptofloor (void) { - edict_t *ent; + prvm_edict_t *ent; vec3_t end; trace_t trace; // assume failure if it returns early - G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; - ent = PROG_TO_EDICT(pr_global_struct->self); - if (ent == sv.edicts) + ent = PRVM_PROG_TO_EDICT(prog->globals.server->self); + if (ent == prog->edicts) PF_WARNING("droptofloor: can not modify world entity\n"); - if (ent->e->free) + if (ent->priv.server->free) PF_WARNING("droptofloor: can not modify free entity\n"); - VectorCopy (ent->v->origin, end); + VectorCopy (ent->fields.server->origin, end); end[2] -= 256; - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent); if (trace.fraction != 1) { - VectorCopy (trace.endpos, ent->v->origin); + VectorCopy (trace.endpos, ent->fields.server->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; + ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; + ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); + PRVM_G_FLOAT(OFS_RETURN) = 1; // if support is destroyed, keep suspended (gross hack for floating items in various maps) - ent->e->suspendedinairflag = true; + ent->priv.server->suspendedinairflag = true; } } @@ -1533,15 +1486,15 @@ void(float style, string value) lightstyle void PF_lightstyle (void) { int style; - char *val; + const char *val; client_t *client; int j; - style = G_FLOAT(OFS_PARM0); - val = G_STRING(OFS_PARM1); + style = PRVM_G_FLOAT(OFS_PARM0); + val = PRVM_G_STRING(OFS_PARM1); // change the string in sv - sv.lightstyles[style] = val; + strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style])); // send message to all clients on this server if (sv.state != ss_active) @@ -1549,7 +1502,7 @@ void PF_lightstyle (void) for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++) { - if (client->netconnection) + if (client->active) { MSG_WriteChar (&client->message, svc_lightstyle); MSG_WriteChar (&client->message,style); @@ -1561,19 +1514,19 @@ void PF_lightstyle (void) void PF_rint (void) { float f; - f = G_FLOAT(OFS_PARM0); + f = PRVM_G_FLOAT(OFS_PARM0); if (f > 0) - G_FLOAT(OFS_RETURN) = (int)(f + 0.5); + PRVM_G_FLOAT(OFS_RETURN) = (int)(f + 0.5); else - G_FLOAT(OFS_RETURN) = (int)(f - 0.5); + PRVM_G_FLOAT(OFS_RETURN) = (int)(f - 0.5); } void PF_floor (void) { - G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = floor(PRVM_G_FLOAT(OFS_PARM0)); } void PF_ceil (void) { - G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = ceil(PRVM_G_FLOAT(OFS_PARM0)); } @@ -1584,7 +1537,7 @@ PF_checkbottom */ void PF_checkbottom (void) { - G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0)); } /* @@ -1594,7 +1547,7 @@ PF_pointcontents */ void PF_pointcontents (void) { - G_FLOAT(OFS_RETURN) = SV_PointQ1Contents(G_VECTOR(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = SV_PointQ1Contents(PRVM_G_VECTOR(OFS_PARM0)); } /* @@ -1607,20 +1560,20 @@ entity nextent(entity) void PF_nextent (void) { int i; - edict_t *ent; + prvm_edict_t *ent; - i = G_EDICTNUM(OFS_PARM0); + i = PRVM_G_EDICTNUM(OFS_PARM0); while (1) { pr_xfunction->builtinsprofile++; i++; - if (i == sv.num_edicts) + if (i == prog->num_edicts) { - RETURN_EDICT(sv.edicts); + RETURN_EDICT(prog->edicts); return; } - ent = EDICT_NUM(i); - if (!ent->e->free) + ent = PRVM_EDICT_NUM(i); + if (!ent->priv.server->free) { RETURN_EDICT(ent); return; @@ -1638,7 +1591,7 @@ vector aim(entity, missilespeed) */ void PF_aim (void) { - edict_t *ent, *check, *bestent; + prvm_edict_t *ent, *check, *bestent; vec3_t start, dir, end, bestdir; int i, j; trace_t tr; @@ -1646,29 +1599,29 @@ void PF_aim (void) float speed; // assume failure if it returns early - VectorCopy(pr_global_struct->v_forward, G_VECTOR(OFS_RETURN)); + VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN)); // if sv_aim is so high it can't possibly accept anything, skip out early if (sv_aim.value >= 1) return; - ent = G_EDICT(OFS_PARM0); - if (ent == sv.edicts) + ent = PRVM_G_EDICT(OFS_PARM0); + if (ent == prog->edicts) PF_WARNING("aim: can not use world entity\n"); - if (ent->e->free) + if (ent->priv.server->free) PF_WARNING("aim: can not use free entity\n"); - speed = G_FLOAT(OFS_PARM1); + speed = PRVM_G_FLOAT(OFS_PARM1); - VectorCopy (ent->v->origin, start); + VectorCopy (ent->fields.server->origin, start); start[2] += 20; // try sending a trace straight - VectorCopy (pr_global_struct->v_forward, dir); + VectorCopy (prog->globals.server->v_forward, dir); VectorMA (start, 2048, dir, end); tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent); - if (tr.ent && ((edict_t *)tr.ent)->v->takedamage == DAMAGE_AIM - && (!teamplay.integer || ent->v->team <=0 || ent->v->team != ((edict_t *)tr.ent)->v->team) ) + if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM + && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) ) { - VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN)); + VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN)); return; } @@ -1678,22 +1631,22 @@ void PF_aim (void) bestdist = sv_aim.value; bestent = NULL; - check = NEXT_EDICT(sv.edicts); - for (i=1 ; iedicts); + for (i=1 ; inum_edicts ; i++, check = PRVM_NEXT_EDICT(check) ) { pr_xfunction->builtinsprofile++; - if (check->v->takedamage != DAMAGE_AIM) + if (check->fields.server->takedamage != DAMAGE_AIM) continue; if (check == ent) continue; - if (teamplay.integer && ent->v->team > 0 && ent->v->team == check->v->team) + if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->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]); + end[j] = check->fields.server->origin[j] + + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]); VectorSubtract (end, start, dir); VectorNormalize (dir); - dist = DotProduct (dir, pr_global_struct->v_forward); + dist = DotProduct (dir, prog->globals.server->v_forward); if (dist < bestdist) continue; // to far to turn tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent); @@ -1706,16 +1659,16 @@ void PF_aim (void) 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); + VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir); + dist = DotProduct (dir, prog->globals.server->v_forward); + VectorScale (prog->globals.server->v_forward, dist, end); end[2] = dir[2]; VectorNormalize (end); - VectorCopy (end, G_VECTOR(OFS_RETURN)); + VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN)); } else { - VectorCopy (bestdir, G_VECTOR(OFS_RETURN)); + VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN)); } } @@ -1728,17 +1681,17 @@ This was a major timewaster in progs, so it was converted to C */ void PF_changeyaw (void) { - edict_t *ent; + prvm_edict_t *ent; float ideal, current, move, speed; - ent = PROG_TO_EDICT(pr_global_struct->self); - if (ent == sv.edicts) + ent = PRVM_PROG_TO_EDICT(prog->globals.server->self); + if (ent == prog->edicts) PF_WARNING("changeyaw: can not modify world entity\n"); - if (ent->e->free) + if (ent->priv.server->free) PF_WARNING("changeyaw: can not modify free entity\n"); - current = ANGLEMOD(ent->v->angles[1]); - ideal = ent->v->ideal_yaw; - speed = ent->v->yaw_speed; + current = ANGLEMOD(ent->fields.server->angles[1]); + ideal = ent->fields.server->ideal_yaw; + speed = ent->fields.server->yaw_speed; if (current == ideal) return; @@ -1764,7 +1717,7 @@ void PF_changeyaw (void) move = -speed; } - ent->v->angles[1] = ANGLEMOD (current + move); + ent->fields.server->angles[1] = ANGLEMOD (current + move); } /* @@ -1774,24 +1727,24 @@ PF_changepitch */ void PF_changepitch (void) { - edict_t *ent; + prvm_edict_t *ent; float ideal, current, move, speed; - eval_t *val; + prvm_eval_t *val; - ent = G_EDICT(OFS_PARM0); - if (ent == sv.edicts) + ent = PRVM_G_EDICT(OFS_PARM0); + if (ent == prog->edicts) PF_WARNING("changepitch: can not modify world entity\n"); - if (ent->e->free) + if (ent->priv.server->free) PF_WARNING("changepitch: can not modify free entity\n"); - current = ANGLEMOD( ent->v->angles[0] ); - if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch))) + current = ANGLEMOD( ent->fields.server->angles[0] ); + if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_idealpitch))) ideal = val->_float; else { PF_WARNING("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n"); return; } - if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed))) + if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_pitch_speed))) speed = val->_float; else { @@ -1823,7 +1776,7 @@ void PF_changepitch (void) move = -speed; } - ent->v->angles[0] = ANGLEMOD (current + move); + ent->fields.server->angles[0] = ANGLEMOD (current + move); } /* @@ -1843,17 +1796,17 @@ sizebuf_t *WriteDest (void) { int entnum; int dest; - edict_t *ent; + prvm_edict_t *ent; - dest = G_FLOAT(OFS_PARM0); + dest = PRVM_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); + ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity); + entnum = PRVM_NUM_FOR_EDICT(ent); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) Host_Error("WriteDest: tried to write to non-client\n"); return &svs.clients[entnum-1].message; @@ -1874,81 +1827,81 @@ sizebuf_t *WriteDest (void) void PF_WriteByte (void) { - MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1)); + MSG_WriteByte (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteChar (void) { - MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1)); + MSG_WriteChar (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteShort (void) { - MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1)); + MSG_WriteShort (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteLong (void) { - MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1)); + MSG_WriteLong (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteAngle (void) { - MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocol); + MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol); } void PF_WriteCoord (void) { - MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocol); + MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol); } void PF_WriteString (void) { - MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1)); + MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1)); } void PF_WriteEntity (void) { - MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1)); + MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1)); } //============================================================================= void PF_makestatic (void) { - edict_t *ent; + prvm_edict_t *ent; int i, large; - ent = G_EDICT(OFS_PARM0); - if (ent == sv.edicts) + ent = PRVM_G_EDICT(OFS_PARM0); + if (ent == prog->edicts) PF_WARNING("makestatic: can not modify world entity\n"); - if (ent->e->free) + if (ent->priv.server->free) PF_WARNING("makestatic: can not modify free entity\n"); large = false; - if (ent->v->modelindex >= 256 || ent->v->frame >= 256) + if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256) large = true; if (large) { MSG_WriteByte (&sv.signon,svc_spawnstatic2); - MSG_WriteShort (&sv.signon, ent->v->modelindex); - MSG_WriteShort (&sv.signon, ent->v->frame); + MSG_WriteShort (&sv.signon, ent->fields.server->modelindex); + MSG_WriteShort (&sv.signon, ent->fields.server->frame); } else { MSG_WriteByte (&sv.signon,svc_spawnstatic); - MSG_WriteByte (&sv.signon, ent->v->modelindex); - MSG_WriteByte (&sv.signon, ent->v->frame); + MSG_WriteByte (&sv.signon, ent->fields.server->modelindex); + MSG_WriteByte (&sv.signon, ent->fields.server->frame); } - MSG_WriteByte (&sv.signon, ent->v->colormap); - MSG_WriteByte (&sv.signon, ent->v->skin); + MSG_WriteByte (&sv.signon, ent->fields.server->colormap); + MSG_WriteByte (&sv.signon, ent->fields.server->skin); for (i=0 ; i<3 ; i++) { - MSG_WriteCoord(&sv.signon, ent->v->origin[i], sv.protocol); - MSG_WriteAngle(&sv.signon, ent->v->angles[i], sv.protocol); + MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol); + MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol); } // throw the entity away now @@ -1964,12 +1917,12 @@ PF_setspawnparms */ void PF_setspawnparms (void) { - edict_t *ent; + prvm_edict_t *ent; int i; client_t *client; - ent = G_EDICT(OFS_PARM0); - i = NUM_FOR_EDICT(ent); + ent = PRVM_G_EDICT(OFS_PARM0); + i = PRVM_NUM_FOR_EDICT(ent); if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active) { Con_Print("tried to setspawnparms on a non-client\n"); @@ -1979,7 +1932,7 @@ void PF_setspawnparms (void) // copy spawn parms out of the client_t client = svs.clients + i-1; for (i=0 ; i< NUM_SPAWN_PARMS ; i++) - (&pr_global_struct->parm1)[i] = client->spawn_parms[i]; + (&prog->globals.server->parm1)[i] = client->spawn_parms[i]; } /* @@ -1989,30 +1942,30 @@ PF_changelevel */ void PF_changelevel (void) { - char *s; + const char *s; // make sure we don't issue two changelevels if (svs.changelevel_issued) return; svs.changelevel_issued = true; - s = G_STRING(OFS_PARM0); + s = PRVM_G_STRING(OFS_PARM0); Cbuf_AddText (va("changelevel %s\n",s)); } void PF_sin (void) { - G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = sin(PRVM_G_FLOAT(OFS_PARM0)); } void PF_cos (void) { - G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = cos(PRVM_G_FLOAT(OFS_PARM0)); } void PF_sqrt (void) { - G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = sqrt(PRVM_G_FLOAT(OFS_PARM0)); } /* @@ -2034,7 +1987,7 @@ void PF_randomvec (void) temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0; } while (DotProduct(temp, temp) >= 1); - VectorCopy (temp, G_VECTOR(OFS_RETURN)); + VectorCopy (temp, PRVM_G_VECTOR(OFS_RETURN)); } /* @@ -2053,21 +2006,21 @@ void PF_GetLight (void) { vec3_t ambientcolor, diffusecolor, diffusenormal; vec_t *p; - p = G_VECTOR(OFS_PARM0); + p = PRVM_G_VECTOR(OFS_PARM0); VectorClear(ambientcolor); VectorClear(diffusecolor); VectorClear(diffusenormal); if (sv.worldmodel && sv.worldmodel->brush.LightPoint) sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal); - VectorMA(ambientcolor, 0.5, diffusecolor, G_VECTOR(OFS_RETURN)); + VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN)); } void PF_registercvar (void) { - char *name, *value; - name = G_STRING(OFS_PARM0); - value = G_STRING(OFS_PARM1); - G_FLOAT(OFS_RETURN) = 0; + const char *name, *value; + name = PRVM_G_STRING(OFS_PARM0); + value = PRVM_G_STRING(OFS_PARM1); + PRVM_G_FLOAT(OFS_RETURN) = 0; // first check to see if it has already been defined if (Cvar_FindVar (name)) @@ -2082,7 +2035,7 @@ void PF_registercvar (void) Cvar_Get(name, value, 0); - G_FLOAT(OFS_RETURN) = 1; // success + PRVM_G_FLOAT(OFS_RETURN) = 1; // success } /* @@ -2098,19 +2051,19 @@ void PF_min (void) { // LordHavoc: 3+ argument enhancement suggested by FrikaC if (pr_argc == 2) - G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); + PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); else if (pr_argc >= 3) { int i; - float f = G_FLOAT(OFS_PARM0); + float f = PRVM_G_FLOAT(OFS_PARM0); for (i = 1;i < pr_argc;i++) - if (G_FLOAT((OFS_PARM0+i*3)) < f) - f = G_FLOAT((OFS_PARM0+i*3)); - G_FLOAT(OFS_RETURN) = f; + if (PRVM_G_FLOAT((OFS_PARM0+i*3)) < f) + f = PRVM_G_FLOAT((OFS_PARM0+i*3)); + PRVM_G_FLOAT(OFS_RETURN) = f; } else { - G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; PF_WARNING("min: must supply at least 2 floats\n"); } } @@ -2128,19 +2081,19 @@ void PF_max (void) { // LordHavoc: 3+ argument enhancement suggested by FrikaC if (pr_argc == 2) - G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); + PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); else if (pr_argc >= 3) { int i; - float f = G_FLOAT(OFS_PARM0); + float f = PRVM_G_FLOAT(OFS_PARM0); for (i = 1;i < pr_argc;i++) - if (G_FLOAT((OFS_PARM0+i*3)) > f) - f = G_FLOAT((OFS_PARM0+i*3)); - G_FLOAT(OFS_RETURN) = f; + if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f) + f = PRVM_G_FLOAT((OFS_PARM0+i*3)); + PRVM_G_FLOAT(OFS_RETURN) = f; } else { - G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; PF_WARNING("max: must supply at least 2 floats\n"); } } @@ -2156,7 +2109,7 @@ min(min, value, max) */ void PF_bound (void) { - G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2)); + PRVM_G_FLOAT(OFS_RETURN) = bound(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1), PRVM_G_FLOAT(OFS_PARM2)); } /* @@ -2170,7 +2123,7 @@ pow(a, b) */ void PF_pow (void) { - G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); + PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); } /* @@ -2184,16 +2137,16 @@ copyentity(src, dst) */ void PF_copyentity (void) { - edict_t *in, *out; - in = G_EDICT(OFS_PARM0); - if (in == sv.edicts) + prvm_edict_t *in, *out; + in = PRVM_G_EDICT(OFS_PARM0); + if (in == prog->edicts) PF_WARNING("copyentity: can not read world entity\n"); - if (in->e->free) + if (in->priv.server->free) PF_WARNING("copyentity: can not read free entity\n"); - out = G_EDICT(OFS_PARM1); - if (out == sv.edicts) + out = PRVM_G_EDICT(OFS_PARM1); + if (out == prog->edicts) PF_WARNING("copyentity: can not modify world entity\n"); - if (out->e->free) + if (out->priv.server->free) PF_WARNING("copyentity: can not modify free entity\n"); memcpy(out->v, in->v, progs->entityfields * 4); } @@ -2211,10 +2164,10 @@ void PF_setcolor (void) { client_t *client; int entnum, i; - eval_t *val; + prvm_eval_t *val; - entnum = G_EDICTNUM(OFS_PARM0); - i = G_FLOAT(OFS_PARM1); + entnum = PRVM_G_EDICTNUM(OFS_PARM0); + i = PRVM_G_FLOAT(OFS_PARM1); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) { @@ -2225,9 +2178,9 @@ void PF_setcolor (void) client = svs.clients + entnum-1; if (client->edict) { - if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors))) + if ((val = PRVM_GETEDICTFIELDVALUE(client->edict, eval_clientcolors))) val->_float = i; - client->edict->v->team = (i & 15) + 1; + client->edict->fields.server->team = (i & 15) + 1; } client->colors = i; if (client->old_colors != client->colors) @@ -2250,53 +2203,53 @@ effect(origin, modelname, startframe, framecount, framerate) void PF_effect (void) { int i; - char *s; - s = G_STRING(OFS_PARM1); + const char *s; + s = PRVM_G_STRING(OFS_PARM1); if (!s || !s[0]) PF_WARNING("effect: no model specified\n"); - i = SV_ModelIndex(s); - if (i < 0) + i = SV_ModelIndex(s, 1); + if (!i) PF_WARNING("effect: model not precached\n"); - SV_StartEffect(G_VECTOR(OFS_PARM0), i, G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4)); + SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4)); } void PF_te_blood (void) { - if (G_FLOAT(OFS_PARM2) < 1) + if (PRVM_G_FLOAT(OFS_PARM2) < 1) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_BLOOD); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // velocity - MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127)); - MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127)); - MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127)); + MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127)); + MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127)); + MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127)); // count - MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255)); + MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255)); } void PF_te_bloodshower (void) { - if (G_FLOAT(OFS_PARM3) < 1) + if (PRVM_G_FLOAT(OFS_PARM3) < 1) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER); // min - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // max - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // speed - MSG_WriteCoord(&sv.datagram, G_FLOAT(OFS_PARM2), sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); } void PF_te_explosionrgb (void) @@ -2304,107 +2257,107 @@ void PF_te_explosionrgb (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // color - MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255)); - MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255)); - MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255)); + MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255)); + MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255)); + MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255)); } void PF_te_particlecube (void) { - if (G_FLOAT(OFS_PARM3) < 1) + if (PRVM_G_FLOAT(OFS_PARM3) < 1) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE); // min - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // max - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // velocity - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); // color - MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4)); + MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4)); // gravity true/false - MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0); + MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0); // randomvel - MSG_WriteCoord(&sv.datagram, G_FLOAT(OFS_PARM6), sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol); } void PF_te_particlerain (void) { - if (G_FLOAT(OFS_PARM3) < 1) + if (PRVM_G_FLOAT(OFS_PARM3) < 1) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN); // min - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // max - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // velocity - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); // color - MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4)); + MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4)); } void PF_te_particlesnow (void) { - if (G_FLOAT(OFS_PARM3) < 1) + if (PRVM_G_FLOAT(OFS_PARM3) < 1) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW); // min - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // max - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // velocity - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); // color - MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4)); + MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4)); } void PF_te_spark (void) { - if (G_FLOAT(OFS_PARM2) < 1) + if (PRVM_G_FLOAT(OFS_PARM2) < 1) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_SPARK); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // velocity - MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127)); - MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127)); - MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127)); + MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127)); + MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127)); + MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127)); // count - MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255)); + MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255)); } void PF_te_gunshotquad (void) @@ -2412,9 +2365,9 @@ void PF_te_gunshotquad (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_spikequad (void) @@ -2422,9 +2375,9 @@ void PF_te_spikequad (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_superspikequad (void) @@ -2432,9 +2385,9 @@ void PF_te_superspikequad (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_explosionquad (void) @@ -2442,9 +2395,9 @@ void PF_te_explosionquad (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_smallflash (void) @@ -2452,29 +2405,29 @@ void PF_te_smallflash (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_SMALLFLASH); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_customflash (void) { - if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0)) + if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0)) return; MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // radius - MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255)); + MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255)); // lifetime - MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255)); + MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255)); // color - MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255)); - MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255)); - MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255)); + MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255)); + MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255)); + MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255)); } void PF_te_gunshot (void) @@ -2482,9 +2435,9 @@ void PF_te_gunshot (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_GUNSHOT); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_spike (void) @@ -2492,9 +2445,9 @@ void PF_te_spike (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_SPIKE); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_superspike (void) @@ -2502,9 +2455,9 @@ void PF_te_superspike (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_explosion (void) @@ -2512,9 +2465,9 @@ void PF_te_explosion (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_EXPLOSION); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_tarexplosion (void) @@ -2522,9 +2475,9 @@ void PF_te_tarexplosion (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_wizspike (void) @@ -2532,9 +2485,9 @@ void PF_te_wizspike (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_WIZSPIKE); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_knightspike (void) @@ -2542,9 +2495,9 @@ void PF_te_knightspike (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_lavasplash (void) @@ -2552,9 +2505,9 @@ void PF_te_lavasplash (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_LAVASPLASH); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_teleport (void) @@ -2562,9 +2515,9 @@ void PF_te_teleport (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_TELEPORT); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } void PF_te_explosion2 (void) @@ -2572,12 +2525,12 @@ void PF_te_explosion2 (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_EXPLOSION2); // origin - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // color - MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1)); - MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM2)); + MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM1)); + MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2)); } void PF_te_lightning1 (void) @@ -2585,15 +2538,15 @@ void PF_te_lightning1 (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_LIGHTNING1); // owner entity - MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0)); + MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0)); // start - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // end - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); } void PF_te_lightning2 (void) @@ -2601,15 +2554,15 @@ void PF_te_lightning2 (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_LIGHTNING2); // owner entity - MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0)); + MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0)); // start - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // end - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); } void PF_te_lightning3 (void) @@ -2617,15 +2570,15 @@ void PF_te_lightning3 (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_LIGHTNING3); // owner entity - MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0)); + MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0)); // start - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // end - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); } void PF_te_beam (void) @@ -2633,183 +2586,204 @@ void PF_te_beam (void) MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_BEAM); // owner entity - MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0)); + MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0)); // start - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // end - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); } void PF_te_plasmaburn (void) { MSG_WriteByte(&sv.datagram, svc_temp_entity); MSG_WriteByte(&sv.datagram, TE_PLASMABURN); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol); - MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); + MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); } -static void clippointtosurface(msurface_t *surf, vec3_t p, vec3_t out) +static void clippointtosurface(msurface_t *surface, vec3_t p, vec3_t out) { - int i, j; - vec3_t v1, clipplanenormal, normal; - vec_t clipplanedist, clipdist; + int i, j, k; + float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist; + const int *e; + bestdist = 1000000000; VectorCopy(p, out); - if (surf->flags & SURF_PLANEBACK) - VectorNegate(surf->plane->normal, normal); - else - VectorCopy(surf->plane->normal, normal); - for (i = 0, j = surf->poly_numverts - 1;i < surf->poly_numverts;j = i, i++) - { - VectorSubtract(&surf->poly_verts[j * 3], &surf->poly_verts[i * 3], v1); - VectorNormalizeFast(v1); - CrossProduct(v1, normal, clipplanenormal); - clipplanedist = DotProduct(&surf->poly_verts[i * 3], clipplanenormal); - clipdist = DotProduct(out, clipplanenormal) - clipplanedist; - if (clipdist > 0) + for (i = 0, e = (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3) + { + // clip original point to each triangle of the surface and find the + // triangle that is closest + v[0] = surface->groupmesh->data_vertex3f + e[0] * 3; + v[1] = surface->groupmesh->data_vertex3f + e[1] * 3; + v[2] = surface->groupmesh->data_vertex3f + e[2] * 3; + TriangleNormal(v[0], v[1], v[2], facenormal); + VectorNormalize(facenormal); + offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal); + VectorMA(p, offsetdist, facenormal, temp); + for (j = 0, k = 2;j < 3;k = j, j++) + { + VectorSubtract(v[k], v[j], edgenormal); + CrossProduct(edgenormal, facenormal, sidenormal); + VectorNormalize(sidenormal); + offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal); + if (offsetdist < 0) + VectorMA(temp, offsetdist, sidenormal, temp); + } + dist = VectorDistance2(temp, p); + if (bestdist > dist) { - clipdist = -clipdist; - VectorMA(out, clipdist, clipplanenormal, out); + bestdist = dist; + VectorCopy(temp, out); } } } -static msurface_t *getsurface(edict_t *ed, int surfnum) +static msurface_t *getsurface(prvm_edict_t *ed, int surfacenum) { int modelindex; model_t *model; - if (!ed || ed->e->free) + if (!ed || ed->priv.server->free) return NULL; - modelindex = ed->v->modelindex; + modelindex = ed->fields.server->modelindex; if (modelindex < 1 || modelindex >= MAX_MODELS) return NULL; model = sv.models[modelindex]; - if (surfnum < 0 || surfnum >= model->nummodelsurfaces) + if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces) return NULL; - return model->brushq1.surfaces + surfnum + model->firstmodelsurface; + return model->data_surfaces + surfacenum + model->firstmodelsurface; } //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434; void PF_getsurfacenumpoints(void) { - msurface_t *surf; + msurface_t *surface; // return 0 if no such surface - if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1)))) + if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)))) { - G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } - G_FLOAT(OFS_RETURN) = surf->poly_numverts; + // note: this (incorrectly) assumes it is a simple polygon + PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices; } //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435; void PF_getsurfacepoint(void) { - edict_t *ed; - msurface_t *surf; + prvm_edict_t *ed; + msurface_t *surface; int pointnum; - VectorClear(G_VECTOR(OFS_RETURN)); - ed = G_EDICT(OFS_PARM0); - if (!ed || ed->e->free) + VectorClear(PRVM_G_VECTOR(OFS_RETURN)); + ed = PRVM_G_EDICT(OFS_PARM0); + if (!ed || ed->priv.server->free) return; - if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1)))) + if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1)))) return; - pointnum = G_FLOAT(OFS_PARM2); - if (pointnum < 0 || pointnum >= surf->poly_numverts) + // note: this (incorrectly) assumes it is a simple polygon + pointnum = PRVM_G_FLOAT(OFS_PARM2); + if (pointnum < 0 || pointnum >= surface->num_vertices) return; // FIXME: implement rotation/scaling - VectorAdd(&surf->poly_verts[pointnum * 3], ed->v->origin, G_VECTOR(OFS_RETURN)); + VectorAdd(&(surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN)); } //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436; void PF_getsurfacenormal(void) { - msurface_t *surf; - VectorClear(G_VECTOR(OFS_RETURN)); - if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1)))) + msurface_t *surface; + vec3_t normal; + VectorClear(PRVM_G_VECTOR(OFS_RETURN)); + if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)))) return; // FIXME: implement rotation/scaling - if (surf->flags & SURF_PLANEBACK) - VectorNegate(surf->plane->normal, G_VECTOR(OFS_RETURN)); - else - VectorCopy(surf->plane->normal, G_VECTOR(OFS_RETURN)); + // note: this (incorrectly) assumes it is a simple polygon + // note: this only returns the first triangle, so it doesn't work very + // well for curved surfaces or arbitrary meshes + TriangleNormal((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 3, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 6, normal); + VectorNormalize(normal); + VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN)); } //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437; void PF_getsurfacetexture(void) { - msurface_t *surf; - G_INT(OFS_RETURN) = 0; - if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1)))) + msurface_t *surface; + PRVM_G_INT(OFS_RETURN) = 0; + if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)))) return; - G_INT(OFS_RETURN) = PR_SetString(surf->texinfo->texture->name); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name); } //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438; void PF_getsurfacenearpoint(void) { - int surfnum, best, modelindex; + int surfacenum, best, modelindex; vec3_t clipped, p; vec_t dist, bestdist; - edict_t *ed; + prvm_edict_t *ed; model_t *model; - msurface_t *surf; + msurface_t *surface; vec_t *point; - G_FLOAT(OFS_RETURN) = -1; - ed = G_EDICT(OFS_PARM0); - point = G_VECTOR(OFS_PARM1); + PRVM_G_FLOAT(OFS_RETURN) = -1; + ed = PRVM_G_EDICT(OFS_PARM0); + point = PRVM_G_VECTOR(OFS_PARM1); - if (!ed || ed->e->free) + if (!ed || ed->priv.server->free) return; - modelindex = ed->v->modelindex; + modelindex = ed->fields.server->modelindex; if (modelindex < 1 || modelindex >= MAX_MODELS) return; model = sv.models[modelindex]; - if (!model->brushq1.numsurfaces) + if (!model->num_surfaces) return; // FIXME: implement rotation/scaling - VectorSubtract(point, ed->v->origin, p); + VectorSubtract(point, ed->fields.server->origin, p); best = -1; bestdist = 1000000000; - for (surfnum = 0;surfnum < model->nummodelsurfaces;surfnum++) - { - surf = model->brushq1.surfaces + surfnum + model->firstmodelsurface; - dist = PlaneDiff(p, surf->plane); - dist = dist * dist; + for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++) + { + surface = model->data_surfaces + surfacenum + model->firstmodelsurface; + // first see if the nearest point on the surface's box is closer than the previous match + clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0]; + clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1]; + clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2]; + dist = VectorLength2(clipped); if (dist < bestdist) { - clippointtosurface(surf, p, clipped); + // it is, check the nearest point on the actual geometry + clippointtosurface(surface, p, clipped); VectorSubtract(clipped, p, clipped); - dist += DotProduct(clipped, clipped); + dist += VectorLength2(clipped); if (dist < bestdist) { - best = surfnum; + // that's closer too, store it as the best match + best = surfacenum; bestdist = dist; } } } - G_FLOAT(OFS_RETURN) = best; + PRVM_G_FLOAT(OFS_RETURN) = best; } //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439; void PF_getsurfaceclippedpoint(void) { - edict_t *ed; - msurface_t *surf; + prvm_edict_t *ed; + msurface_t *surface; vec3_t p, out; - VectorClear(G_VECTOR(OFS_RETURN)); - ed = G_EDICT(OFS_PARM0); - if (!ed || ed->e->free) + VectorClear(PRVM_G_VECTOR(OFS_RETURN)); + ed = PRVM_G_EDICT(OFS_PARM0); + if (!ed || ed->priv.server->free) return; - if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1)))) + if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1)))) return; // FIXME: implement rotation/scaling - VectorSubtract(G_VECTOR(OFS_PARM2), ed->v->origin, p); - clippointtosurface(surf, p, out); + VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p); + clippointtosurface(surface, p, out); // FIXME: implement rotation/scaling - VectorAdd(out, ed->v->origin, G_VECTOR(OFS_RETURN)); + VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN)); } #define MAX_PRFILES 256 @@ -2837,24 +2811,24 @@ void PF_stof(void) { char string[STRINGTEMP_LENGTH]; PF_VarString(0, string, sizeof(string)); - G_FLOAT(OFS_RETURN) = atof(string); + PRVM_G_FLOAT(OFS_RETURN) = atof(string); } //float(string filename, float mode) fopen = #110; // opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE), returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason void PF_fopen(void) { - int filenum, mode, i; - char *modestring, *filename; + int filenum, mode; + const char *modestring, *filename; for (filenum = 0;filenum < MAX_PRFILES;filenum++) if (pr_files[filenum] == NULL) break; if (filenum >= MAX_PRFILES) { Con_Printf("PF_fopen: ran out of file handles (%i)\n", MAX_PRFILES); - G_FLOAT(OFS_RETURN) = -2; + PRVM_G_FLOAT(OFS_RETURN) = -2; return; } - mode = G_FLOAT(OFS_PARM1); + mode = PRVM_G_FLOAT(OFS_PARM1); switch(mode) { case 0: // FILE_READ @@ -2868,40 +2842,26 @@ void PF_fopen(void) break; default: Con_Printf("PF_fopen: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", mode); - G_FLOAT(OFS_RETURN) = -3; + PRVM_G_FLOAT(OFS_RETURN) = -3; return; } - filename = G_STRING(OFS_PARM0); - // control characters do not cause issues with any platforms I know of, but they are usually annoying to deal with - // ../ is parent directory on many platforms - // // is parent directory on Amiga - // / at the beginning of a path is root on unix, and parent directory on Amiga - // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea) - // \ is a windows-ism (so it's naughty to use it, / works on all platforms) - for (i = 0;filename[i];i++) - { - if (filename[i] < ' ' || (filename[i] == '/' && filename[i+1] == '/') || (filename[i] == '.' && filename[i+1] == '.') || filename[i] == ':' || filename[i] == '\\' || filename[0] == '/') - { - Con_Printf("PF_fopen: dangerous/confusing/annoying/non-portable filename \"%s\" not allowed. (contains control characters or // or .. or : or \\ or begins with /)\n", filename); - G_FLOAT(OFS_RETURN) = -4; - return; - } - } - pr_files[filenum] = FS_Open(va("data/%s", filename), modestring, false); + filename = PRVM_G_STRING(OFS_PARM0); + // -4 failure (dangerous/non-portable filename) removed, FS_Open checks + pr_files[filenum] = FS_Open(va("data/%s", filename), modestring, false, false); if (pr_files[filenum] == NULL && modestring == "rb") - pr_files[filenum] = FS_Open(filename, modestring, false); + pr_files[filenum] = FS_Open(filename, modestring, false, false); if (pr_files[filenum] == NULL) - G_FLOAT(OFS_RETURN) = -1; + PRVM_G_FLOAT(OFS_RETURN) = -1; else - G_FLOAT(OFS_RETURN) = filenum; + PRVM_G_FLOAT(OFS_RETURN) = filenum; } //void(float fhandle) fclose = #111; // closes a file void PF_fclose(void) { - int filenum = G_FLOAT(OFS_PARM0); + int filenum = PRVM_G_FLOAT(OFS_PARM0); if (filenum < 0 || filenum >= MAX_PRFILES) { Con_Printf("PF_fclose: invalid file handle %i\n", filenum); @@ -2921,7 +2881,7 @@ void PF_fgets(void) { int c, end; static char string[STRINGTEMP_LENGTH]; - int filenum = G_FLOAT(OFS_PARM0); + int filenum = PRVM_G_FLOAT(OFS_PARM0); if (filenum < 0 || filenum >= MAX_PRFILES) { Con_Printf("PF_fgets: invalid file handle %i\n", filenum); @@ -2944,13 +2904,17 @@ void PF_fgets(void) string[end] = 0; // remove \n following \r if (c == '\r') + { c = FS_Getc(pr_files[filenum]); + if (c != '\n') + FS_UnGetc(pr_files[filenum], (unsigned char)c); + } if (developer.integer) Con_Printf("fgets: %s\n", string); if (c >= 0 || end) - G_INT(OFS_RETURN) = PR_SetString(string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string); else - G_INT(OFS_RETURN) = 0; + PRVM_G_INT(OFS_RETURN) = 0; } //void(float fhandle, string s) fputs = #113; // writes a line of text to the end of the file @@ -2958,7 +2922,7 @@ void PF_fputs(void) { int stringlength; char string[STRINGTEMP_LENGTH]; - int filenum = G_FLOAT(OFS_PARM0); + int filenum = PRVM_G_FLOAT(OFS_PARM0); if (filenum < 0 || filenum >= MAX_PRFILES) { Con_Printf("PF_fputs: invalid file handle %i\n", filenum); @@ -2979,12 +2943,12 @@ void PF_fputs(void) //float(string s) strlen = #114; // returns how many characters are in a string void PF_strlen(void) { - char *s; - s = G_STRING(OFS_PARM0); + const char *s; + s = PRVM_G_STRING(OFS_PARM0); if (s) - G_FLOAT(OFS_RETURN) = strlen(s); + PRVM_G_FLOAT(OFS_RETURN) = strlen(s); else - G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; } //string(string s1, string s2) strcat = #115; // concatenates two strings (for example "abc", "def" would return "abcdef") and returns as a tempstring @@ -2992,24 +2956,25 @@ void PF_strcat(void) { char *s = PR_GetTempString(); PF_VarString(0, s, STRINGTEMP_LENGTH); - G_INT(OFS_RETURN) = PR_SetString(s); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } //string(string s, float start, float length) substring = #116; // returns a section of a string as a tempstring void PF_substring(void) { int i, start, length; - char *s, *string = PR_GetTempString(); - s = G_STRING(OFS_PARM0); - start = G_FLOAT(OFS_PARM1); - length = G_FLOAT(OFS_PARM2); + const char *s; + char *string = PR_GetTempString(); + s = PRVM_G_STRING(OFS_PARM0); + start = PRVM_G_FLOAT(OFS_PARM1); + length = PRVM_G_FLOAT(OFS_PARM2); if (!s) s = ""; for (i = 0;i < start && *s;i++, s++); for (i = 0;i < STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++) string[i] = *s; string[i] = 0; - G_INT(OFS_RETURN) = PR_SetString(string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string); } //vector(string s) stov = #117; // returns vector value from a string @@ -3017,23 +2982,24 @@ void PF_stov(void) { char string[STRINGTEMP_LENGTH]; PF_VarString(0, string, sizeof(string)); - Math_atov(string, G_VECTOR(OFS_RETURN)); + Math_atov(string, PRVM_G_VECTOR(OFS_RETURN)); } //string(string s) strzone = #118; // makes a copy of a string into the string zone and returns it, this is often used to keep around a tempstring for longer periods of time (tempstrings are replaced often) void PF_strzone(void) { - char *in, *out; - in = G_STRING(OFS_PARM0); - out = Mem_Alloc(pr_strings_mempool, strlen(in) + 1); + const char *in; + char *out; + in = PRVM_G_STRING(OFS_PARM0); + out = PR_AllocString(strlen(in) + 1); strcpy(out, in); - G_INT(OFS_RETURN) = PR_SetString(out); + PRVM_G_INT(OFS_RETURN) = PR_SetQCString(out); } //void(string s) strunzone = #119; // removes a copy of a string from the string zone (you can not use that string again or it may crash!!!) void PF_strunzone(void) { - Mem_Free(G_STRING(OFS_PARM0)); + PR_FreeString((char *)PRVM_G_STRING(OFS_PARM0)); } //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client @@ -3044,7 +3010,7 @@ void PF_clientcommand (void) int i; //find client for this entity - i = (NUM_FOR_EDICT(G_EDICT(OFS_PARM0)) - 1); + i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1); if (i < 0 || i >= svs.maxclients || !svs.clients[i].active) { Con_Print("PF_clientcommand: entity is not a client\n"); @@ -3053,7 +3019,7 @@ void PF_clientcommand (void) temp_client = host_client; host_client = svs.clients + i; - Cmd_ExecuteString (G_STRING(OFS_PARM1), src_client); + Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client); host_client = temp_client; } @@ -3066,7 +3032,7 @@ void PF_tokenize (void) { int pos; const char *p; - p = G_STRING(OFS_PARM0); + p = PRVM_G_STRING(OFS_PARM0); num_tokens = 0; pos = 0; @@ -3081,117 +3047,73 @@ void PF_tokenize (void) pos += strlen(com_token) + 1; } - G_FLOAT(OFS_RETURN) = num_tokens; + PRVM_G_FLOAT(OFS_RETURN) = num_tokens; } //string(float n) argv = #442; // returns a word from the tokenized string (returns nothing for an invalid index) //this function originally written by KrimZon, made shorter by LordHavoc void PF_argv (void) { - int token_num = G_FLOAT(OFS_PARM0); + int token_num = PRVM_G_FLOAT(OFS_PARM0); if (token_num >= 0 && token_num < num_tokens) - G_INT(OFS_RETURN) = PR_SetString(tokens[token_num]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tokens[token_num]); else - G_INT(OFS_RETURN) = PR_SetString(""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(NULL); } //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag) void PF_setattachment (void) { - edict_t *e = G_EDICT(OFS_PARM0); - edict_t *tagentity = G_EDICT(OFS_PARM1); - char *tagname = G_STRING(OFS_PARM2); - eval_t *v; - int i, modelindex; + prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0); + prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1); + const char *tagname = PRVM_G_STRING(OFS_PARM2); + prvm_eval_t *v; + int modelindex; model_t *model; - if (e == sv.edicts) + if (e == prog->edicts) PF_WARNING("setattachment: can not modify world entity\n"); - if (e->e->free) + if (e->priv.server->free) PF_WARNING("setattachment: can not modify free entity\n"); if (tagentity == NULL) - tagentity = sv.edicts; + tagentity = prog->edicts; - v = GETEDICTFIELDVALUE(e, eval_tag_entity); + v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_entity); if (v) - v->edict = EDICT_TO_PROG(tagentity); + fields.server->edict = PRVM_EDICT_TO_PROG(tagentity); - v = GETEDICTFIELDVALUE(e, eval_tag_index); + v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_index); if (v) - v->_float = 0; - if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0]) + fields.server->_float = 0; + if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0]) { - modelindex = (int)tagentity->v->modelindex; + modelindex = (int)tagentity->fields.server->modelindex; if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex])) { - if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames) - for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++) - if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name)) - v->_float = i + 1; - // FIXME: use a model function to get tag info (need to handle skeletal) - if (v->_float == 0 && model->alias.aliasnum_tags) - for (i = 0;i < model->alias.aliasnum_tags;i++) - if (!strcmp(tagname, model->alias.aliasdata_tags[i].name)) - v->_float = i + 1; - if (v->_float == 0) - Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name); + fields.server->_float = Mod_Alias_GetTagIndexForName(model, tagentity->fields.server->skin, tagname); + if (fields.server->_float == 0) + Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name); } else - Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity)); + Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity)); } } ///////////////////////////////////////// // DP_MD3_TAGINFO extension coded by VorteX -//float(entity ent, string tagname) gettagindex; -void PF_gettagindex (void) +int SV_GetTagIndex (prvm_edict_t *e, const char *tagname) { - edict_t *e = G_EDICT(OFS_PARM0); - const char *tagname = G_STRING(OFS_PARM1); - int modelindex, tagindex, i; + int i; model_t *model; - if (e == sv.edicts) - PF_WARNING("gettagindex: can't affect world entity\n"); - if (e->e->free) - PF_WARNING("gettagindex: can't affect free entity\n"); + i = e->fields.server->modelindex; + if (i < 1 || i >= MAX_MODELS) + return -1; + model = sv.models[i]; - modelindex = (int)e->v->modelindex; - if (modelindex <= 0 || modelindex > MAX_MODELS) - { - Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", NUM_FOR_EDICT(e)); - return; - } - model = sv.models[modelindex]; - - tagindex = -1; - if (model->data_overridetagnamesforskin && (unsigned int)e->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)e->v->skin].num_overridetagnames) - { - for (i = 0; i < model->data_overridetagnamesforskin[(unsigned int)e->v->skin].num_overridetagnames; i++) - { - if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)e->v->skin].data_overridetagnames[i].name)) - { - tagindex = i; - break; - } - } - } - if (tagindex == -1) - { - for (i = 0;i < model->alias.aliasnum_tags; i++) - { - if (!(strcmp(tagname, model->alias.aliasdata_tags[i].name))) - { - tagindex = i; - break; - } - } - } - if (tagindex == -1) - Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", NUM_FOR_EDICT(e), tagname); - G_FLOAT(OFS_RETURN) = tagindex + 1; + return Mod_Alias_GetTagIndexForName(model, e->fields.server->skin, tagname); }; // Warnings/errors code: @@ -3200,101 +3122,172 @@ void PF_gettagindex (void) // 2 - free entity // 3 - null or non-precached model // 4 - no tags with requested index -int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex) -{ - eval_t *val; - float scale; - int modelindex, tagsnum, reqframe; - matrix4x4_t entitymatrix, tagmatrix; +// 5 - runaway loop at attachment chain +extern cvar_t cl_bob; +extern cvar_t cl_bobcycle; +extern cvar_t cl_bobup; +int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) +{ + prvm_eval_t *val; + int modelindex, reqframe, attachloop; + matrix4x4_t entitymatrix, tagmatrix, attachmatrix; + prvm_edict_t *attachent; model_t *model; Matrix4x4_CreateIdentity(out); // warnings and errors return identical matrix - if (ent == sv.edicts) + if (ent == prog->edicts) return 1; - if (ent->e->free) + if (ent->priv.server->free) return 2; - modelindex = (int)ent->v->modelindex; + modelindex = (int)ent->fields.server->modelindex; if (modelindex <= 0 || modelindex > MAX_MODELS) return 3; model = sv.models[modelindex]; - tagsnum = model->alias.aliasnum_tags; - if (tagindex <= 0 || tagindex > tagsnum) + if (ent->fields.server->frame >= 0 && ent->fields.server->frame < model->numframes && model->animscenes) + reqframe = model->animscenes[(int)ent->fields.server->frame].firstframe; + else + reqframe = 0; // if model has wrong frame, engine automatically switches to model first frame + + // get initial tag matrix + if (tagindex) { - if (tagsnum && tagindex) // Only appear if model has no tags or not-null tag requested - return 4; - return 0; + int ret = Mod_Alias_GetTagMatrix(model, reqframe, tagindex - 1, &tagmatrix); + if (ret) + return ret; } - - if (ent->v->frame < 0 || ent->v->frame > model->alias.aliasnum_tagframes) - reqframe = 0; // if model has wrong frame, engine automatically switches to model first frame else - reqframe = ent->v->frame; + Matrix4x4_CreateIdentity(&tagmatrix); - // just reusing a temp - modelindex = (tagindex - 1) + ent->v->frame*tagsnum; + if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict) + { // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity + attachloop = 0; + do + { + attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached + val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index); + if (val->_float >= 1 && attachent->fields.server->modelindex >= 1 && attachent->fields.server->modelindex < MAX_MODELS && (model = sv.models[(int)attachent->fields.server->modelindex]) && model->animscenes && attachent->fields.server->frame >= 0 && attachent->fields.server->frame < model->numframes) + Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.server->frame].firstframe, val->_float - 1, &attachmatrix); + else + Matrix4x4_CreateIdentity(&attachmatrix); + + // apply transformation by child entity matrix + val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale); + if (val->_float == 0) + val->_float = 1; + Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], val->_float); + Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); + out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]); + out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]); + out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]); + Matrix4x4_Copy(&tagmatrix, out); + + // finally transformate by matrix of tag on parent entity + Matrix4x4_Concat(out, &attachmatrix, &tagmatrix); + out->m[0][3] = attachmatrix.m[0][3] + attachmatrix.m[0][0]*tagmatrix.m[0][3] + attachmatrix.m[0][1]*tagmatrix.m[1][3] + attachmatrix.m[0][2]*tagmatrix.m[2][3]; + out->m[1][3] = attachmatrix.m[1][3] + attachmatrix.m[1][0]*tagmatrix.m[0][3] + attachmatrix.m[1][1]*tagmatrix.m[1][3] + attachmatrix.m[1][2]*tagmatrix.m[2][3]; + out->m[2][3] = attachmatrix.m[2][3] + attachmatrix.m[2][0]*tagmatrix.m[0][3] + attachmatrix.m[2][1]*tagmatrix.m[1][3] + attachmatrix.m[2][2]*tagmatrix.m[2][3]; + Matrix4x4_Copy(&tagmatrix, out); + + ent = attachent; + attachloop += 1; + if (attachloop > 255) // prevent runaway looping + return 5; + } + while ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict); + } - // transform tag by its own entity matrix - Matrix4x4_Copy(&tagmatrix, &model->alias.aliasdata_tags[modelindex].matrix); - // FIXME: add scale parameter - scale = 1; + // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain) + val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale); + if (val->_float == 0) + val->_float = 1; // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype... - Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], -ent->v->angles[0], ent->v->angles[1], ent->v->angles[2], scale); + Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], val->_float); Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); - // True origin for rotation (Matrix4x4_Concat creates wrong), this is done using all rotation matrix - out->m[0][3] = entitymatrix.m[0][3] + entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]; - out->m[1][3] = entitymatrix.m[1][3] + entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]; - out->m[2][3] = entitymatrix.m[2][3] + entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]; - - // additional actions for render-view entities - if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict) - {// RENDER_VIEWMODEL + out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]); + out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]); + out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]); + + if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict) + {// RENDER_VIEWMODEL magic Matrix4x4_Copy(&tagmatrix, out); - ent = EDICT_NUM(val->edict); - // FIXME: add bobbing (cl_bob), add scale parameter - scale = 1; - Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2] + ent->v->view_ofs[2], ent->v->v_angle[0], ent->v->v_angle[1], ent->v->v_angle[2], scale); + ent = PRVM_EDICT_NUM(val->edict); + + val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale); + if (val->_float == 0) + val->_float = 1; + + Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], val->_float); Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); - out->m[0][3] = entitymatrix.m[0][3] + entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]; - out->m[1][3] = entitymatrix.m[1][3] + entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]; - out->m[2][3] = entitymatrix.m[2][3] + entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]; - Con_DPrintf("SV_GetTagMatrix: returned origin is %f %f %f\n", out->m[0][3], out->m[1][3], out->m[2][3]); - return 0; - } - // RENDER_VIEWMODEL can't be attached by tag, right? - val = GETEDICTFIELDVALUE(ent, eval_tag_entity); - if (val->edict) - {// DP_GFX_QUAKE3MODELTAGS - do + out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]); + out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]); + out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]); + + /* + // Cl_bob, ported from rendering code + if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value) { - ent = EDICT_NUM(val->edict); - // FIXME: add scale parameter - Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], -ent->v->angles[0], ent->v->angles[1], ent->v->angles[2], scale); - Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); - // True origin for rotation (Matrix4x4_Concat creates wrong), this is done using all rotation matrix - out->m[0][3] = entitymatrix.m[0][3] + entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]; - out->m[1][3] = entitymatrix.m[1][3] + entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]; - out->m[2][3] = entitymatrix.m[2][3] + entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]; - + double bob, cycle; + // LordHavoc: this code is *weird*, but not replacable (I think it + // should be done in QC on the server, but oh well, quake is quake) + // LordHavoc: figured out bobup: the time at which the sin is at 180 + // degrees (which allows lengthening or squishing the peak or valley) + cycle = sv.time/cl_bobcycle.value; + cycle -= (int)cycle; + if (cycle < cl_bobup.value) + cycle = sin(M_PI * cycle / cl_bobup.value); + else + cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value)); + // bob is proportional to velocity in the xy plane + // (don't count Z, or jumping messes it up) + bob = sqrt(ent->fields.server->velocity[0]*ent->fields.server->velocity[0] + ent->fields.server->velocity[1]*ent->fields.server->velocity[1])*cl_bob.value; + bob = bob*0.3 + bob*0.7*cycle; + out->m[2][3] += bound(-7, bob, 4); } - while ((val = GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict); + */ } return 0; } +//float(entity ent, string tagname) gettagindex; + +void PF_gettagindex (void) +{ + prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0); + const char *tag_name = PRVM_G_STRING(OFS_PARM1); + int modelindex, tag_index; + + if (ent == prog->edicts) + PF_WARNING("gettagindex: can't affect world entity\n"); + if (ent->priv.server->free) + PF_WARNING("gettagindex: can't affect free entity\n"); + + modelindex = (int)ent->fields.server->modelindex; + tag_index = 0; + if (modelindex <= 0 || modelindex > MAX_MODELS) + Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent)); + else + { + tag_index = SV_GetTagIndex(ent, tag_name); + if (tag_index == 0) + Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name); + } + PRVM_G_FLOAT(OFS_RETURN) = tag_index; +}; + //vector(entity ent, float tagindex) gettaginfo; void PF_gettaginfo (void) { - edict_t *e = G_EDICT(OFS_PARM0); - int tagindex = (int)G_FLOAT(OFS_PARM1); + prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0); + int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1); matrix4x4_t tag_matrix; int returncode; returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex); - Matrix4x4_ToVectors(&tag_matrix, pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up, G_VECTOR(OFS_RETURN)); + Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN)); switch(returncode) { @@ -3305,10 +3298,13 @@ void PF_gettaginfo (void) PF_WARNING("gettagindex: can't affect free entity\n"); break; case 3: - Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", NUM_FOR_EDICT(e)); + Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e)); break; case 4: - Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", NUM_FOR_EDICT(e), tagindex); + Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex); + break; + case 5: + Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e)); break; } } @@ -3347,16 +3343,16 @@ float search_begin(string pattern, float caseinsensitive, float quiet) void PF_search_begin(void) { int handle; - char *pattern; + const char *pattern; int caseinsens, quiet; - pattern = G_STRING(OFS_PARM0); + pattern = PRVM_G_STRING(OFS_PARM0); + if (!pattern || pattern[0] <= ' ') + PF_ERROR("PF_search_begin: Bad string"); - PR_CheckEmptyString(pattern); + caseinsens = PRVM_G_FLOAT(OFS_PARM1); + quiet = PRVM_G_FLOAT(OFS_PARM2); - caseinsens = G_FLOAT(OFS_PARM1); - quiet = G_FLOAT(OFS_PARM2); - for(handle = 0; handle < MAX_SEARCHES; handle++) if(!pr_fssearchlist[handle]) break; @@ -3364,14 +3360,14 @@ void PF_search_begin(void) if(handle >= MAX_SEARCHES) { Con_Printf("PR_search_begin: ran out of search handles (%i)\n", MAX_SEARCHES); - G_FLOAT(OFS_RETURN) = -2; + PRVM_G_FLOAT(OFS_RETURN) = -2; return; } if(!(pr_fssearchlist[handle] = FS_Search(pattern,caseinsens, quiet))) - G_FLOAT(OFS_RETURN) = -1; + PRVM_G_FLOAT(OFS_RETURN) = -1; else - G_FLOAT(OFS_RETURN) = handle; + PRVM_G_FLOAT(OFS_RETURN) = handle; } /* @@ -3385,8 +3381,8 @@ void PF_search_end(void) { int handle; - handle = G_FLOAT(OFS_PARM0); - + handle = PRVM_G_FLOAT(OFS_PARM0); + if(handle < 0 || handle >= MAX_SEARCHES) { Con_Printf("PF_search_end: invalid handle %i\n", handle); @@ -3413,7 +3409,7 @@ void PF_search_getsize(void) { int handle; - handle = G_FLOAT(OFS_PARM0); + handle = PRVM_G_FLOAT(OFS_PARM0); if(handle < 0 || handle >= MAX_SEARCHES) { @@ -3425,8 +3421,8 @@ void PF_search_getsize(void) Con_Printf("PF_search_getsize: no such handle %i\n", handle); return; } - - G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames; + + PRVM_G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames; } /* @@ -3441,8 +3437,8 @@ void PF_search_getfilename(void) int handle, filenum; char *tmp; - handle = G_FLOAT(OFS_PARM0); - filenum = G_FLOAT(OFS_PARM1); + handle = PRVM_G_FLOAT(OFS_PARM0); + filenum = PRVM_G_FLOAT(OFS_PARM1); if(handle < 0 || handle >= MAX_SEARCHES) { @@ -3459,20 +3455,20 @@ void PF_search_getfilename(void) Con_Printf("PF_search_getfilename: invalid filenum %i\n", filenum); return; } - + tmp = PR_GetTempString(); strcpy(tmp, pr_fssearchlist[handle]->filenames[filenum]); - G_INT(OFS_RETURN) = PR_SetString(tmp); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tmp); } void PF_cvar_string (void) { - char *str; + const char *str; cvar_t *var; char *tmp; - str = G_STRING(OFS_PARM0); + str = PRVM_G_STRING(OFS_PARM0); var = Cvar_FindVar (str); if (var) { @@ -3480,8 +3476,8 @@ void PF_cvar_string (void) strcpy(tmp, var->string); } else - tmp = ""; - G_INT(OFS_RETURN) = PR_SetString(tmp); + tmp = NULL; + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tmp); } //void(entity clent) dropclient (DP_SV_DROPCLIENT) @@ -3489,7 +3485,7 @@ void PF_dropclient (void) { int clientnum; client_t *oldhostclient; - clientnum = G_EDICTNUM(OFS_PARM0) - 1; + clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1; if (clientnum < 0 || clientnum >= svs.maxclients) PF_WARNING("dropclient: not a client\n"); if (!svs.clients[clientnum].active) @@ -3500,6 +3496,40 @@ void PF_dropclient (void) host_client = oldhostclient; } +//entity() spawnclient (DP_SV_BOTCLIENT) +void PF_spawnclient (void) +{ + int i; + prvm_edict_t *ed; + pr_xfunction->builtinsprofile += 2; + ed = prog->edicts; + for (i = 0;i < svs.maxclients;i++) + { + if (!svs.clients[i].active) + { + pr_xfunction->builtinsprofile += 100; + SV_ConnectClient (i, NULL); + ed = PRVM_EDICT_NUM(i + 1); + break; + } + } + RETURN_EDICT(ed); +} + +//float(entity clent) clienttype (DP_SV_BOTCLIENT) +void PF_clienttype (void) +{ + int clientnum; + clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1; + if (clientnum < 0 || clientnum >= svs.maxclients) + PRVM_G_FLOAT(OFS_RETURN) = 3; + else if (!svs.clients[clientnum].active) + PRVM_G_FLOAT(OFS_RETURN) = 0; + else if (svs.clients[clientnum].netconnection) + PRVM_G_FLOAT(OFS_RETURN) = 1; + else + PRVM_G_FLOAT(OFS_RETURN) = 2; +} builtin_t pr_builtin[] = { @@ -3544,7 +3574,7 @@ PF_floor, // #37 float(float v) floor PF_ceil, // #38 float(float v) ceil NULL, // #39 PF_checkbottom, // #40 float(entity e) checkbottom -PF_pointcontents , // #41 float(vector v) pointcontents +PF_pointcontents, // #41 float(vector v) pointcontents NULL, // #42 PF_fabs, // #43 float(float f) fabs PF_aim, // #44 vector(entity e, float speed) aim @@ -3681,8 +3711,8 @@ PF_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_ PF_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO) PF_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO) PF_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT) -NULL, // #454 -NULL, // #455 +PF_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT) +PF_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT) NULL, // #456 NULL, // #457 NULL, // #458 @@ -3695,14 +3725,16 @@ int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]); void PR_Cmd_Init(void) { - pr_strings_mempool = Mem_AllocPool("pr_stringszone", 0, NULL); PR_Files_Init(); PR_Search_Init(); } +void PR_Cmd_Shutdown(void) +{ +} + void PR_Cmd_Reset(void) { - Mem_EmptyPool(pr_strings_mempool); PR_Search_Reset(); PR_Files_CloseAll(); }