From d6dc394db4b00c4e8aa8472b042e30561d2c90fb Mon Sep 17 00:00:00 2001 From: Reki Date: Tue, 6 Apr 2021 12:56:54 -0400 Subject: [PATCH] Added various extensions: csqcflags, solid ssqc objects, input_impulse, and some others --- .gitignore | 2 + .travis-script-xonotic.sh | 4 +- cl_collision.c | 120 +++++++++++++++++++++++++++++++++++++- cl_ents5.c | 14 +++++ cl_ents_nq.c | 2 + cl_input.c | 2 +- clvm_cmds.c | 14 ++++- csprogs.c | 7 +++ makefile.inc | 2 +- protocol.c | 3 +- protocol.h | 14 ++++- prvm_offsets.h | 6 ++ sbar.c | 2 +- server.h | 1 + snd_main.c | 8 ++- sound.h | 1 + sv_ents5.c | 16 +++++ sv_ents_nq.c | 5 +- sv_phys.c | 13 +++-- sv_send.c | 8 +++ sv_user.c | 1 - svvm_cmds.c | 11 +++- 22 files changed, 231 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 79a6843b..cf533dd4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ darkplaces-agl darkplaces-glx darkplaces-sdl darkplaces-dedicated +doombringer-lx +doombringer-lx-ded gmon.out *.ncb *.opt diff --git a/.travis-script-xonotic.sh b/.travis-script-xonotic.sh index d511662b..78acf5db 100755 --- a/.travis-script-xonotic.sh +++ b/.travis-script-xonotic.sh @@ -73,7 +73,7 @@ for os in "$@"; do DP_LINK_ODE=dlopen DP_LINK_ZLIB=dlopen' maketargets='release' - outputs='darkplaces-sdl.exe:darkplaces-x86.exe darkplaces-dedicated.exe:darkplaces-x86-dedicated.exe' + outputs='doombringer.exe:darkplaces-x86.exe darkplaces-dedicated.exe:darkplaces-x86-dedicated.exe' ;; win64) chroot= @@ -91,7 +91,7 @@ for os in "$@"; do DP_LINK_ODE=dlopen DP_LINK_ZLIB=dlopen' maketargets='release' - outputs='darkplaces-sdl.exe:darkplaces.exe darkplaces-dedicated.exe:darkplaces-dedicated.exe' + outputs='doombringer.exe:darkplaces.exe darkplaces-dedicated.exe:darkplaces-dedicated.exe' ;; osx) chroot= diff --git a/cl_collision.c b/cl_collision.c index 2cd3a619..68e47b62 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -282,12 +282,15 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL; clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0; - // collide against network entities if (hitnetworkbrushmodels) { for (i = 0;i < cl.num_brushmodel_entities;i++) { + entity_state_t *ent_fields = &cl.entities[cl.brushmodel_entities[i]].state_current; + if (ent_fields->solid == SOLID_NOT) + continue; + entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render; if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs)) continue; @@ -296,6 +299,36 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int *hitnetworkentity = cl.brushmodel_entities[i]; Collision_CombineTraces(&cliptrace, &trace, NULL, true); } + + + + + vec3_t origin, entmins, entmaxs; + matrix4x4_t entmatrix, entinversematrix; + + for (i = cl.maxclients;i < cl.num_entities;i++) + { + entity_render_t *ent = &cl.entities[i].render; + entity_state_t *ent_fields = &cl.entities[i].state_current; + + // don't hit players that don't exist + if (!cl.entities_active[i]) + continue; + if (ent_fields->solid == SOLID_NOT || ent_fields->solid == SOLID_NOTNETWORKED) + continue; + + Matrix4x4_OriginFromMatrix(&ent->matrix, origin); + VectorAdd(origin, ent_fields->mins, entmins); + VectorAdd(origin, ent_fields->maxs, entmaxs); + if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs)) + continue; + Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]); + Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]); + Collision_ClipPointToGenericEntity(&trace, NULL, NULL, NULL, ent_fields->mins, ent_fields->maxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask); + if (cliptrace.fraction > trace.fraction && hitnetworkentity) + *hitnetworkentity = i; + Collision_CombineTraces(&cliptrace, &trace, NULL, false); + } } // collide against player entities @@ -314,14 +347,17 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int for (i = 1;i <= cl.maxclients;i++) { entity_render_t *ent = &cl.entities[i].render; - + entity_state_t *ent_fields = &cl.entities[i].state_current; + // don't hit ourselves if (i == cl.playerentity) continue; - + // don't hit players that don't exist if (!cl.entities_active[i]) continue; + if (ent_fields->solid == SOLID_NOT) + continue; if (!cl.scores[i-1].name[0]) continue; @@ -512,6 +548,10 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ { for (i = 0;i < cl.num_brushmodel_entities;i++) { + entity_state_t *ent_fields = &cl.entities[cl.brushmodel_entities[i]].state_current; + if (ent_fields->solid == SOLID_NOT) + continue; + entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render; if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs)) continue; @@ -520,6 +560,37 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ *hitnetworkentity = cl.brushmodel_entities[i]; Collision_CombineTraces(&cliptrace, &trace, NULL, true); } + + + + + + vec3_t origin, entmins, entmaxs; + matrix4x4_t entmatrix, entinversematrix; + + for (i = cl.maxclients;i < cl.num_entities;i++) + { + entity_render_t *ent = &cl.entities[i].render; + entity_state_t *ent_fields = &cl.entities[i].state_current; + + // don't hit players that don't exist + if (!cl.entities_active[i]) + continue; + if (ent_fields->solid == SOLID_NOT || ent_fields->solid == SOLID_NOTNETWORKED) + continue; + + Matrix4x4_OriginFromMatrix(&ent->matrix, origin); + VectorAdd(origin, ent_fields->mins, entmins); + VectorAdd(origin, ent_fields->maxs, entmaxs); + if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs)) + continue; + Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]); + Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]); + Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, ent_fields->mins, ent_fields->maxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces); + if (cliptrace.fraction > trace.fraction && hitnetworkentity) + *hitnetworkentity = i; + Collision_CombineTraces(&cliptrace, &trace, NULL, false); + } } // collide against player entities @@ -538,6 +609,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ for (i = 1;i <= cl.maxclients;i++) { entity_render_t *ent = &cl.entities[i].render; + entity_state_t *ent_fields = &cl.entities[i].state_current; // don't hit ourselves if (i == cl.playerentity) @@ -546,6 +618,8 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // don't hit players that don't exist if (!cl.entities_active[i]) continue; + if (ent_fields->solid == SOLID_NOT) + continue; if (!cl.scores[i-1].name[0]) continue; @@ -763,6 +837,10 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co { for (i = 0;i < cl.num_brushmodel_entities;i++) { + entity_state_t *ent_fields = &cl.entities[cl.brushmodel_entities[i]].state_current; + if (ent_fields->solid == SOLID_NOT) + continue; + entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render; if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs)) continue; @@ -771,6 +849,39 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co *hitnetworkentity = cl.brushmodel_entities[i]; Collision_CombineTraces(&cliptrace, &trace, NULL, true); } + + + vec3_t origin, entmins, entmaxs; + matrix4x4_t entmatrix, entinversematrix; + + for (i = cl.maxclients;i < cl.num_entities;i++) + { + entity_render_t *ent = &cl.entities[i].render; + entity_state_t *ent_fields = &cl.entities[i].state_current; + + // don't hit players that don't exist + if (!cl.entities_active[i]) + continue; + if (ent_fields->solid == SOLID_NOT || ent_fields->solid == SOLID_NOTNETWORKED) + continue; + + Matrix4x4_OriginFromMatrix(&ent->matrix, origin); + VectorAdd(origin, ent_fields->mins, entmins); + VectorAdd(origin, ent_fields->maxs, entmaxs); + if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs)) + continue; + Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]); + Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]); + + //if (ent_fields->solid == SOLID_BSP) + // Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend); + //else + Collision_ClipToGenericEntity(&trace, NULL, NULL, NULL, ent_fields->mins, ent_fields->maxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend); + + if (cliptrace.fraction > trace.fraction && hitnetworkentity) + *hitnetworkentity = i; + Collision_CombineTraces(&cliptrace, &trace, NULL, false); + } } // collide against player entities @@ -789,6 +900,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co for (i = 1;i <= cl.maxclients;i++) { entity_render_t *ent = &cl.entities[i].render; + entity_state_t *ent_fields = &cl.entities[i].state_current; // don't hit ourselves if (i == cl.playerentity) @@ -797,6 +909,8 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // don't hit players that don't exist if (!cl.entities_active[i]) continue; + if (ent_fields->solid == SOLID_NOT) + continue; if (!cl.scores[i-1].name[0]) continue; diff --git a/cl_ents5.c b/cl_ents5.c index fceb5b3d..5f2a8f81 100644 --- a/cl_ents5.c +++ b/cl_ents5.c @@ -220,6 +220,20 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number) } if (bits & E5_TRAILEFFECTNUM) s->traileffectnum = (unsigned short) MSG_ReadShort(&cl_message); + if (bits & E5_SOLID) + { + s->solid = MSG_ReadByte(&cl_message); + + if (s->solid != SOLID_NOT && s->solid != SOLID_BSP) + { + s->mins[0] = MSG_ReadCoord32f(&cl_message); + s->mins[1] = MSG_ReadCoord32f(&cl_message); + s->mins[2] = MSG_ReadCoord32f(&cl_message); + s->maxs[0] = MSG_ReadCoord32f(&cl_message); + s->maxs[1] = MSG_ReadCoord32f(&cl_message); + s->maxs[2] = MSG_ReadCoord32f(&cl_message); + } + } bytes = cl_message.readcount - startoffset; diff --git a/cl_ents_nq.c b/cl_ents_nq.c index 0edd34e3..f986b29b 100644 --- a/cl_ents_nq.c +++ b/cl_ents_nq.c @@ -79,8 +79,10 @@ void EntityFrameQuake_ReadEntity(int bits) if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL; if (bits & U_FRAME2) s.frame = (s.frame & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); if (bits & U_MODEL2) s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); + if (bits & U_SOLID) s.solid = MSG_ReadByte(&cl_message); if (bits & U_VIEWMODEL) s.flags |= RENDER_VIEWMODEL; if (bits & U_EXTERIORMODEL) s.flags |= RENDER_EXTERIORMODEL; + // LadyHavoc: to allow playback of the Nehahra movie if (cls.protocol == PROTOCOL_NEHAHRAMOVIE && (bits & U_EXTEND1)) diff --git a/cl_input.c b/cl_input.c index a75495cf..151e9e23 100644 --- a/cl_input.c +++ b/cl_input.c @@ -1818,7 +1818,7 @@ void CL_SendMove(void) // ridiculous value rejection (matches qw) if (cl.cmd.msec > 250) cl.cmd.msec = 100; - cl.cmd.frametime = cl.cmd.msec * (1.0 / 1000.0); + cl.cmd.frametime = cl.cmd.time - (cl.movecmd[1].time);//cl.cmd.msec * (1.0 / 1000.0); switch(cls.protocol) { diff --git a/clvm_cmds.c b/clvm_cmds.c index ff68d4f8..5681d2d0 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -207,7 +207,7 @@ static void VM_CL_sound (prvm_prog_t *prog) else { // 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); + flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED | CHANNELFLAG_FULLVOLUME | CHANNELFLAG_BGMVOLUME); } // sound_starttime exists instead of sound_startposition because in a @@ -708,6 +708,13 @@ static void VM_CL_getlight (prvm_prog_t *prog) VectorCopy(diffusenormal, PRVM_clientglobalvector(getlight_dir)); } + +// DOOMBRINGER extensions + + + + + //============================================================================ //[515]: SCENE MANAGER builtins @@ -2232,6 +2239,7 @@ static void VM_CL_getinputstate (prvm_prog_t *prog) { VectorCopy(cl.movecmd[i].viewangles, PRVM_clientglobalvector(input_angles)); PRVM_clientglobalfloat(input_buttons) = cl.movecmd[i].buttons; // FIXME: this should not be directly exposed to csqc (translation layer needed?) + PRVM_clientglobalfloat(input_impulse) = cl.movecmd[i].impulse; PRVM_clientglobalvector(input_movevalues)[0] = cl.movecmd[i].forwardmove; PRVM_clientglobalvector(input_movevalues)[1] = cl.movecmd[i].sidemove; PRVM_clientglobalvector(input_movevalues)[2] = cl.movecmd[i].upmove; @@ -2304,6 +2312,7 @@ static void VM_CL_runplayerphysics (prvm_prog_t *prog) s.cmd.sidemove = PRVM_clientglobalvector(input_movevalues)[1]; s.cmd.upmove = PRVM_clientglobalvector(input_movevalues)[2]; s.cmd.buttons = PRVM_clientglobalfloat(input_buttons); + s.cmd.impulse = PRVM_clientglobalfloat(input_impulse); s.cmd.frametime = PRVM_clientglobalfloat(input_timelength); s.cmd.jump = (s.cmd.buttons & 2) != 0; s.cmd.crouch = (s.cmd.buttons & 16) != 0; @@ -5036,7 +5045,7 @@ VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_Q VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW) VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT) VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system) -// FrikaC and Telejano range #100-#199 +// FrikaC and Telejano range #100-#179 NULL, // #100 NULL, // #101 NULL, // #102 @@ -5117,6 +5126,7 @@ NULL, // #176 NULL, // #177 NULL, // #178 NULL, // #179 +// DOOMBRINGER range #180-#199 NULL, // #180 NULL, // #181 NULL, // #182 diff --git a/csprogs.c b/csprogs.c index 80666f5e..95b2247d 100644 --- a/csprogs.c +++ b/csprogs.c @@ -234,6 +234,7 @@ static void CSQC_SetGlobals (double frametime) VectorCopy(cl.viewangles, PRVM_clientglobalvector(input_angles)); // // FIXME: this actually belongs into getinputstate().. [12/17/2007 Black] PRVM_clientglobalfloat(input_buttons) = cl.movecmd[0].buttons; + PRVM_clientglobalfloat(input_impulse) = cl.movecmd[0].impulse; VectorSet(PRVM_clientglobalvector(input_movevalues), cl.movecmd[0].forwardmove, cl.movecmd[0].sidemove, cl.movecmd[0].upmove); VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin); VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles); @@ -253,6 +254,12 @@ static void CSQC_SetGlobals (double frametime) PRVM_clientglobalfloat(maxclients) = cl.maxclients; PRVM_clientglobalfloat(player_localentnum) = cl.viewentity; + + char temp[128]; + InfoString_GetValue(cls.userinfo, "*ip", temp, sizeof(temp)); + PRVM_clientglobalstring(server_ip) = PRVM_SetEngineString(prog, temp); + //Con_Printf(PRVM_clientglobalstring(server_ip)); + //Con_Printf("\n"); CSQC_R_RecalcView(); CSQC_END diff --git a/makefile.inc b/makefile.inc index 2fdc966a..88a68f48 100644 --- a/makefile.inc +++ b/makefile.inc @@ -292,7 +292,7 @@ WINDRES ?= windres LDFLAGS_WINSV=$(LDFLAGS_WINCOMMON) $(LIB_CRYPTO) $(LIB_CRYPTO_RIJNDAEL) -mconsole -lwinmm -lws2_32 $(LIB_Z) $(LIB_JPEG) LDFLAGS_WINSDL=$(LDFLAGS_WINCOMMON) $(LIB_CRYPTO) $(LIB_CRYPTO_RIJNDAEL) $(LDFLAGS_UNIXSDL) -lwinmm -lws2_32 $(LIB_Z) $(LIB_JPEG) $(LIB_SND_XMP) EXE_WINSV=darkplaces-dedicated.exe -EXE_WINSDL=darkplaces-sdl.exe +EXE_WINSDL=doombringer.exe EXE_WINSVNEXUIZ=nexuiz-dedicated.exe EXE_WINSDLNEXUIZ=nexuiz-sdl.exe diff --git a/protocol.c b/protocol.c index 8bdb0051..11220c29 100644 --- a/protocol.c +++ b/protocol.c @@ -1,6 +1,6 @@ #include "quakedef.h" -// this is 88 bytes (must match entity_state_t in protocol.h) +// this is 89 bytes (must match entity_state_t in protocol.h) entity_state_t defaultstate = { // ! means this is not sent to client @@ -35,6 +35,7 @@ entity_state_t defaultstate = 0,//unsigned char tagindex; {32, 32, 32},//unsigned char colormod[3]; {32, 32, 32},//unsigned char glowmod[3]; + SOLID_NOTNETWORKED,//unsigned char solid; <-- Added by Reki for DOOMBRINGER }; // LadyHavoc: I own protocol ranges 96, 97, 3500-3599 diff --git a/protocol.h b/protocol.h index 170db5b9..8d5849c6 100644 --- a/protocol.h +++ b/protocol.h @@ -145,7 +145,7 @@ void Protocol_Names(char *buffer, size_t buffersize); #define U_FRAME2 (1<<26) // 1 byte, this is .frame & 0xFF00 (second byte) #define U_MODEL2 (1<<27) // 1 byte, this is .modelindex & 0xFF00 (second byte) #define U_EXTERIORMODEL (1<<28) // causes this model to not be drawn when using a first person view (third person will draw it, first person will not) -#define U_UNUSED29 (1<<29) // future expansion +#define U_SOLID (1<<29) // REKI: Solid state #define U_UNUSED30 (1<<30) // future expansion #define U_EXTEND3 (1<<31) // another byte to follow, future expansion @@ -470,6 +470,9 @@ typedef struct entity_state_s unsigned char tagindex; unsigned char colormod[3]; unsigned char glowmod[3]; + unsigned char solid; + float mins[3]; + float maxs[3]; // LadyHavoc: very big data here :( framegroupblend_t framegroupblend[4]; skeleton_t skeletonobject; @@ -737,6 +740,11 @@ qbool EntityFrame4_WriteFrame(struct sizebuf_s *msg, int maxsize, entityframe4_d // reads a frame from the network stream void EntityFrame4_CL_ReadFrame(void); + +//CSQC Flags +#define CSQCFLAG_SOLIDITY (1<<0) + + // reset all entity fields (typically used if status changed) #define E5_FULLUPDATE (1<<0) // E5_ORIGIN32=0: short[3] = s->origin[0] * 8, s->origin[1] * 8, s->origin[2] * 8 @@ -810,8 +818,8 @@ void EntityFrame4_CL_ReadFrame(void); #define E5_COMPLEXANIMATION (1<<25) // ushort traileffectnum #define E5_TRAILEFFECTNUM (1<<26) -// unused -#define E5_UNUSED27 (1<<27) +// REKI: solid flag for prediction +#define E5_SOLID (1<<27) // unused #define E5_UNUSED28 (1<<28) // unused diff --git a/prvm_offsets.h b/prvm_offsets.h index 97a2defb..e89b058a 100644 --- a/prvm_offsets.h +++ b/prvm_offsets.h @@ -113,6 +113,7 @@ PRVM_DECLARE_clientglobalvector(getlight_ambient) PRVM_DECLARE_clientglobalvector(getlight_diffuse) PRVM_DECLARE_clientglobalvector(getlight_dir) PRVM_DECLARE_clientglobalfloat(input_buttons) +PRVM_DECLARE_clientglobalfloat(input_impulse) PRVM_DECLARE_clientglobalfloat(input_timelength) PRVM_DECLARE_clientglobalfloat(intermission) PRVM_DECLARE_clientglobalfloat(maxclients) @@ -175,6 +176,7 @@ PRVM_DECLARE_clientglobalfloat(trace_startsolid) PRVM_DECLARE_clientglobalfloat(transparent_offset) PRVM_DECLARE_clientglobalstring(gettaginfo_name) PRVM_DECLARE_clientglobalstring(mapname) +PRVM_DECLARE_clientglobalstring(server_ip) PRVM_DECLARE_clientglobalstring(trace_dphittexturename) PRVM_DECLARE_clientglobalvector(dmg_origin) PRVM_DECLARE_clientglobalvector(drawfontscale) @@ -262,6 +264,7 @@ PRVM_DECLARE_field(color) PRVM_DECLARE_field(colormap) PRVM_DECLARE_field(colormod) PRVM_DECLARE_field(contentstransition) +PRVM_DECLARE_field(csqcflags) PRVM_DECLARE_field(crypto_encryptmethod) PRVM_DECLARE_field(crypto_idfp) PRVM_DECLARE_field(crypto_idfp_signed) @@ -471,11 +474,13 @@ PRVM_DECLARE_global(getlight_diffuse) PRVM_DECLARE_global(getlight_dir) PRVM_DECLARE_global(input_angles) PRVM_DECLARE_global(input_buttons) +PRVM_DECLARE_global(input_impulse) PRVM_DECLARE_global(input_movevalues) PRVM_DECLARE_global(input_timelength) PRVM_DECLARE_global(intermission) PRVM_DECLARE_global(killed_monsters) PRVM_DECLARE_global(mapname) +PRVM_DECLARE_global(server_ip) PRVM_DECLARE_global(maxclients) PRVM_DECLARE_global(movevar_accelerate) PRVM_DECLARE_global(movevar_airaccelerate) @@ -652,6 +657,7 @@ PRVM_DECLARE_serverfieldfloat(buttonuse) PRVM_DECLARE_serverfieldfloat(clientcolors) PRVM_DECLARE_serverfieldfloat(clipgroup) PRVM_DECLARE_serverfieldfloat(colormap) +PRVM_DECLARE_serverfieldfloat(csqcflags) PRVM_DECLARE_serverfieldfloat(currentammo) PRVM_DECLARE_serverfieldfloat(cursor_active) PRVM_DECLARE_serverfieldfloat(deadflag) diff --git a/sbar.c b/sbar.c index 6fc6c327..7b5ba210 100644 --- a/sbar.c +++ b/sbar.c @@ -359,7 +359,7 @@ static void sbar_newmap(void) void Sbar_Init (void) { - if(gamemode == GAME_NORMAL) // Workaround so Quake doesn't trample on Xonotic. + if(gamemode == GAME_NORMAL || gamemode == GAME_DOOMBRINGER ) // Workaround so Quake doesn't trample on Xonotic. { Cmd_AddCommand(CF_CLIENT, "+showscores", Sbar_ShowScores_f, "show scoreboard"); Cmd_AddCommand(CF_CLIENT, "-showscores", Sbar_DontShowScores_f, "hide scoreboard"); diff --git a/server.h b/server.h index 9a9a6d9b..7d6ec633 100644 --- a/server.h +++ b/server.h @@ -346,6 +346,7 @@ typedef struct client_s #define SOLID_BSP 4 ///< bsp clip, touch on edge, block // LadyHavoc: corpse code #define SOLID_CORPSE 5 ///< same as SOLID_BBOX, except it behaves as SOLID_NOT against SOLID_SLIDEBOX objects (players/monsters) +#define SOLID_NOTNETWORKED 11 ///< Reki: added this to keep old "assumed" behavior for networked objects // LadyHavoc: physics // VorteX: now these fields are deprecated, as geomtype is more flexible #define SOLID_PHYSICS_BOX 32 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) diff --git a/snd_main.c b/snd_main.c index 3e8d52a8..3daf4ffd 100644 --- a/snd_main.c +++ b/snd_main.c @@ -1331,7 +1331,12 @@ static void SND_Spatialize_WithSfx(channel_t *ch, qbool isstatic, sfx_t *sfx) // If this channel does not manage its own volume (like CD tracks) if (!(ch->flags & CHANNELFLAG_FULLVOLUME)) - mastervol *= volume.value; + { + if ((ch->flags & CHANNELFLAG_BGMVOLUME)) + mastervol *= bgmvolume.value; + else + mastervol *= volume.value; + } if(snd_maxchannelvolume.value > 0) { @@ -1700,6 +1705,7 @@ qbool S_SetChannelFlag (unsigned int ch_ind, unsigned int flag, qbool value) if (flag != CHANNELFLAG_FORCELOOP && flag != CHANNELFLAG_PAUSED && flag != CHANNELFLAG_FULLVOLUME && + flag != CHANNELFLAG_BGMVOLUME && flag != CHANNELFLAG_LOCALSOUND) return false; diff --git a/sound.h b/sound.h index 697ded8e..1590a697 100644 --- a/sound.h +++ b/sound.h @@ -40,6 +40,7 @@ struct cmd_state_s; #define CHANNELFLAG_LOCALSOUND (1 << 2) // INTERNAL USE. Not settable by S_SetChannelFlag #define CHANNELFLAG_PAUSED (1 << 3) // pause status #define CHANNELFLAG_FULLVOLUME (1 << 4) // isn't affected by the general volume +#define CHANNELFLAG_BGMVOLUME (1 << 8) // uses bgmvolume instead of volume // ==================================================================== // Types and variables diff --git a/sv_ents5.c b/sv_ents5.c index 4ede6d3d..9eb7abd8 100644 --- a/sv_ents5.c +++ b/sv_ents5.c @@ -168,6 +168,8 @@ static int EntityState5_DeltaBits(const entity_state_t *o, const entity_state_t } if (o->traileffectnum != n->traileffectnum) bits |= E5_TRAILEFFECTNUM; + if (o->solid != n->solid) + bits |= E5_SOLID; } else if (o->active == ACTIVE_NETWORK) @@ -402,6 +404,20 @@ void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbi } if (bits & E5_TRAILEFFECTNUM) MSG_WriteShort(msg, s->traileffectnum); + if (bits & E5_SOLID) + { + MSG_WriteByte(msg, s->solid); + + if (s->solid != SOLID_NOT && s->solid != SOLID_BSP) + { + MSG_WriteCoord32f(msg, s->mins[0]); + MSG_WriteCoord32f(msg, s->mins[1]); + MSG_WriteCoord32f(msg, s->mins[2]); + MSG_WriteCoord32f(msg, s->maxs[0]); + MSG_WriteCoord32f(msg, s->maxs[1]); + MSG_WriteCoord32f(msg, s->maxs[2]); + } + } ENTITYSIZEPROFILING_END(msg, s->number, bits); } } diff --git a/sv_ents_nq.c b/sv_ents_nq.c index 8db8a623..d1b5216b 100644 --- a/sv_ents_nq.c +++ b/sv_ents_nq.c @@ -84,6 +84,8 @@ qbool EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates, co bits |= U_GLOWCOLOR; if (!VectorCompare(baseline.colormod, s->colormod)) bits |= U_COLORMOD; + if (baseline.solid != s->solid) + bits |= U_SOLID; // if extensions are disabled, clear the relevant update flags if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_NEHAHRAMOVIE) @@ -139,7 +141,8 @@ qbool EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates, co if (bits & U_COLORMOD) {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[2] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);} if (bits & U_FRAME2) MSG_WriteByte(&buf, s->frame >> 8); if (bits & U_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8); - + if (bits & U_SOLID) MSG_WriteByte(&buf, s->solid); + // the nasty protocol if ((bits & U_EXTEND1) && sv.protocol == PROTOCOL_NEHAHRAMOVIE) { diff --git a/sv_phys.c b/sv_phys.c index a72a7ca6..d4902a4d 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -1428,7 +1428,9 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qbool applygravity, float PRVM_serveredictvector(ent, velocity)[2] -= gravity * 0.5f; } } - + + //Con_Printf("SSQC: %d\n", blocked); + return blocked; } @@ -2329,7 +2331,6 @@ static void SV_WalkMove (prvm_edict_t *ent) VectorCopy (PRVM_serveredictvector(ent, velocity), start_velocity); clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0); - if(sv_gameplayfix_downtracesupportsongroundflag.integer) if(!(clip & 1)) { @@ -2966,6 +2967,10 @@ void SV_Physics_ClientMove(void) // call player physics, this needs the proper frametime PRVM_serverglobalfloat(frametime) = sv.frametime; SV_PlayerPhysics(); + + // perform movetype behaviour + // note: will always be MOVETYPE_WALK if disableclientprediction = 0 + SV_Physics_ClientEntity_NoThink (ent); // call standard client pre-think, with frametime = 0 PRVM_serverglobalfloat(time) = sv.time; @@ -2977,10 +2982,6 @@ void SV_Physics_ClientMove(void) // make sure the velocity is sane (not a NaN) SV_CheckVelocity(ent); - // perform movetype behaviour - // note: will always be MOVETYPE_WALK if disableclientprediction = 0 - SV_Physics_ClientEntity_NoThink (ent); - // call standard player post-think, with frametime = 0 PRVM_serverglobalfloat(time) = sv.time; PRVM_serverglobalfloat(frametime) = 0; diff --git a/sv_send.c b/sv_send.c index 984f9635..619b3c83 100644 --- a/sv_send.c +++ b/sv_send.c @@ -518,6 +518,14 @@ static qbool SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, cs->tagindex = (unsigned char)PRVM_serveredictfloat(ent, tag_index); cs->glowsize = glowsize; cs->traileffectnum = PRVM_serveredictfloat(ent, traileffectnum); + + int csqcflags = (int)(PRVM_serveredictfloat(ent, csqcflags)); + if (csqcflags & CSQCFLAG_SOLIDITY) + { + cs->solid = PRVM_serveredictfloat(ent, solid); + VectorCopy(PRVM_serveredictvector(ent, mins), cs->mins); + VectorCopy(PRVM_serveredictvector(ent, maxs), cs->maxs); + } // don't need to init cs->colormod because the defaultstate did that for us //cs->colormod[0] = cs->colormod[1] = cs->colormod[2] = 32; diff --git a/sv_user.c b/sv_user.c index 9e17dbfe..a2df63c8 100644 --- a/sv_user.c +++ b/sv_user.c @@ -613,7 +613,6 @@ void SV_PlayerPhysics (void) PRVM_serveredictvector(host_client->edict, angles)[PITCH] = -v_angle[PITCH]/3; PRVM_serveredictvector(host_client->edict, angles)[YAW] = v_angle[YAW]; } - if ( (int)PRVM_serveredictfloat(host_client->edict, flags) & FL_WATERJUMP ) { SV_WaterJump (); diff --git a/svvm_cmds.c b/svvm_cmds.c index bece8d54..a8bf069c 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -566,7 +566,7 @@ static void VM_SV_sound(prvm_prog_t *prog) else { // 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); + flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED | CHANNELFLAG_FULLVOLUME | CHANNELFLAG_BGMVOLUME); } if (nvolume < 0 || nvolume > 255) @@ -3207,6 +3207,13 @@ static void VM_SV_frameduration(prvm_prog_t *prog) PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate; } +// #277 void(entity e) touchtriggers = #279; +static void VM_SV_touchtriggers(prvm_prog_t *prog) +{ + prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM0); + SV_LinkEdict_TouchAreaGrid(ed); +} + prvm_builtin_t vm_sv_builtins[] = { NULL, // #0 NULL function (not callable) (QUAKE) @@ -3490,7 +3497,7 @@ VM_SV_skel_delete, // #275 void(float skel) skel_delete = #275; // (DP_SKELET VM_SV_frameforname, // #276 float(float modlindex, string framename) frameforname = #276; // (DP_SKELETONOBJECTS) finds number of a specified frame in the animation, returns -1 if no match found VM_SV_frameduration, // #277 float(float modlindex, float framenum) frameduration = #277; // (DP_SKELETONOBJECTS) returns the intended play time (in seconds) of the specified framegroup, if it does not exist the result is 0, if it is a single frame it may be a small value around 0.1 or 0. NULL, // #278 -NULL, // #279 +VM_SV_touchtriggers, // #279 NULL, // #280 NULL, // #281 NULL, // #282 -- 2.39.2