#include "quakedef.h"
#include "prvm_cmds.h"
+#include "jpeg.h"
//============================================================================
// Server
"DP_BUTTONUSE "
"DP_CL_LOADSKY "
"DP_CON_ALIASPARAMETERS "
+"DP_CON_BESTWEAPON "
"DP_CON_EXPANDCVAR "
"DP_CON_SET "
"DP_CON_SETA "
"DP_CON_STARTMAP "
+"DP_CSQC_MULTIFRAME_INTERPOLATION "
"DP_EF_ADDITIVE "
"DP_EF_BLUE "
"DP_EF_DOUBLESIDED "
"DP_EF_FULLBRIGHT "
"DP_EF_NODEPTHTEST "
"DP_EF_NODRAW "
-"DP_EF_NOSHADOW "
"DP_EF_NOGUNBOB "
+"DP_EF_NOSELFSHADOW "
+"DP_EF_NOSHADOW "
"DP_EF_RED "
"DP_EF_STARDUST "
+"DP_EF_TELEPORT_BIT "
"DP_ENT_ALPHA "
"DP_ENT_COLORMOD "
"DP_ENT_CUSTOMCOLORMAP "
"DP_ENT_EXTERIORMODELTOCLIENT "
"DP_ENT_GLOW "
+"DP_ENT_GLOWMOD "
"DP_ENT_LOWPRECISION "
"DP_ENT_SCALE "
"DP_ENT_VIEWMODEL "
+"DP_GECKO_SUPPORT "
"DP_GFX_EXTERNALTEXTURES "
"DP_GFX_EXTERNALTEXTURES_PERMAP "
"DP_GFX_FOG "
"DP_GFX_QUAKE3MODELTAGS "
"DP_GFX_SKINFILES "
"DP_GFX_SKYBOX "
+"DP_GFX_MODEL_INTERPOLATION "
"DP_HALFLIFE_MAP "
"DP_HALFLIFE_MAP_CVAR "
"DP_HALFLIFE_SPRITE "
"DP_MONSTERWALK "
"DP_MOVETYPEBOUNCEMISSILE "
"DP_MOVETYPEFOLLOW "
+"DP_NULL_MODEL "
"DP_QC_ASINACOSATANATAN2TAN "
"DP_QC_CHANGEPITCH "
+"DP_QC_CMD "
"DP_QC_COPYENTITY "
+"DP_QC_CRC16 "
"DP_QC_CVAR_DEFSTRING "
+"DP_QC_CVAR_DESCRIPTION "
"DP_QC_CVAR_STRING "
+"DP_QC_CVAR_TYPE "
+"DP_QC_EDICT_NUM "
+"DP_QC_ENTITYDATA "
+"DP_QC_ENTITYSTRING "
"DP_QC_ETOS "
+"DP_QC_EXTRESPONSEPACKET "
"DP_QC_FINDCHAIN "
+"DP_QC_FINDCHAIN_TOFIELD "
"DP_QC_FINDCHAINFLAGS "
"DP_QC_FINDCHAINFLOAT "
"DP_QC_FINDFLAGS "
"DP_QC_FS_SEARCH "
"DP_QC_GETLIGHT "
"DP_QC_GETSURFACE "
+"DP_QC_GETSURFACEPOINTATTRIBUTE "
"DP_QC_GETTAGINFO "
+"DP_QC_GETTAGINFO_BONEPROPERTIES "
+"DP_QC_GETTIME "
+"DP_QC_GETTIME_CDTRACK "
"DP_QC_MINMAXBOUND "
"DP_QC_MULTIPLETEMPSTRINGS "
+"DP_QC_NUM_FOR_EDICT "
"DP_QC_RANDOMVEC "
"DP_QC_SINCOSSQRTPOW "
"DP_QC_STRFTIME "
-"DP_QC_STRING_CASE_FUNCTIONS "
"DP_QC_STRINGBUFFERS "
+"DP_QC_STRINGBUFFERS_CVARLIST "
"DP_QC_STRINGCOLORFUNCTIONS "
+"DP_QC_STRING_CASE_FUNCTIONS "
+"DP_QC_STRREPLACE "
"DP_QC_TOKENIZEBYSEPARATOR "
+"DP_QC_TOKENIZE_CONSOLE "
"DP_QC_TRACEBOX "
"DP_QC_TRACETOSS "
"DP_QC_TRACE_MOVETYPE_HITMODEL "
"DP_QC_TRACE_MOVETYPE_WORLDONLY "
"DP_QC_UNLIMITEDTEMPSTRINGS "
+"DP_QC_URI_ESCAPE "
+"DP_QC_URI_GET "
"DP_QC_VECTOANGLES_WITH_ROLL "
"DP_QC_VECTORVECTORS "
+"DP_QC_WHICHPACK "
"DP_QUAKE2_MODEL "
"DP_QUAKE2_SPRITE "
"DP_QUAKE3_MAP "
"DP_SOLIDCORPSE "
"DP_SPRITE32 "
"DP_SV_BOTCLIENT "
+"DP_SV_BOUNCEFACTOR "
"DP_SV_CLIENTCOLORS "
"DP_SV_CLIENTNAME "
+"DP_SV_CMD "
"DP_SV_CUSTOMIZEENTITYFORCLIENT "
"DP_SV_DRAWONLYTOCLIENT "
"DP_SV_DROPCLIENT "
"DP_SV_EFFECT "
"DP_SV_ENTITYCONTENTSTRANSITION "
-"DP_SV_ONENTITYNOSPAWNFUNCTION "
"DP_SV_MODELFLAGS_AS_EFFECTS "
+"DP_SV_MOVETYPESTEP_LANDEVENT "
"DP_SV_NETADDRESS "
"DP_SV_NODRAWTOCLIENT "
+"DP_SV_ONENTITYNOSPAWNFUNCTION "
+"DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
"DP_SV_PING "
"DP_SV_PLAYERPHYSICS "
"DP_SV_POINTPARTICLES "
"DP_SV_PRECACHEANYTIME "
"DP_SV_PRINT "
"DP_SV_PUNCHVECTOR "
+"DP_SV_QCSTATUS "
"DP_SV_ROTATINGBMODEL "
"DP_SV_SETCOLOR "
+"DP_SV_SHUTDOWN "
"DP_SV_SLOWMO "
+"DP_SV_SPAWNFUNC_PREFIX "
+"DP_SV_WRITEPICTURE "
"DP_SV_WRITEUNTERMINATEDSTRING "
"DP_TE_BLOOD "
"DP_TE_BLOODSHOWER "
"DP_TE_STANDARDEFFECTBUILTINS "
"DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
"DP_VIEWZOOM "
+"DP_LIGHTSTYLE_STATICVALUE "
"EXT_BITSHIFT "
-//"EXT_CSQC " // not ready yet
"FRIK_FILE "
+"FTE_QC_CHECKPVS "
+"FTE_STRINGS "
"KRIMZON_SV_PARSECLIENTCOMMAND "
"NEH_CMD_PLAY2 "
"NEH_RESTOREGAME "
"PRYDON_CLIENTCURSOR "
"TENEBRAE_GFX_DLIGHTS "
"TW_SV_STEPCONTROL "
-"DP_SV_CMD "
-"DP_QC_CMD "
-"FTE_STRINGS "
-"DP_CON_BESTWEAPON "
-"DP_QC_STRREPLACE "
+"ZQ_PAUSE "
+"DP_CSQC_SPAWNPARTICLE "
+"DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
+"DP_CSQC_ENTITYNOCULL "
+//"EXT_CSQC " // not ready yet
;
/*
}
org = PRVM_G_VECTOR(OFS_PARM1);
VectorCopy (org, e->fields.server->origin);
- SV_LinkEdict (e, false);
+ SV_LinkEdict(e);
}
// TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
VectorCopy (max, e->fields.server->maxs);
VectorSubtract (max, min, e->fields.server->size);
- SV_LinkEdict (e, false);
+ SV_LinkEdict(e);
}
/*
static void VM_SV_setmodel (void)
{
prvm_edict_t *e;
- model_t *mod;
+ dp_model_t *mod;
int i;
VM_SAFEPARMCOUNT(2, VM_setmodel);
move = (int)PRVM_G_FLOAT(OFS_PARM2);
ent = PRVM_G_EDICT(OFS_PARM3);
- if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
+ if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+ trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
VM_SetTraceGlobals(&trace);
}
move = (int)PRVM_G_FLOAT(OFS_PARM4);
ent = PRVM_G_EDICT(OFS_PARM5);
- if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
+ if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+ trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
VM_SetTraceGlobals(&trace);
}
gravity = val->_float;
else
gravity = 1.0;
- gravity *= sv_gravity.value * 0.05;
+ gravity *= sv_gravity.value * 0.025;
for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
{
VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
VectorScale (tossent->fields.server->velocity, 0.05, move);
VectorAdd (tossent->fields.server->origin, move, end);
- trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
+ trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
VectorCopy (trace.endpos, tossent->fields.server->origin);
+ tossent->fields.server->velocity[2] -= gravity;
if (trace.fraction < 1)
break;
//============================================================================
+/*
+=================
+VM_SV_checkpvs
+
+Checks if an entity is in a point's PVS.
+Should be fast but can be inexact.
+
+float checkpvs(vector viewpos, entity viewee) = #240;
+=================
+*/
+static void VM_SV_checkpvs (void)
+{
+ vec3_t viewpos;
+ prvm_edict_t *viewee;
+#if 1
+ unsigned char *pvs;
+#else
+ static int fatpvsbytes;
+ static unsigned char fatpvs[MAX_MAP_LEAFS/8];
+#endif
+
+ VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
+ viewee = PRVM_G_EDICT(OFS_PARM1);
+
+ if(viewee->priv.server->free)
+ {
+ VM_Warning("checkpvs: can not check free entity\n");
+ PRVM_G_FLOAT(OFS_RETURN) = 4;
+ return;
+ }
+
+#if 1
+ if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ {
+ // no PVS support on this worldmodel... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 3;
+ return;
+ }
+ pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
+ if(!pvs)
+ {
+ // viewpos isn't in any PVS... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 2;
+ return;
+ }
+ PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
+#else
+ // using fat PVS like FTEQW does (slow)
+ if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ {
+ // no PVS support on this worldmodel... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 3;
+ return;
+ }
+ fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
+ if(!fatpvsbytes)
+ {
+ // viewpos isn't in any PVS... darn
+ PRVM_G_FLOAT(OFS_RETURN) = 2;
+ return;
+ }
+ PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
+#endif
+}
+
/*
=================
int i;
int numtouchedicts;
prvm_edict_t *touchedicts[MAX_EDICTS];
+ int chainfield;
+
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
- VM_SAFEPARMCOUNT(2, VM_SV_findradius);
+ if(prog->argc == 3)
+ chainfield = PRVM_G_INT(OFS_PARM2);
+ else
+ chainfield = prog->fieldoffsets.chain;
+ if (chainfield < 0)
+ PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
chain = (prvm_edict_t *)prog->edicts;
VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
if (DotProduct(eorg, eorg) < radius2)
{
- ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
+ PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
chain = ent;
}
}
VectorCopy (ent->fields.server->origin, end);
end[2] -= 256;
- trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
+ if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
+ SV_UnstickEntity(ent);
- if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
+ trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
+ if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
{
- if (trace.fraction < 1)
+ vec3_t offset, org;
+ VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]);
+ VectorAdd(ent->fields.server->origin, offset, org);
+ trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
+ VectorSubtract(trace.endpos, offset, trace.endpos);
+ if (trace.startsolid)
+ {
+ Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
+ SV_UnstickEntity(ent);
+ SV_LinkEdict(ent);
+ ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+ ent->fields.server->groundentity = 0;
+ PRVM_G_FLOAT(OFS_RETURN) = 1;
+ }
+ else if (trace.fraction < 1)
+ {
+ Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
VectorCopy (trace.endpos, ent->fields.server->origin);
- SV_LinkEdict (ent, false);
- 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->priv.server->suspendedinairflag = true;
+ SV_UnstickEntity(ent);
+ SV_LinkEdict(ent);
+ 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->priv.server->suspendedinairflag = true;
+ }
+ }
+ else
+ {
+ if (trace.fraction != 1)
+ {
+ if (trace.fraction < 1)
+ VectorCopy (trace.endpos, ent->fields.server->origin);
+ SV_LinkEdict(ent);
+ 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->priv.server->suspendedinairflag = true;
+ }
}
}
// try sending a trace straight
VectorCopy (prog->globals.server->v_forward, dir);
VectorMA (start, 2048, dir, end);
- tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
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) )
{
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, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
if (tr.ent == check)
{ // can shoot at this one
bestdist = dist;
MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
}
+// writes a picture as at most size bytes of data
+// message:
+// IMGNAME \0 SIZE(short) IMGDATA
+// if failed to read/compress:
+// IMGNAME \0 \0 \0
+//#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
+static void VM_SV_WritePicture (void)
+{
+ const char *imgname;
+ void *buf;
+ size_t size;
+
+ VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
+
+ imgname = PRVM_G_STRING(OFS_PARM1);
+ size = (int) PRVM_G_FLOAT(OFS_PARM2);
+ if(size > 65535)
+ size = 65535;
+
+ MSG_WriteString(WriteDest(), imgname);
+ if(Image_Compress(imgname, size, &buf, &size))
+ {
+ // actual picture
+ MSG_WriteShort(WriteDest(), size);
+ SZ_Write(WriteDest(), (unsigned char *) buf, size);
+ }
+ else
+ {
+ // placeholder
+ MSG_WriteShort(WriteDest(), 0);
+ }
+}
+
//////////////////////////////////////////////////////////
static void VM_SV_makestatic (void)
stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
break;
//float field sent as-is
- case 2:
+ case 8:
stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
break;
//integer value of float field
- case 8:
+ case 2:
stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
break;
default:
return;
}
memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
- SV_LinkEdict(out, false);
+ SV_LinkEdict(out);
}
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) 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));
+ MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
+ MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
+ MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
// count
MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
SV_FlushBroadcastMessages();
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) 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));
+ MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
+ MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
+ MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
// count
MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
SV_FlushBroadcastMessages();
SV_FlushBroadcastMessages();
}
-void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
+void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
{
int i, j, k;
float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
}
}
-static model_t *getmodel(prvm_edict_t *ed)
+static dp_model_t *getmodel(prvm_edict_t *ed)
{
int modelindex;
if (!ed || ed->priv.server->free)
return sv.models[modelindex];
}
-static msurface_t *getsurface(model_t *model, int surfacenum)
+static msurface_t *getsurface(dp_model_t *model, int surfacenum)
{
if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
return NULL;
//PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
static void VM_SV_getsurfacenumpoints(void)
{
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
// return 0 if no such surface
static void VM_SV_getsurfacepoint(void)
{
prvm_edict_t *ed;
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
int pointnum;
VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
static void VM_SV_getsurfacepointattribute(void)
{
prvm_edict_t *ed;
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
int pointnum;
int attributetype;
//PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
static void VM_SV_getsurfacenormal(void)
{
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
vec3_t normal;
VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
//PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
static void VM_SV_getsurfacetexture(void)
{
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
PRVM_G_INT(OFS_RETURN) = OFS_NULL;
vec3_t clipped, p;
vec_t dist, bestdist;
prvm_edict_t *ed;
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
vec_t *point;
VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
static void VM_SV_getsurfaceclippedpoint(void)
{
prvm_edict_t *ed;
- model_t *model;
+ dp_model_t *model;
msurface_t *surface;
vec3_t p, out;
VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
const char *tagname = PRVM_G_STRING(OFS_PARM2);
prvm_eval_t *v;
int modelindex;
- model_t *model;
+ dp_model_t *model;
VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
if (e == prog->edicts)
int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
{
int i;
- model_t *model;
+ dp_model_t *model;
i = (int)e->fields.server->modelindex;
if (i < 1 || i >= MAX_MODELS)
model = sv.models[i];
return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
-};
+}
+
+int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
+{
+ int r;
+ dp_model_t *model;
+ int frame;
+ int modelindex;
+
+ *tagname = NULL;
+ *parentindex = 0;
+ Matrix4x4_CreateIdentity(tag_localmatrix);
+
+ if (tagindex >= 0
+ && (modelindex = (int)e->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
+ && (model = sv.models[(int)e->fields.server->modelindex])
+ && model->animscenes)
+ {
+ frame = (int)e->fields.server->frame;
+ if (frame < 0 || frame >= model->numframes)
+ frame = 0;
+
+ r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, model->animscenes[frame].firstframe, tagindex - 1, parentindex, tagname, tag_localmatrix);
+
+ if(!r) // success?
+ *parentindex += 1;
+
+ return r;
+ }
+
+ return 1;
+}
void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
{
- float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
- if (scale == 0)
- scale = 1;
+ prvm_eval_t *val;
+ float scale;
+ float pitchsign = 1;
+
+ scale = 1;
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
+ if (val && val->_float != 0)
+ scale = val->_float;
+
if (viewmatrix)
- Matrix4x4_CreateFromQuakeEntity(out, 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], scale);
+ Matrix4x4_CreateFromQuakeEntity(out, 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], scale * cl_viewmodel_scale.value);
else
- Matrix4x4_CreateFromQuakeEntity(out, 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], scale * cl_viewmodel_scale.value);
+ {
+ pitchsign = SV_GetPitchSign(ent);
+ Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], pitchsign * ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale);
+ }
}
int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
{
int modelindex;
int frame;
- model_t *model;
+ dp_model_t *model;
if (tagindex >= 0
&& (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
&& (model = sv.models[(int)ent->fields.server->modelindex])
prvm_eval_t *val;
int modelindex, attachloop;
matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
- model_t *model;
+ dp_model_t *model;
*out = identitymatrix; // warnings and errors return identical matrix
return 2;
modelindex = (int)ent->fields.server->modelindex;
- if (modelindex <= 0 || modelindex > MAX_MODELS)
+ if (modelindex <= 0 || modelindex >= MAX_MODELS)
return 3;
model = sv.models[modelindex];
ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
if (ret && attachloop == 0)
return ret;
- Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
SV_GetEntityMatrix(ent, &entitymatrix, false);
- Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
+ Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
+ Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
// next iteration we process the parent entity
if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
{
modelindex = (int)ent->fields.server->modelindex;
tag_index = 0;
- if (modelindex <= 0 || modelindex > MAX_MODELS)
+ if (modelindex <= 0 || modelindex >= MAX_MODELS)
Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
else
{
Con_Printf("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;
static void VM_SV_gettaginfo (void)
prvm_edict_t *e;
int tagindex;
matrix4x4_t tag_matrix;
+ matrix4x4_t tag_localmatrix;
+ int parentindex;
+ const char *tagname;
int returncode;
+ prvm_eval_t *val;
+ vec3_t fo, le, up, trans;
VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
- Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
+ Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
+ VectorScale(le, -1, prog->globals.server->v_right);
+ SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
+ Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
+
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
+ val->_float = parentindex;
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
+ val->string = tagname ? PRVM_SetTempString(tagname) : 0;
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
+ VectorCopy(trans, val->vector);
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
+ VectorCopy(fo, val->vector);
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
+ VectorScale(le, -1, val->vector);
+ if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
+ VectorCopy(up, val->vector);
switch(returncode)
{
static void VM_SV_setmodelindex (void)
{
prvm_edict_t *e;
- model_t *mod;
+ dp_model_t *mod;
int i;
VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
return;
}
i = (int)PRVM_G_FLOAT(OFS_PARM1);
- if (i <= 0 || i > MAX_MODELS)
+ if (i <= 0 || i >= MAX_MODELS)
{
VM_Warning("setmodelindex: invalid modelindex\n");
return;
PRVM_G_INT(OFS_RETURN) = OFS_NULL;
i = (int)PRVM_G_FLOAT(OFS_PARM0);
- if (i <= 0 || i > MAX_MODELS)
+ if (i <= 0 || i >= MAX_MODELS)
{
VM_Warning("modelnameforindex: invalid modelindex\n");
return;
{
VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
+ if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
+ return;
+
MSG_WriteByte(&sv.datagram, svc_trailparticles);
MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
int effectnum, count;
vec3_t org, vel;
VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
+
+ if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
+ return;
+
effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
SV_FlushBroadcastMessages();
}
+//PF_setpause, // void(float pause) setpause = #531;
+static void VM_SV_setpause(void) {
+ int pauseValue;
+ pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
+ if (pauseValue != 0) { //pause the game
+ sv.paused = 1;
+ sv.pausedstart = Sys_DoubleTime();
+ } else { //disable pause, in case it was enabled
+ if (sv.paused != 0) {
+ sv.paused = 0;
+ sv.pausedstart = 0;
+ }
+ }
+ // send notification to all clients
+ MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
+ MSG_WriteByte(&sv.reliable_datagram, sv.paused);
+}
+
prvm_builtin_t vm_sv_builtins[] = {
NULL, // #0 NULL function (not callable) (QUAKE)
VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
VM_spawn, // #14 entity() spawn (QUAKE)
VM_remove, // #15 void(entity e) remove (QUAKE)
-VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
+VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
NULL, // #237
NULL, // #238
NULL, // #239
-NULL, // #240
+VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
NULL, // #241
NULL, // #242
NULL, // #243
VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
-VM_hash, // #487 float(float caseinsensitive, string s, ...) hash = #487;
+NULL, // #487
NULL, // #488
NULL, // #489
NULL, // #490
NULL, // #491
NULL, // #492
NULL, // #493
-NULL, // #494
-NULL, // #495
-NULL, // #496
-NULL, // #497
-NULL, // #498
-NULL, // #499
+VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
+VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
+VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
+VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
+VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
+VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
+VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
+VM_SV_WritePicture, // #501
+NULL, // #502
+VM_whichpack, // #503 string(string) whichpack = #503;
+NULL, // #504
+NULL, // #505
+NULL, // #506
+NULL, // #507
+NULL, // #508
+NULL, // #509
+VM_uri_escape, // #510 string(string in) uri_escape = #510;
+VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
+VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
+VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
+VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
+VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
+VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
+VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
+NULL, // #520
+NULL, // #521
+NULL, // #522
+NULL, // #523
+NULL, // #524
+NULL, // #525
+NULL, // #526
+NULL, // #527
+NULL, // #528
+VM_loadfromdata, // #529
+VM_loadfromfile, // #530
+VM_SV_setpause, // #531 void(float pause) setpause = #531;
+NULL, // #532
+NULL, // #533
+NULL, // #534
+NULL, // #535
+NULL, // #536
+NULL, // #537
+NULL, // #538
+NULL, // #539
+NULL, // #540
+NULL, // #541
+NULL, // #542
+NULL, // #543
+NULL, // #544
+NULL, // #545
+NULL, // #546
+NULL, // #547
+NULL, // #548
+NULL, // #549
+NULL, // #550
+NULL, // #551
+NULL, // #552
+NULL, // #553
+NULL, // #554
+NULL, // #555
+NULL, // #556
+NULL, // #557
+NULL, // #558
+NULL, // #559
+NULL, // #560
+NULL, // #561
+NULL, // #562
+NULL, // #563
+NULL, // #564
+NULL, // #565
+NULL, // #566
+NULL, // #567
+NULL, // #568
+NULL, // #569
+NULL, // #570
+NULL, // #571
+NULL, // #572
+NULL, // #573
+NULL, // #574
+NULL, // #575
+NULL, // #576
+NULL, // #577
+NULL, // #578
+NULL, // #579
+NULL, // #580
+NULL, // #581
+NULL, // #582
+NULL, // #583
+NULL, // #584
+NULL, // #585
+NULL, // #586
+NULL, // #587
+NULL, // #588
+NULL, // #589
+NULL, // #590
+NULL, // #591
+NULL, // #592
+NULL, // #593
+NULL, // #594
+NULL, // #595
+NULL, // #596
+NULL, // #597
+NULL, // #598
+NULL, // #599
+NULL, // #600
+NULL, // #601
+NULL, // #602
+NULL, // #603
+NULL, // #604
+VM_callfunction, // #605
+VM_writetofile, // #606
+VM_isfunction, // #607
+NULL, // #608
+NULL, // #609
+NULL, // #610
+NULL, // #611
+NULL, // #612
+VM_parseentitydata, // #613
+NULL, // #614
+NULL, // #615
+NULL, // #616
+NULL, // #617
+NULL, // #618
+NULL, // #619
+NULL, // #620
+NULL, // #621
+NULL, // #622
+NULL, // #623
+VM_getextresponse, // #624 string getextresponse(void)
+NULL, // #625
};
const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
void VM_SV_Cmd_Reset(void)
{
+ World_End(&sv.world);
+ if(prog->funcoffsets.SV_Shutdown)
+ {
+ func_t s = prog->funcoffsets.SV_Shutdown;
+ prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
+ PRVM_ExecuteProgram(s,"SV_Shutdown() required");
+ }
+
VM_Cmd_Reset();
}