-const char *vm_sv_extensions =
-"BX_WAL_SUPPORT "
-"DP_BUTTONCHAT "
-"DP_BUTTONUSE "
-"DP_CL_LOADSKY "
-"DP_CON_ALIASPARAMETERS "
-"DP_CON_BESTWEAPON "
-"DP_CON_EXPANDCVAR "
-"DP_CON_SET "
-"DP_CON_SETA "
-"DP_CON_STARTMAP "
-"DP_CRYPTO "
-"DP_CSQC_BINDMAPS "
-"DP_CSQC_ENTITYWORLDOBJECT "
-"DP_CSQC_ENTITYMODELLIGHT "
-"DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
-"DP_CSQC_MAINVIEW "
-"DP_CSQC_MINFPS_QUALITY "
-"DP_CSQC_MULTIFRAME_INTERPOLATION "
-"DP_CSQC_BOXPARTICLES "
-"DP_CSQC_SPAWNPARTICLE "
-"DP_CSQC_QUERYRENDERENTITY "
-"DP_CSQC_ROTATEMOVES "
-"DP_CSQC_SETPAUSE "
-"DP_CSQC_V_CALCREFDEF_WIP1 "
-"DP_CSQC_V_CALCREFDEF_WIP2 "
-"DP_EF_ADDITIVE "
-"DP_EF_BLUE "
-"DP_EF_DOUBLESIDED "
-"DP_EF_DYNAMICMODELLIGHT "
-"DP_EF_FLAME "
-"DP_EF_FULLBRIGHT "
-"DP_EF_NODEPTHTEST "
-"DP_EF_NODRAW "
-"DP_EF_NOGUNBOB "
-"DP_EF_NOSELFSHADOW "
-"DP_EF_NOSHADOW "
-"DP_EF_RED "
-"DP_EF_RESTARTANIM_BIT "
-"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_TRAILEFFECTNUM "
-"DP_ENT_VIEWMODEL "
-"DP_GFX_EXTERNALTEXTURES "
-"DP_GFX_EXTERNALTEXTURES_PERMAP "
-"DP_GFX_FOG "
-"DP_GFX_MODEL_INTERPOLATION "
-"DP_GFX_QUAKE3MODELTAGS "
-"DP_GFX_SKINFILES "
-"DP_GFX_SKYBOX "
-"DP_GFX_FONTS "
-"DP_GFX_FONTS_FREETYPE "
-"DP_UTF8 "
-"DP_FONT_VARIABLEWIDTH "
-"DP_HALFLIFE_MAP "
-"DP_HALFLIFE_MAP_CVAR "
-"DP_HALFLIFE_SPRITE "
-"DP_INPUTBUTTONS "
-"DP_LIGHTSTYLE_STATICVALUE "
-"DP_LITSPRITES "
-"DP_LITSUPPORT "
-"DP_MONSTERWALK "
-"DP_MOVETYPEBOUNCEMISSILE "
-"DP_MOVETYPEFLYWORLDONLY "
-"DP_MOVETYPEFOLLOW "
-"DP_NULL_MODEL "
-"DP_QC_ASINACOSATANATAN2TAN "
-"DP_QC_AUTOCVARS "
-"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_DIGEST "
-"DP_QC_DIGEST_SHA256 "
-"DP_QC_EDICT_NUM "
-"DP_QC_ENTITYDATA "
-"DP_QC_ENTITYSTRING "
-"DP_QC_ETOS "
-"DP_QC_EXTRESPONSEPACKET "
-"DP_QC_FINDCHAIN "
-"DP_QC_FINDCHAINFLAGS "
-"DP_QC_FINDCHAINFLOAT "
-"DP_QC_FINDCHAIN_TOFIELD "
-"DP_QC_FINDFLAGS "
-"DP_QC_FINDFLOAT "
-"DP_QC_FS_SEARCH "
-"DP_QC_GETLIGHT "
-"DP_QC_GETSURFACE "
-"DP_QC_GETSURFACETRIANGLE "
-"DP_QC_GETSURFACEPOINTATTRIBUTE "
-"DP_QC_GETTAGINFO "
-"DP_QC_GETTAGINFO_BONEPROPERTIES "
-"DP_QC_GETTIME "
-"DP_QC_GETTIME_CDTRACK "
-"DP_QC_I18N "
-"DP_QC_LOG "
-"DP_QC_MINMAXBOUND "
-"DP_QC_MULTIPLETEMPSTRINGS "
-"DP_QC_NUM_FOR_EDICT "
-"DP_QC_RANDOMVEC "
-"DP_QC_SINCOSSQRTPOW "
-"DP_QC_SPRINTF "
-"DP_QC_STRFTIME "
-"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_URI_POST "
-"DP_QC_VECTOANGLES_WITH_ROLL "
-"DP_QC_VECTORVECTORS "
-"DP_QC_WHICHPACK "
-"DP_QUAKE2_MODEL "
-"DP_QUAKE2_SPRITE "
-"DP_QUAKE3_MAP "
-"DP_QUAKE3_MODEL "
-"DP_REGISTERCVAR "
-"DP_SKELETONOBJECTS "
-"DP_SND_DIRECTIONLESSATTNNONE "
-"DP_SND_FAKETRACKS "
-"DP_SND_SOUND7_WIP1 "
-"DP_SND_SOUND7_WIP2 "
-"DP_SND_OGGVORBIS "
-"DP_SND_SETPARAMS "
-"DP_SND_STEREOWAV "
-"DP_SND_GETSOUNDTIME "
-"DP_VIDEO_DPV "
-"DP_VIDEO_SUBTITLES "
-"DP_SOLIDCORPSE "
-"DP_SPRITE32 "
-"DP_SV_BOTCLIENT "
-"DP_SV_BOUNCEFACTOR "
-"DP_SV_CLIENTCAMERA "
-"DP_SV_CLIENTCOLORS "
-"DP_SV_CLIENTNAME "
-"DP_SV_CMD "
-"DP_SV_CUSTOMIZEENTITYFORCLIENT "
-"DP_SV_DISCARDABLEDEMO "
-"DP_SV_DRAWONLYTOCLIENT "
-"DP_SV_DROPCLIENT "
-"DP_SV_EFFECT "
-"DP_SV_ENTITYCONTENTSTRANSITION "
-"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_PING_PACKETLOSS "
-"DP_SV_PLAYERPHYSICS "
-"DP_PHYSICS_ODE "
-"DP_SV_POINTPARTICLES "
-"DP_SV_POINTSOUND "
-"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_CUSTOMFLASH "
-"DP_TE_EXPLOSIONRGB "
-"DP_TE_FLAMEJET "
-"DP_TE_PARTICLECUBE "
-"DP_TE_PARTICLERAIN "
-"DP_TE_PARTICLESNOW "
-"DP_TE_PLASMABURN "
-"DP_TE_QUADEFFECTS1 "
-"DP_TE_SMALLFLASH "
-"DP_TE_SPARK "
-"DP_TE_STANDARDEFFECTBUILTINS "
-"DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
-"DP_VIEWZOOM "
-"EXT_BITSHIFT "
-"FRIK_FILE "
-"FTE_CSQC_SKELETONOBJECTS "
-"FTE_QC_CHECKPVS "
-"FTE_STRINGS "
-"KRIMZON_SV_PARSECLIENTCOMMAND "
-"NEH_CMD_PLAY2 "
-"NEH_RESTOREGAME "
-"NEXUIZ_PLAYERMODEL "
-"NXQ_GFX_LETTERBOX "
-"PRYDON_CLIENTCURSOR "
-"TENEBRAE_GFX_DLIGHTS "
-"TW_SV_STEPCONTROL "
-"ZQ_PAUSE "
-//"EXT_CSQC " // not ready yet
-;
+const char *vm_sv_extensions[] = {
+"BX_WAL_SUPPORT",
+"DP_BUTTONCHAT",
+"DP_BUTTONUSE",
+"DP_CL_LOADSKY",
+"DP_CON_ALIASPARAMETERS",
+"DP_CON_BESTWEAPON",
+"DP_CON_EXPANDCVAR",
+"DP_CON_SET",
+"DP_CON_SETA",
+"DP_CON_STARTMAP",
+"DP_COVERAGE",
+"DP_CRYPTO",
+"DP_CSQC_BINDMAPS",
+"DP_CSQC_ENTITYWORLDOBJECT",
+"DP_CSQC_ENTITYMODELLIGHT",
+"DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET",
+"DP_CSQC_MAINVIEW",
+"DP_CSQC_MINFPS_QUALITY",
+"DP_CSQC_MULTIFRAME_INTERPOLATION",
+"DP_CSQC_BOXPARTICLES",
+"DP_CSQC_SPAWNPARTICLE",
+"DP_CSQC_QUERYRENDERENTITY",
+"DP_CSQC_ROTATEMOVES",
+"DP_CSQC_SETPAUSE",
+"DP_CSQC_V_CALCREFDEF_WIP1",
+"DP_CSQC_V_CALCREFDEF_WIP2",
+"DP_EF_ADDITIVE",
+"DP_EF_BLUE",
+"DP_EF_DOUBLESIDED",
+"DP_EF_DYNAMICMODELLIGHT",
+"DP_EF_FLAME",
+"DP_EF_FULLBRIGHT",
+"DP_EF_NODEPTHTEST",
+"DP_EF_NODRAW",
+"DP_EF_NOGUNBOB",
+"DP_EF_NOSELFSHADOW",
+"DP_EF_NOSHADOW",
+"DP_EF_RED",
+"DP_EF_RESTARTANIM_BIT",
+"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_TRAILEFFECTNUM",
+"DP_ENT_VIEWMODEL",
+"DP_GFX_EXTERNALTEXTURES",
+"DP_GFX_EXTERNALTEXTURES_PERMAP",
+"DP_GFX_FOG",
+"DP_GFX_MODEL_INTERPOLATION",
+"DP_GFX_QUAKE3MODELTAGS",
+"DP_GFX_SKINFILES",
+"DP_GFX_SKYBOX",
+"DP_GFX_FONTS",
+"DP_GFX_FONTS_FREETYPE",
+"DP_UTF8",
+"DP_FONT_VARIABLEWIDTH",
+"DP_HALFLIFE_MAP",
+"DP_HALFLIFE_MAP_CVAR",
+"DP_HALFLIFE_SPRITE",
+"DP_INPUTBUTTONS",
+"DP_LIGHTSTYLE_STATICVALUE",
+"DP_LITSPRITES",
+"DP_LITSUPPORT",
+"DP_MONSTERWALK",
+"DP_MOVETYPEBOUNCEMISSILE",
+"DP_MOVETYPEFLYWORLDONLY",
+"DP_MOVETYPEFOLLOW",
+"DP_NULL_MODEL",
+"DP_QC_ASINACOSATANATAN2TAN",
+"DP_QC_AUTOCVARS",
+"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_DIGEST",
+"DP_QC_DIGEST_SHA256",
+"DP_QC_EDICT_NUM",
+"DP_QC_ENTITYDATA",
+"DP_QC_ENTITYSTRING",
+"DP_QC_ETOS",
+"DP_QC_EXTRESPONSEPACKET",
+"DP_QC_FINDBOX",
+"DP_QC_FINDCHAIN",
+"DP_QC_FINDCHAINFLAGS",
+"DP_QC_FINDCHAINFLOAT",
+"DP_QC_FINDCHAIN_TOFIELD",
+"DP_QC_FINDFLAGS",
+"DP_QC_FINDFLOAT",
+"DP_QC_FS_SEARCH",
+"DP_QC_FS_SEARCH_PACKFILE",
+"DP_QC_GETLIGHT",
+"DP_QC_GETSURFACE",
+"DP_QC_GETSURFACETRIANGLE",
+"DP_QC_GETSURFACEPOINTATTRIBUTE",
+"DP_QC_GETTAGINFO",
+"DP_QC_GETTAGINFO_BONEPROPERTIES",
+"DP_QC_GETTIME",
+"DP_QC_GETTIME_CDTRACK",
+"DP_QC_I18N",
+"DP_QC_LOG",
+"DP_QC_MINMAXBOUND",
+"DP_QC_MULTIPLETEMPSTRINGS",
+"DP_QC_NUDGEOUTOFSOLID",
+"DP_QC_NUM_FOR_EDICT",
+"DP_QC_RANDOMVEC",
+"DP_QC_SINCOSSQRTPOW",
+"DP_QC_SPRINTF",
+"DP_QC_STRFTIME",
+"DP_QC_STRINGBUFFERS",
+"DP_QC_STRINGBUFFERS_CVARLIST",
+"DP_QC_STRINGBUFFERS_EXT_WIP",
+"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_URI_POST",
+"DP_QC_VECTOANGLES_WITH_ROLL",
+"DP_QC_VECTORVECTORS",
+"DP_QC_WHICHPACK",
+"DP_QUAKE2_MODEL",
+"DP_QUAKE2_SPRITE",
+"DP_QUAKE3_MAP",
+"DP_QUAKE3_MODEL",
+"DP_REGISTERCVAR",
+"DP_SKELETONOBJECTS",
+"DP_SND_DIRECTIONLESSATTNNONE",
+"DP_SND_FAKETRACKS",
+"DP_SND_SOUND7_WIP1",
+"DP_SND_SOUND7_WIP2",
+"DP_SND_OGGVORBIS",
+"DP_SND_SETPARAMS",
+"DP_SND_STEREOWAV",
+"DP_SND_GETSOUNDTIME",
+"DP_VIDEO_DPV",
+"DP_VIDEO_SUBTITLES",
+"DP_SOLIDCORPSE",
+"DP_SPRITE32",
+"DP_SV_BOTCLIENT",
+"DP_SV_BOUNCEFACTOR",
+"DP_SV_CLIENTCAMERA",
+"DP_SV_CLIENTCOLORS",
+"DP_SV_CLIENTNAME",
+"DP_SV_CMD",
+"DP_SV_CUSTOMIZEENTITYFORCLIENT",
+"DP_SV_DISABLECLIENTPREDICTION",
+"DP_SV_DISCARDABLEDEMO",
+"DP_SV_DRAWONLYTOCLIENT",
+"DP_SV_DROPCLIENT",
+"DP_SV_EFFECT",
+"DP_SV_ENTITYCONTENTSTRANSITION",
+"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_PING_PACKETLOSS",
+"DP_SV_PLAYERPHYSICS",
+"DP_PHYSICS_ODE",
+"DP_SV_POINTPARTICLES",
+"DP_SV_POINTSOUND",
+"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_CUSTOMFLASH",
+"DP_TE_EXPLOSIONRGB",
+"DP_TE_FLAMEJET",
+"DP_TE_PARTICLECUBE",
+"DP_TE_PARTICLERAIN",
+"DP_TE_PARTICLESNOW",
+"DP_TE_PLASMABURN",
+"DP_TE_QUADEFFECTS1",
+"DP_TE_SMALLFLASH",
+"DP_TE_SPARK",
+"DP_TE_STANDARDEFFECTBUILTINS",
+"DP_TRACE_HITCONTENTSMASK_SURFACEINFO"
+"DP_USERMOVETYPES",
+"DP_VIEWZOOM",
+"EXT_BITSHIFT",
+"FRIK_FILE",
+"FTE_CSQC_SKELETONOBJECTS",
+"FTE_QC_CHECKPVS",
+"FTE_STRINGS",
+"KRIMZON_SV_PARSECLIENTCOMMAND",
+"NEH_CMD_PLAY2",
+"NEH_RESTOREGAME",
+"NEXUIZ_PLAYERMODEL",
+"NXQ_GFX_LETTERBOX",
+"PRYDON_CLIENTCURSOR",
+"TENEBRAE_GFX_DLIGHTS",
+"TW_SV_STEPCONTROL",
+"ZQ_PAUSE",
+"DP_RM_CLIPGROUP",
+NULL
+//"EXT_CSQC" // not ready yet
+};
/*
=================
static void VM_SV_setorigin(prvm_prog_t *prog)
{
prvm_edict_t *e;
- float *org;
- VM_SAFEPARMCOUNT(2, VM_setorigin);
+ VM_SAFEPARMCOUNT(2, VM_SV_setorigin);
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
VM_Warning(prog, "setorigin: can not modify world entity\n");
return;
}
- if (e->priv.server->free)
+ if (e->free)
{
VM_Warning(prog, "setorigin: can not modify free entity\n");
return;
}
- org = PRVM_G_VECTOR(OFS_PARM1);
- VectorCopy (org, PRVM_serveredictvector(e, origin));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), PRVM_serveredictvector(e, origin));
if(e->priv.required->mark == PRVM_EDICT_MARK_WAIT_FOR_SETORIGIN)
e->priv.required->mark = PRVM_EDICT_MARK_SETORIGIN_CAUGHT;
SV_LinkEdict(e);
}
// TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
-static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max, qboolean rotate)
+static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max, qbool rotate)
{
int i;
VM_SV_setsize
the size box is rotated by the current angle
-LordHavoc: no it isn't...
+LadyHavoc: no it isn't...
setsize (entity, minvector, maxvector)
=================
static void VM_SV_setsize(prvm_prog_t *prog)
{
prvm_edict_t *e;
- float *min, *max;
+ vec3_t mins, maxs;
- VM_SAFEPARMCOUNT(3, VM_setsize);
+ VM_SAFEPARMCOUNT(3, VM_SV_setsize);
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
VM_Warning(prog, "setsize: can not modify world entity\n");
return;
}
- if (e->priv.server->free)
+ if (e->free)
{
VM_Warning(prog, "setsize: can not modify free entity\n");
return;
}
- min = PRVM_G_VECTOR(OFS_PARM1);
- max = PRVM_G_VECTOR(OFS_PARM2);
- SetMinMaxSize(prog, e, min, max, false);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), mins);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), maxs);
+ SetMinMaxSize(prog, e, mins, maxs, false);
}
static void VM_SV_setmodel(prvm_prog_t *prog)
{
prvm_edict_t *e;
- dp_model_t *mod;
+ model_t *mod;
int i;
- VM_SAFEPARMCOUNT(2, VM_setmodel);
+ VM_SAFEPARMCOUNT(2, VM_SV_setmodel);
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
VM_Warning(prog, "setmodel: can not modify world entity\n");
return;
}
- if (e->priv.server->free)
+ if (e->free)
{
VM_Warning(prog, "setmodel: can not modify free entity\n");
return;
VM_VarString(prog, 1, string, sizeof(string));
entnum = PRVM_G_EDICTNUM(OFS_PARM0);
- // LordHavoc: div0 requested that sprintto world operate like print
+ // LadyHavoc: div0 requested that sprintto world operate like print
if (entnum == 0)
{
Con_Print(string);
*/
static void VM_SV_particle(prvm_prog_t *prog)
{
- float *org, *dir;
- float color;
- float count;
+ vec3_t org, dir;
+ int color;
+ int count;
VM_SAFEPARMCOUNT(4, VM_SV_particle);
- 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, (int)color, (int)count);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), dir);
+ color = (int)PRVM_G_FLOAT(OFS_PARM2);
+ count = (int)PRVM_G_FLOAT(OFS_PARM3);
+ SV_StartParticle (org, dir, color, count);
}
static void VM_SV_ambientsound(prvm_prog_t *prog)
{
const char *samp;
- float *pos;
- float vol, attenuation;
+ vec3_t pos;
+ prvm_vec_t vol, attenuation;
int soundnum, large;
VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
- pos = PRVM_G_VECTOR (OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
samp = PRVM_G_STRING(OFS_PARM1);
vol = PRVM_G_FLOAT(OFS_PARM2);
attenuation = PRVM_G_FLOAT(OFS_PARM3);
if (soundnum >= 256)
large = true;
+ if(sv.protocol == PROTOCOL_NEHAHRABJP)
+ large = false;
+
// add an svc_spawnambient command to the level signon packet
if (large)
MSG_WriteVector(&sv.signon, pos, sv.protocol);
- if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ if (large || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
MSG_WriteShort (&sv.signon, soundnum);
else
MSG_WriteByte (&sv.signon, soundnum);
An attenuation of 0 will play full volume everywhere in the level.
Larger attenuations will drop off.
+void(entity e, float chan, string samp, float volume[, float atten[, float pitchchange[, float flags]]]) sound (QUAKE)
=================
*/
static void VM_SV_sound(prvm_prog_t *prog)
const char *sample;
int channel;
prvm_edict_t *entity;
- int volume;
+ int nvolume;
int flags;
float attenuation;
float pitchchange;
entity = PRVM_G_EDICT(OFS_PARM0);
channel = (int)PRVM_G_FLOAT(OFS_PARM1);
sample = PRVM_G_STRING(OFS_PARM2);
- volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
+ nvolume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
if (prog->argc < 5)
{
Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
flags = 0;
if(channel >= 8 && channel <= 15) // weird QW feature
{
- flags |= CHANFLAG_RELIABLE;
+ flags |= CHANNELFLAG_RELIABLE;
channel -= 8;
}
}
else
- flags = PRVM_G_FLOAT(OFS_PARM6);
+ {
+ // LadyHavoc: we only let the qc set certain flags, others are off-limits
+ flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED | CHANNELFLAG_FULLVOLUME);
+ }
- if (volume < 0 || volume > 255)
+ if (nvolume < 0 || nvolume > 255)
{
VM_Warning(prog, "SV_StartSound: volume must be in range 0-1\n");
return;
return;
}
- SV_StartSound (entity, channel, sample, volume, attenuation, flags & CHANFLAG_RELIABLE, pitchchange);
+ SV_StartSound (entity, channel, sample, nvolume, attenuation, flags & CHANNELFLAG_RELIABLE, pitchchange);
}
/*
static void VM_SV_pointsound(prvm_prog_t *prog)
{
const char *sample;
- int volume;
+ int nvolume;
float attenuation;
float pitchchange;
vec3_t org;
VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
sample = PRVM_G_STRING(OFS_PARM1);
- volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
+ nvolume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
attenuation = PRVM_G_FLOAT(OFS_PARM3);
pitchchange = prog->argc < 5 ? 0 : PRVM_G_FLOAT(OFS_PARM4) * 0.01f;
- if (volume < 0 || volume > 255)
+ if (nvolume < 0 || nvolume > 255)
{
VM_Warning(prog, "SV_StartPointSound: volume must be in range 0-1\n");
return;
return;
}
- SV_StartPointSound (org, sample, volume, attenuation, pitchchange);
+ SV_StartPointSound (org, sample, nvolume, attenuation, pitchchange);
}
/*
*/
static void VM_SV_traceline(prvm_prog_t *prog)
{
- float *v1, *v2;
+ vec3_t v1, v2;
trace_t trace;
int move;
prvm_edict_t *ent;
prog->xfunction->builtinsprofile += 30;
- v1 = PRVM_G_VECTOR(OFS_PARM0);
- v2 = PRVM_G_VECTOR(OFS_PARM1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), v2);
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(v2[1]) || IS_NAN(v2[2]))
+ if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+ trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtracelinelength.value);
VM_SetTraceGlobals(prog, &trace);
}
tracebox (vector1, vector mins, vector maxs, vector2, tryents)
=================
*/
-// LordHavoc: added this for my own use, VERY useful, similar to traceline
+// LadyHavoc: added this for my own use, VERY useful, similar to traceline
static void VM_SV_tracebox(prvm_prog_t *prog)
{
- float *v1, *v2, *m1, *m2;
+ vec3_t v1, v2, m1, m2;
trace_t trace;
int move;
prvm_edict_t *ent;
prog->xfunction->builtinsprofile += 30;
- v1 = PRVM_G_VECTOR(OFS_PARM0);
- m1 = PRVM_G_VECTOR(OFS_PARM1);
- m2 = PRVM_G_VECTOR(OFS_PARM2);
- v2 = PRVM_G_VECTOR(OFS_PARM3);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), m1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), m2);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM3), v2);
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(v2[1]) || IS_NAN(v2[2]))
+ if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->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_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+ trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtraceboxlength.value);
VM_SetTraceGlobals(prog, &trace);
}
{
int i;
float gravity;
- vec3_t move, end;
+ vec3_t move, end, tossentorigin, tossentmins, tossentmaxs;
vec3_t original_origin;
vec3_t original_velocity;
vec3_t original_angles;
gravity = 1.0f;
gravity *= sv_gravity.value * 0.025;
- for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
+ for (i = 0;i < 200;i++) // LadyHavoc: sanity check; never trace more than 10 seconds
{
SV_CheckVelocity (tossent);
PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
VectorMA (PRVM_serveredictvector(tossent, angles), 0.05, PRVM_serveredictvector(tossent, avelocity), PRVM_serveredictvector(tossent, angles));
VectorScale (PRVM_serveredictvector(tossent, velocity), 0.05, move);
VectorAdd (PRVM_serveredictvector(tossent, origin), move, end);
- trace = SV_TraceBox(PRVM_serveredictvector(tossent, origin), PRVM_serveredictvector(tossent, mins), PRVM_serveredictvector(tossent, maxs), end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
+ VectorCopy(PRVM_serveredictvector(tossent, origin), tossentorigin);
+ VectorCopy(PRVM_serveredictvector(tossent, mins), tossentmins);
+ VectorCopy(PRVM_serveredictvector(tossent, maxs), tossentmaxs);
+ trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent), 0, 0, collision_extendmovelength.value);
VectorCopy (trace.endpos, PRVM_serveredictvector(tossent, origin));
PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
// look up the client's edict
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->priv.server->free || PRVM_serveredictfloat(ent, health) <= 0 || ((int)PRVM_serveredictfloat(ent, flags) & FL_NOTARGET)))
+ if (i != check && (ent->free || PRVM_serveredictfloat(ent, health) <= 0 || ((int)PRVM_serveredictfloat(ent, flags) & FL_NOTARGET)))
continue;
// found a valid client (possibly the same one again)
break;
// return check if it might be visible
ent = PRVM_EDICT_NUM(sv.lastcheck);
- if (ent->priv.server->free || PRVM_serveredictfloat(ent, health) <= 0)
+ if (ent->free || PRVM_serveredictfloat(ent, health) <= 0)
{
VM_RETURN_EDICT(prog->edicts);
return;
*/
static void VM_SV_checkpvs(prvm_prog_t *prog)
{
- vec3_t viewpos;
+ vec3_t viewpos, absmin, absmax;
prvm_edict_t *viewee;
#if 1
unsigned char *pvs;
VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
viewee = PRVM_G_EDICT(OFS_PARM1);
- if(viewee->priv.server->free)
+ if(viewee->free)
{
VM_Warning(prog, "checkpvs: can not check free entity\n");
PRVM_G_FLOAT(OFS_RETURN) = 4;
}
#if 1
- if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ if(!sv.worldmodel || !sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
{
// no PVS support on this worldmodel... darn
PRVM_G_FLOAT(OFS_RETURN) = 3;
PRVM_G_FLOAT(OFS_RETURN) = 2;
return;
}
- PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, PRVM_serveredictvector(viewee, absmin), PRVM_serveredictvector(viewee, absmax));
+ VectorCopy(PRVM_serveredictvector(viewee, absmin), absmin);
+ VectorCopy(PRVM_serveredictvector(viewee, absmax), absmax);
+ PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, absmin, absmax);
#else
// using fat PVS like FTEQW does (slow)
- if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ if(!sv.worldmodel || !sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
{
// no PVS support on this worldmodel... darn
PRVM_G_FLOAT(OFS_RETURN) = 3;
PRVM_G_FLOAT(OFS_RETURN) = 2;
return;
}
- PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, PRVM_serveredictvector(viewee, absmin), PRVM_serveredictvector(viewee, absmax));
+ VectorCopy(PRVM_serveredictvector(viewee, absmin), absmin);
+ VectorCopy(PRVM_serveredictvector(viewee, absmax), absmax);
+ PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, absmin, absmax);
#endif
}
old = host_client;
host_client = svs.clients + entnum-1;
- Host_ClientCommands ("%s", string);
+ SV_ClientCommands ("%s", string);
host_client = old;
}
else
chainfield = prog->fieldoffsets.chain;
if (chainfield < 0)
- prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
+ prog->error_cmd("VM_SV_findradius: %s doesnt have the specified chain field !", prog->name);
chain = (prvm_edict_t *)prog->edicts;
// (note: this is the reason you can't blow up fallen zombies)
if (PRVM_serveredictfloat(ent, solid) == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
continue;
- // LordHavoc: compare against bounding box rather than center so it
+ // LadyHavoc: compare against bounding box rather than center so it
// doesn't miss large objects, and use DotProduct instead of Length
// for a major speedup
VectorSubtract(org, PRVM_serveredictvector(ent, origin), eorg);
VM_RETURN_EDICT(chain);
}
+/*
+=================
+VM_SV_findbox
+
+Returns a chain of entities that are touching a box (a simpler findradius); supports DP_QC_FINDCHAIN_TOFIELD
+
+findbox (mins, maxs)
+=================
+*/
+static void VM_SV_findbox(prvm_prog_t *prog)
+{
+ prvm_edict_t *chain;
+ int i, numtouchedicts;
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
+ int chainfield;
+
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findbox);
+
+ if(prog->argc == 3)
+ chainfield = PRVM_G_INT(OFS_PARM2);
+ else
+ chainfield = prog->fieldoffsets.chain;
+ if (chainfield < 0)
+ prog->error_cmd("VM_SV_findbox: %s doesnt have the specified chain field !", prog->name);
+
+ chain = (prvm_edict_t *)prog->edicts;
+
+ numtouchedicts = SV_EntitiesInBox(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), MAX_EDICTS, touchedicts);
+ if (numtouchedicts > MAX_EDICTS)
+ {
+ // this never happens
+ Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+ numtouchedicts = MAX_EDICTS;
+ }
+ for (i = 0; i < numtouchedicts; ++i)
+ {
+ prog->xfunction->builtinsprofile++;
+ PRVM_EDICTFIELDEDICT(touchedicts[i], chainfield) = PRVM_EDICT_TO_PROG(chain);
+ chain = touchedicts[i];
+ }
+
+ VM_RETURN_EDICT(chain);
+}
+
static void VM_SV_precache_sound(prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
vec3_t move;
mfunction_t *oldf;
int oldself;
- qboolean settrace;
+ qbool settrace;
VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
VM_Warning(prog, "walkmove: can not modify world entity\n");
return;
}
- if (ent->priv.server->free)
+ if (ent->free)
{
VM_Warning(prog, "walkmove: can not modify free entity\n");
return;
void() droptofloor
===============
*/
-
+inline static qbool droptofloor_bsp_failcond(trace_t *trace)
+{
+ if (sv.worldmodel->brush.isq3bsp || sv.worldmodel->brush.isq2bsp)
+ return trace->startsolid;
+ else
+ return trace->allsolid || trace->fraction == 1;
+}
static void VM_SV_droptofloor(prvm_prog_t *prog)
{
- prvm_edict_t *ent;
- vec3_t end;
- trace_t trace;
+ prvm_edict_t *ent;
+ vec3_t end;
+ trace_t trace;
VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
VM_Warning(prog, "droptofloor: can not modify world entity\n");
return;
}
- if (ent->priv.server->free)
+ if (ent->free)
{
VM_Warning(prog, "droptofloor: can not modify free entity\n");
return;
}
- VectorCopy (PRVM_serveredictvector(ent, origin), end);
- end[2] -= 256;
-
if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
-
- trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
- if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
- {
- vec3_t offset, org;
- VectorSet(offset, 0.5f * (PRVM_serveredictvector(ent, mins)[0] + PRVM_serveredictvector(ent, maxs)[0]), 0.5f * (PRVM_serveredictvector(ent, mins)[1] + PRVM_serveredictvector(ent, maxs)[1]), PRVM_serveredictvector(ent, mins)[2]);
- VectorAdd(PRVM_serveredictvector(ent, origin), offset, org);
- trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
- VectorSubtract(trace.endpos, offset, trace.endpos);
- if (trace.startsolid)
+ {
+ int n = PHYS_NudgeOutOfSolid(prog, ent);
+ if (!n)
+ VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid_nudgetocorrect COULD NOT FIX badly placed entity \"%s\" before drop\n", PRVM_gameedictvector(ent, origin)[0], PRVM_gameedictvector(ent, origin)[1], PRVM_gameedictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
+ else if (n > 0)
+ VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid_nudgetocorrect FIXED badly placed entity \"%s\" before drop\n", PRVM_gameedictvector(ent, origin)[0], PRVM_gameedictvector(ent, origin)[1], PRVM_gameedictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
+ }
+
+ VectorCopy (PRVM_serveredictvector(ent, origin), end);
+ if (sv.worldmodel->brush.isq3bsp)
+ end[2] -= 4096;
+ else if (sv.worldmodel->brush.isq2bsp)
+ end[2] -= 128;
+ else
+ end[2] -= 256; // Quake, QuakeWorld
+
+ /* bones_was_here: not using SV_GenericHitSuperContentsMask(ent) anymore because it was setting:
+ * items: SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY
+ * monsters: SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP
+ * explobox: SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE
+ * which caused (startsolid == true) when, for example, a health was touching a monster.
+ * Changing MOVE_NORMAL also fixes that, but other engines are using MOVE_NORMAL here.
+ */
+ trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value);
+ if (droptofloor_bsp_failcond(&trace))
+ {
+ if (sv_gameplayfix_droptofloorstartsolid.integer)
{
- Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
- SV_LinkEdict(ent);
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
- PRVM_serveredictedict(ent, groundentity) = 0;
- PRVM_G_FLOAT(OFS_RETURN) = 1;
+ vec3_t offset, org;
+
+ offset[0] = 0.5f * (PRVM_serveredictvector(ent, mins)[0] + PRVM_serveredictvector(ent, maxs)[0]);
+ offset[1] = 0.5f * (PRVM_serveredictvector(ent, mins)[1] + PRVM_serveredictvector(ent, maxs)[1]);
+ offset[2] = PRVM_serveredictvector(ent, mins)[2];
+ VectorAdd(PRVM_serveredictvector(ent, origin), offset, org);
+ VectorAdd(end, offset, end);
+
+ trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value);
+ if (droptofloor_bsp_failcond(&trace))
+ {
+ VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid COULD NOT FIX badly placed entity \"%s\"\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
+ return;
+ }
+ VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid FIXED badly placed entity \"%s\"\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
+ VectorSubtract(trace.endpos, offset, PRVM_serveredictvector(ent, origin));
+
+ // only because we dropped it without considering its bbox
+ if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
+ PHYS_NudgeOutOfSolid(prog, ent);
}
- else if (trace.fraction < 1)
+ else
{
- Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
- VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
- SV_LinkEdict(ent);
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
- PRVM_serveredictedict(ent, 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;
+ VM_Warning(prog, "droptofloor at \"%f %f %f\": badly placed entity \"%s\", startsolid: %d allsolid: %d\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)), trace.startsolid, trace.allsolid);
+ return;
}
}
else
- {
- if (trace.fraction != 1)
- {
- if (trace.fraction < 1)
- VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
- SV_LinkEdict(ent);
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
- PRVM_serveredictedict(ent, 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;
- }
- }
+ VectorCopy(trace.endpos, PRVM_serveredictvector(ent, origin));
+
+ SV_LinkEdict(ent);
+ PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
+ PRVM_serveredictedict(ent, 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;
}
/*
*/
static void VM_SV_pointcontents(prvm_prog_t *prog)
{
+ vec3_t point;
VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
- PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point);
+ PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(SV_PointSuperContents(point));
}
/*
VM_Warning(prog, "aim: can not use world entity\n");
return;
}
- if (ent->priv.server->free)
+ if (ent->free)
{
VM_Warning(prog, "aim: can not use free entity\n");
return;
// try sending a trace straight
VectorCopy (PRVM_serverglobalvector(v_forward), dir);
VectorMA (start, 2048, dir, end);
- tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, 0, collision_extendmovelength.value);
if (tr.ent && PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), takedamage) == DAMAGE_AIM
&& (!teamplay.integer || PRVM_serveredictfloat(ent, team) <=0 || PRVM_serveredictfloat(ent, team) != PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), team)) )
{
dist = DotProduct (dir, PRVM_serverglobalvector(v_forward));
if (dist < bestdist)
continue; // to far to turn
- tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, 0, collision_extendmovelength.value);
if (tr.ent == check)
{ // can shoot at this one
bestdist = dist;
case MSG_ONE:
ent = PRVM_PROG_TO_EDICT(PRVM_serverglobaledict(msg_entity));
entnum = PRVM_NUM_FOR_EDICT(ent);
- if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
+ if (entnum < 1 || entnum > svs.maxclients)
{
VM_Warning(prog, "WriteDest: tried to write to non-client\n");
return &sv.reliable_datagram;
}
+ else if (!svs.clients[entnum-1].active)
+ {
+ VM_Warning(prog, "WriteDest: tried to write to a disconnected client\n");
+ return &sv.reliable_datagram;
+ }
+ else if (!svs.clients[entnum-1].netconnection)
+ {
+ VM_Warning(prog, "WriteDest: tried to write to a bot client\n");
+ return &sv.reliable_datagram;
+ }
else
return &svs.clients[entnum-1].netconnection->message;
VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
imgname = PRVM_G_STRING(OFS_PARM1);
- size = (int) PRVM_G_FLOAT(OFS_PARM2);
+ size = (size_t) PRVM_G_FLOAT(OFS_PARM2);
if(size > 65535)
size = 65535;
if(Image_Compress(imgname, size, &buf, &size))
{
// actual picture
- MSG_WriteShort(WriteDest(prog), size);
- SZ_Write(WriteDest(prog), (unsigned char *) buf, size);
+ MSG_WriteShort(WriteDest(prog), (int)size);
+ SZ_Write(WriteDest(prog), (unsigned char *) buf, (int)size);
}
else
{
VM_Warning(prog, "makestatic: can not modify world entity\n");
return;
}
- if (ent->priv.server->free)
+ if (ent->free)
{
VM_Warning(prog, "makestatic: can not modify free entity\n");
return;
if (PRVM_serveredictfloat(ent, modelindex) >= 256 || PRVM_serveredictfloat(ent, frame) >= 256)
large = true;
- if (large)
+ if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
{
- MSG_WriteByte (&sv.signon,svc_spawnstatic2);
+ MSG_WriteByte (&sv.signon,svc_spawnstatic);
MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex));
- MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
+ MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
}
- else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ else if (large)
{
- MSG_WriteByte (&sv.signon,svc_spawnstatic);
+ MSG_WriteByte (&sv.signon,svc_spawnstatic2);
MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex));
- MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
+ MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
}
else
{
static void VM_SV_getlight(prvm_prog_t *prog)
{
vec3_t ambientcolor, diffusecolor, diffusenormal;
- vec_t *p;
+ vec3_t p;
VM_SAFEPARMCOUNT(1, VM_SV_getlight);
- p = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), p);
VectorClear(ambientcolor);
VectorClear(diffusecolor);
VectorClear(diffusenormal);
typedef struct
{
- unsigned char type; // 1/2/8 or other value if isn't used
+ unsigned char type; // 1/2/8 or 0 to indicate unused
int fieldoffset;
}customstat_t;
-static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
+static customstat_t vm_customstats[MAX_CL_STATS]; // matches the regular stat numbers, but only MIN_VM_STAT to MAX_VM_STAT range is used if things are working properly (can register stats from MAX_VM_STAT to MAX_CL_STATS but will warn)
static int vm_customstats_last;
void VM_CustomStats_Clear (void)
{
- if(vm_customstats)
- {
- Z_Free(vm_customstats);
- vm_customstats = NULL;
- vm_customstats_last = -1;
- }
+ memset(vm_customstats, 0, sizeof(vm_customstats));
+ vm_customstats_last = -1;
}
void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
prvm_prog_t *prog = SVVM_prog;
int i;
char s[17];
+ union {
+ int i;
+ float f;
+ } u;
- if(!vm_customstats)
- return;
-
- for(i=0; i<vm_customstats_last+1 ;i++)
+ for(i=MIN_VM_STAT; i<=vm_customstats_last ;i++)
{
if(!vm_customstats[i].type)
continue;
case 1:
memset(s, 0, 17);
strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
- stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
- stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
- stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
- stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
+ stats[i] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
+ stats[i+1] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
+ stats[i+2] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
+ stats[i+3] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
break;
//float field sent as-is
case 8:
- stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
+ // can't directly use PRVM_E_INT on the field because it may be PRVM_64 and a double is not the representation we want to send
+ u.f = PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
+ stats[i] = u.i;
break;
//integer value of float field
case 2:
- stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
+ stats[i] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
break;
default:
break;
}
}
+extern cvar_t sv_gameplayfix_customstats;
+
// void(float index, float type, .void field) SV_AddStat = #232;
// Set up an auto-sent player stat.
// Client's get thier own fields sent to them. Index may not be less than 32.
// 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
static void VM_SV_AddStat(prvm_prog_t *prog)
{
- int off, i;
- unsigned char type;
+ int off, i, type;
VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
- if(!vm_customstats)
- {
- vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
- if(!vm_customstats)
- {
- VM_Warning(prog, "PF_SV_AddStat: not enough memory\n");
- return;
- }
- }
i = (int)PRVM_G_FLOAT(OFS_PARM0);
type = (int)PRVM_G_FLOAT(OFS_PARM1);
off = PRVM_G_INT (OFS_PARM2);
- i -= 32;
- if(i < 0)
+ switch (type)
{
- VM_Warning(prog, "PF_SV_AddStat: index may not be less than 32\n");
+ case 1:
+ case 2:
+ case 8:
+ break;
+ default:
+ VM_Warning(prog, "PF_SV_AddStat: unrecognized type %i - supported types are 1 (string up to 16 bytes, takes 4 stat slots), 2 (truncate to int32), 8 (send as float)", type);
return;
}
- if(i >= (MAX_CL_STATS-32))
+
+ if (i < 0)
+ {
+ VM_Warning(prog, "PF_SV_AddStat: index (%i) may not be less than %i\n", i, MIN_VM_STAT);
+ return;
+ }
+
+ if (i >= MAX_CL_STATS)
{
- VM_Warning(prog, "PF_SV_AddStat: index >= MAX_CL_STATS\n");
+ VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_CL_STATS (%i), not supported by protocol, and AddStat beyond MAX_VM_STAT (%i) conflicts with engine MOVEVARS\n", i, MAX_CL_STATS, MAX_VM_STAT);
return;
}
- if(i > (MAX_CL_STATS-32-4) && type == 1)
+
+ if (i > (MAX_CL_STATS - 4) && type == 1)
{
- VM_Warning(prog, "PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
+ VM_Warning(prog, "PF_SV_AddStat: index (%i) > (MAX_CL_STATS (%i) - 4) with string type won't fit in the protocol, and AddStat beyond MAX_VM_STAT conflicts with engine MOVEVARS\n", i, MAX_CL_STATS);
return;
}
+
+ // these are hazardous to override but sort of allowed if one wants to be adventurous... and enjoys warnings.
+ if (i < MIN_VM_STAT)
+ VM_Warning(prog, "PF_SV_AddStat: index (%i) < MIN_VM_STAT (%i) may conflict with engine stats - allowed, but this may break things\n", i, MIN_VM_STAT);
+ else if (i >= MAX_VM_STAT && !sv_gameplayfix_customstats.integer)
+ VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_VM_STAT (%i) conflicts with engine stats - allowed, but this may break slowmo and stuff\n", i, MAX_VM_STAT);
+ else if (i > (MAX_VM_STAT - 4) && type == 1 && !sv_gameplayfix_customstats.integer)
+ VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_VM_STAT (%i) - 4 with string type won't fit within MAX_VM_STAT, thus conflicting with engine stats - allowed, but this may break slowmo and stuff\n", i, MAX_VM_STAT);
+
vm_customstats[i].type = type;
vm_customstats[i].fieldoffset = off;
if(vm_customstats_last < i)
VM_Warning(prog, "copyentity: can not read world entity\n");
return;
}
- if (in->priv.server->free)
+ if (in->free)
{
VM_Warning(prog, "copyentity: can not read free entity\n");
return;
VM_Warning(prog, "copyentity: can not modify world entity\n");
return;
}
- if (out->priv.server->free)
+ if (out->free)
{
VM_Warning(prog, "copyentity: can not modify free entity\n");
return;
}
- memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
+ memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t));
+
SV_LinkEdict(out);
}
{
int i;
const char *s;
+ vec3_t org;
VM_SAFEPARMCOUNT(5, VM_SV_effect);
s = PRVM_G_STRING(OFS_PARM1);
if (!s[0])
return;
}
- SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+ SV_StartEffect(org, i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
}
static void VM_SV_te_blood(prvm_prog_t *prog)
}
//void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
-//this function originally written by KrimZon, made shorter by LordHavoc
+//this function originally written by KrimZon, made shorter by LadyHavoc
static void VM_SV_clientcommand(prvm_prog_t *prog)
{
client_t *temp_client;
temp_client = host_client;
host_client = svs.clients + i;
- Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client, true);
+ Cmd_ExecuteString(cmd_serverfromclient, PRVM_G_STRING(OFS_PARM1), src_client, true);
host_client = temp_client;
}
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);
- dp_model_t *model;
+ model_t *model;
int tagindex;
VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
VM_Warning(prog, "setattachment: can not modify world entity\n");
return;
}
- if (e->priv.server->free)
+ if (e->free)
{
VM_Warning(prog, "setattachment: can not modify free entity\n");
return;
static int SV_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
{
int r;
- dp_model_t *model;
+ model_t *model;
*tagname = NULL;
*parentindex = 0;
return 1;
}
-void SV_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
+void SV_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qbool viewmatrix)
{
float scale;
float pitchsign = 1;
static int SV_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
{
- dp_model_t *model;
+ model_t *model;
if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
{
VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
// 3 - null or non-precached model
// 4 - no tags with requested index
// 5 - runaway loop at attachment chain
-extern cvar_t cl_bob;
-extern cvar_t cl_bobcycle;
-extern cvar_t cl_bobup;
static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
{
int ret;
int modelindex, attachloop;
matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
- dp_model_t *model;
+ model_t *model;
*out = identitymatrix; // warnings and errors return identical matrix
if (ent == prog->edicts)
return 1;
- if (ent->priv.server->free)
+ if (ent->free)
return 2;
modelindex = (int)PRVM_serveredictfloat(ent, modelindex);
SV_GetEntityMatrix(prog, ent, &entitymatrix, true);
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
-
- /*
- // Cl_bob, ported from rendering code
- if (PRVM_serveredictfloat(ent, health) > 0 && cl_bob.value && cl_bobcycle.value)
- {
- 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(PRVM_serveredictvector(ent, velocity)[0]*PRVM_serveredictvector(ent, velocity)[0] + PRVM_serveredictvector(ent, velocity)[1]*PRVM_serveredictvector(ent, velocity)[1])*cl_bob.value;
- bob = bob*0.3 + bob*0.7*cycle;
- Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
- }
- */
}
return 0;
}
VM_Warning(prog, "VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
return;
}
- if (ent->priv.server->free)
+ if (ent->free)
{
VM_Warning(prog, "VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
return;
int parentindex;
const char *tagname;
int returncode;
- vec3_t fo, le, up, trans;
- const dp_model_t *model;
+ vec3_t forward, left, up, origin;
+ const model_t *model;
VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
returncode = SV_GetTagMatrix(prog, &tag_matrix, e, tagindex);
- Matrix4x4_ToVectors(&tag_matrix, PRVM_serverglobalvector(v_forward), le, PRVM_serverglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
- VectorScale(le, -1, PRVM_serverglobalvector(v_right));
+ Matrix4x4_ToVectors(&tag_matrix, forward, left, up, origin);
+ VectorCopy(forward, PRVM_serverglobalvector(v_forward));
+ VectorNegate(left, PRVM_serverglobalvector(v_right));
+ VectorCopy(up, PRVM_serverglobalvector(v_up));
+ VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
model = SV_GetModelFromEdict(e);
VM_GenerateFrameGroupBlend(prog, e->priv.server->framegroupblend, e);
VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model, sv.time);
VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
SV_GetExtendedTagInfo(prog, e, tagindex, &parentindex, &tagname, &tag_localmatrix);
- Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
+ Matrix4x4_ToVectors(&tag_localmatrix, forward, left, up, origin);
PRVM_serverglobalfloat(gettaginfo_parent) = parentindex;
PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
- VectorCopy(trans, PRVM_serverglobalvector(gettaginfo_offset));
- VectorCopy(fo, PRVM_serverglobalvector(gettaginfo_forward));
- VectorScale(le, -1, PRVM_serverglobalvector(gettaginfo_right));
+ VectorCopy(forward, PRVM_serverglobalvector(gettaginfo_forward));
+ VectorNegate(left, PRVM_serverglobalvector(gettaginfo_right));
VectorCopy(up, PRVM_serverglobalvector(gettaginfo_up));
+ VectorCopy(origin, PRVM_serverglobalvector(gettaginfo_offset));
switch(returncode)
{
}
oldhostclient = host_client;
host_client = svs.clients + clientnum;
- SV_DropClient(false);
+ SV_DropClient(false, "Client dropped");
host_client = oldhostclient;
}
VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
if (clientnum < 0 || clientnum >= svs.maxclients)
- PRVM_G_FLOAT(OFS_RETURN) = 3;
+ PRVM_G_FLOAT(OFS_RETURN) = 3; // CLIENTTYPE_NOTACLIENT
else if (!svs.clients[clientnum].active)
- PRVM_G_FLOAT(OFS_RETURN) = 0;
+ PRVM_G_FLOAT(OFS_RETURN) = 0; // CLIENTTYPE_DISCONNECTED
else if (svs.clients[clientnum].netconnection)
- PRVM_G_FLOAT(OFS_RETURN) = 1;
+ PRVM_G_FLOAT(OFS_RETURN) = 1; // CLIENTTYPE_REAL
else
- PRVM_G_FLOAT(OFS_RETURN) = 2;
+ PRVM_G_FLOAT(OFS_RETURN) = 2; // CLIENTTYPE_BOT
}
/*
static void VM_SV_setmodelindex(prvm_prog_t *prog)
{
prvm_edict_t *e;
- dp_model_t *mod;
+ model_t *mod;
int i;
VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
VM_Warning(prog, "setmodelindex: can not modify world entity\n");
return;
}
- if (e->priv.server->free)
+ if (e->free)
{
VM_Warning(prog, "setmodelindex: can not modify free entity\n");
return;
// #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
static void VM_SV_trailparticles(prvm_prog_t *prog)
{
+ vec3_t start, end;
VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
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));
- MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
- MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), start);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM3), end);
+ MSG_WriteVector(&sv.datagram, start, sv.protocol);
+ MSG_WriteVector(&sv.datagram, end, sv.protocol);
SV_FlushBroadcastMessages();
}
SV_FlushBroadcastMessages();
}
+qbool SV_VM_ConsoleCommand (const char *text)
+{
+ prvm_prog_t *prog = SVVM_prog;
+ return PRVM_ConsoleCommand(prog, text, &prog->funcoffsets.ConsoleCmd, true, PRVM_EDICT_TO_PROG(sv.world.prog->edicts), sv.time, !(!sv.active || !prog || !prog->loaded), "QC function ConsoleCmd is missing");
+}
+
+// #352 void(string cmdname) registercommand (EXT_CSQC)
+static void VM_SV_registercommand (prvm_prog_t *prog)
+{
+ VM_SAFEPARMCOUNT(1, VM_SV_registercmd);
+ Cmd_AddCommand(CF_SERVER, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
+}
+
//PF_setpause, // void(float pause) setpause = #531;
static void VM_SV_setpause(prvm_prog_t *prog) {
int pauseValue;
pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
if (pauseValue != 0) { //pause the game
sv.paused = 1;
- sv.pausedstart = realtime;
+ sv.pausedstart = host.realtime;
} else { //disable pause, in case it was enabled
if (sv.paused != 0) {
sv.paused = 0;
static void VM_SV_skel_create(prvm_prog_t *prog)
{
int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
- dp_model_t *model = SV_GetModelByIndex(modelindex);
+ model_t *model = SV_GetModelByIndex(modelindex);
skeleton_t *skeleton;
int i;
PRVM_G_FLOAT(OFS_RETURN) = 0;
float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
- dp_model_t *model = SV_GetModelByIndex(modelindex);
- float blendfrac;
+ model_t *model = SV_GetModelByIndex(modelindex);
int numblends;
int bonenum;
int blendindex;
framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
frameblend_t frameblend[MAX_FRAMEBLENDS];
- matrix4x4_t blendedmatrix;
+ matrix4x4_t bonematrix;
matrix4x4_t matrix;
PRVM_G_FLOAT(OFS_RETURN) = 0;
if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
lastbone = min(lastbone, skeleton->model->num_bones - 1);
VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, sv.time);
- blendfrac = 1.0f - retainfrac;
for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
- frameblend[numblends].lerp *= blendfrac;
+ ;
for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
{
- memset(&blendedmatrix, 0, sizeof(blendedmatrix));
- Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
+ memset(&bonematrix, 0, sizeof(bonematrix));
for (blendindex = 0;blendindex < numblends;blendindex++)
{
Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
- Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
+ Matrix4x4_Accumulate(&bonematrix, &matrix, frameblend[blendindex].lerp);
}
- skeleton->relativetransforms[bonenum] = blendedmatrix;
+ Matrix4x4_Normalize3(&bonematrix, &bonematrix);
+ Matrix4x4_Interpolate(&skeleton->relativetransforms[bonenum], &bonematrix, &skeleton->relativetransforms[bonenum], retainfrac);
}
PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
}
static void VM_SV_frameforname(prvm_prog_t *prog)
{
int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
- dp_model_t *model = SV_GetModelByIndex(modelindex);
+ model_t *model = SV_GetModelByIndex(modelindex);
const char *name = PRVM_G_STRING(OFS_PARM1);
int i;
PRVM_G_FLOAT(OFS_RETURN) = -1;
static void VM_SV_frameduration(prvm_prog_t *prog)
{
int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
- dp_model_t *model = SV_GetModelByIndex(modelindex);
+ model_t *model = SV_GetModelByIndex(modelindex);
int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
PRVM_G_FLOAT(OFS_RETURN) = 0;
if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
VM_break, // #6 void() break (QUAKE)
VM_random, // #7 float() random (QUAKE)
-VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
+VM_SV_sound, // #8 void(entity e, float chan, string samp, float volume[, float atten[, float pitchchange[, float flags]]]) sound (QUAKE)
VM_normalize, // #9 vector(vector v) normalize (QUAKE)
VM_error, // #10 void(string e) error (QUAKE)
VM_objerror, // #11 void(string e) objerror (QUAKE)
VM_fabs, // #43 float(float f) fabs (QUAKE)
VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
VM_cvar, // #45 float(string s) cvar (QUAKE)
-VM_localcmd, // #46 void(string s) localcmd (QUAKE)
+VM_localcmd_server, // #46 void(string s) localcmd (QUAKE)
VM_nextent, // #47 entity(entity e) nextent (QUAKE)
VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
-VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
+VM_strcat, // #115 string(string s, string...) strcat (FRIK_FILE)
VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
VM_stov, // #117 vector(string) stov (FRIK_FILE)
VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
NULL, // #242
NULL, // #243
NULL, // #244
-NULL, // #245
+VM_modulo, // #245
NULL, // #246
NULL, // #247
NULL, // #248
NULL, // #349 float() isdemo (EXT_CSQC)
VM_isserver, // #350 float() isserver (EXT_CSQC)
NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
-NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
+VM_SV_registercommand, // #352 void(string cmdname) registercommand (EXT_CSQC)
VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
NULL, // #355
NULL, // #397
NULL, // #398
NULL, // #399
-// LordHavoc's range #400-#499
+// LadyHavoc's range #400-#499
VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
VM_log, // #532
VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
-NULL, // #535
-NULL, // #536
-NULL, // #537
-NULL, // #538
+VM_buf_loadfile, // #535 float(string filename, float bufhandle) buf_loadfile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_buf_writefile, // #536 float(float filehandle, float bufhandle, float startpos, float numstrings) buf_writefile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_bufstr_find, // #537 float(float bufhandle, string match, float matchrule, float startpos) bufstr_find (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_matchpattern, // #538 float(string s, string pattern, float matchrule) matchpattern (DP_QC_STRINGBUFFERS_EXT_WIP)
NULL, // #539
VM_physics_enable, // #540 void(entity e, float physics_enabled) physics_enable = #540; (DP_PHYSICS_ODE)
VM_physics_addforce, // #541 void(entity e, vector force, vector relative_ofs) physics_addforce = #541; (DP_PHYSICS_ODE)
NULL, // #563
NULL, // #564
NULL, // #565
-NULL, // #566
-NULL, // #567
+VM_SV_findbox, // #566 entity(vector mins, vector maxs) findbox = #566; (DP_QC_FINDBOX)
+VM_nudgeoutofsolid, // #567 float(entity ent) nudgeoutofsolid = #567; (DP_QC_NUDGEOUTOFSOLID)
NULL, // #568
NULL, // #569
NULL, // #570
NULL, // #638
VM_digest_hex, // #639
NULL, // #640
+NULL, // #641
+VM_coverage, // #642
+NULL, // #643
};
const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
void SVVM_reset_cmd(prvm_prog_t *prog)
{
World_End(&sv.world);
- if(PRVM_serverfunction(SV_Shutdown))
+
+ if(prog->loaded && PRVM_serverfunction(SV_Shutdown))
{
func_t s = PRVM_serverfunction(SV_Shutdown);
PRVM_serverglobalfloat(time) = sv.time;