finally implement stat_matchstarttime iiuc.

add a new gimmick. there's a cvar to enable it.
fix up rbe plugins to be usable in dedicated servers.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4844 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-03-05 22:14:21 +00:00
parent 086841f1b8
commit 1ba434bb17
11 changed files with 185 additions and 47 deletions

View file

@ -638,20 +638,7 @@ qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, cons
AngleVectors, AngleVectors,
GenMatrixPosQuat4Scale, GenMatrixPosQuat4Scale,
COM_StripExtension, COM_StripExtension,
Alias_ForceConvertBoneData, Alias_ForceConvertBoneData
#ifdef USERBE
World_LinkEdict,
World_RegisterPhysicsEngine,
World_UnregisterPhysicsEngine,
World_GenerateCollisionMesh,
World_ReleaseCollisionMesh
#else
NULL,
NULL,
NULL,
NULL,
NULL
#endif
}; };
if (VM_LONG(arg[0]) >= sizeof(funcs)) if (VM_LONG(arg[0]) >= sizeof(funcs))
return (qintptr_t)&funcs; return (qintptr_t)&funcs;

View file

@ -1435,7 +1435,10 @@ void SCR_DrawGameClock(void)
else else
timelimit = 0; timelimit = 0;
showtime = timelimit - cl.matchgametime; if (cl.playerview[0].statsf[STAT_MATCHSTARTTIME])
showtime = timelimit - (cl.servertime - cl.playerview[0].statsf[STAT_MATCHSTARTTIME]);
else
showtime = timelimit - cl.matchgametime;
if (showtime < 0) if (showtime < 0)
{ {

View file

@ -1178,7 +1178,7 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
#endif #endif
TRACE(("dbg: R_ApplyRenderer: reloading server map\n")); TRACE(("dbg: R_ApplyRenderer: reloading server map\n"));
sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_ERROR); sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_WARN);
TRACE(("dbg: R_ApplyRenderer: loaded\n")); TRACE(("dbg: R_ApplyRenderer: loaded\n"));
if (sv.world.worldmodel->loadstate == MLS_LOADING) if (sv.world.worldmodel->loadstate == MLS_LOADING)
COM_WorkerPartialSync(sv.world.worldmodel, &sv.world.worldmodel->loadstate, MLS_LOADING); COM_WorkerPartialSync(sv.world.worldmodel, &sv.world.worldmodel->loadstate, MLS_LOADING);

View file

@ -27,6 +27,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ctype.h> // for isdigit(); #include <ctype.h> // for isdigit();
cvar_t ffov = SCVAR("ffov", "0"); cvar_t ffov = SCVAR("ffov", "0");
#if defined(_WIN32) && !defined(MINIMAL)
//amusing gimmick / easteregg.
#include "winquake.h"
cvar_t itburnsitburnsmakeitstop = CVARFD("itburnsitburnsmakeitstop", "0", CVAR_NOTFROMSERVER, "Ouch");
#endif
/* /*
@ -373,6 +378,37 @@ void V_Gamma_Callback(struct cvar_s *var, char *oldvalue)
V_UpdatePalette (true); V_UpdatePalette (true);
} }
#ifdef _WIN32
void W32_BlowChunk(vec3_t pos, float radius)
{
vec3_t center;
if (Matrix4x4_CM_Project(pos, center, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y))
{
int mid_x = center[0]*r_refdef.vrect.width+r_refdef.vrect.x;
int mid_y = (1-center[1])*r_refdef.vrect.height+r_refdef.vrect.y;
HRGN tmp = CreateRectRgn(0,0,0,0);
HRGN newrgn = CreateRectRgn(0,0,0,0);
HRGN oldrgn = CreateRectRgn(0,0,0,0);
HRGN hole = CreateEllipticRgn(mid_x-radius, mid_y-radius, mid_x+radius, mid_y+radius);
if (GetWindowRgn(mainwindow, oldrgn) <= NULLREGION)
{
RECT rect;
DeleteObject(oldrgn);
GetWindowRect(mainwindow, &rect);
oldrgn = CreateRectRgn(0,0,rect.right-rect.left,rect.bottom-rect.top);
}
CombineRgn(tmp, oldrgn, hole, RGN_XOR);
CombineRgn(newrgn, oldrgn, tmp, RGN_AND);
DeleteObject(oldrgn);
DeleteObject(hole);
DeleteObject(tmp);
SetWindowRgn(mainwindow, newrgn, TRUE);
}
}
#endif
/* /*
=============== ===============
V_ParseDamage V_ParseDamage
@ -394,6 +430,11 @@ void V_ParseDamage (playerview_t *pv)
pv->faceanimtime = cl.time + 0.2; // but sbar face into pain frame pv->faceanimtime = cl.time + 0.2; // but sbar face into pain frame
#if defined(_WIN32) && !defined(MINIMAL)
if (itburnsitburnsmakeitstop.value > 0)
W32_BlowChunk(from, (armor+blood) * itburnsitburnsmakeitstop.value);
#endif
#ifdef CSQC_DAT #ifdef CSQC_DAT
if (CSQC_Parse_Damage(armor, blood, from)) if (CSQC_Parse_Damage(armor, blood, from))
return; return;
@ -1871,4 +1912,8 @@ void V_Init (void)
Cvar_Register (&chase_active, VIEWVARS); Cvar_Register (&chase_active, VIEWVARS);
Cvar_Register (&chase_back, VIEWVARS); Cvar_Register (&chase_back, VIEWVARS);
Cvar_Register (&chase_up, VIEWVARS); Cvar_Register (&chase_up, VIEWVARS);
#if defined(_WIN32) && !defined(MINIMAL)
Cvar_Register (&itburnsitburnsmakeitstop, VIEWVARS);
#endif
} }

View file

@ -154,8 +154,16 @@ typedef struct
#define Q1CONTENTS_SLIME -4 #define Q1CONTENTS_SLIME -4
#define Q1CONTENTS_LAVA -5 #define Q1CONTENTS_LAVA -5
#define Q1CONTENTS_SKY -6 #define Q1CONTENTS_SKY -6
#define Q1CONTENTS_CLIP -8 #define Q1CONTENTS_STRIPPED -7 /*not known to engine*/
#define Q1CONTENTS_LADDER -16 #define Q1CONTENTS_CLIP -8 /*solid to players*/
#define Q1CONTENTS_FLOW_1 -9 /*moves player*/
#define Q1CONTENTS_FLOW_2 -10 /*moves player*/
#define Q1CONTENTS_FLOW_3 -11 /*moves player*/
#define Q1CONTENTS_FLOW_4 -12 /*moves player*/
#define Q1CONTENTS_FLOW_5 -13 /*moves player*/
#define Q1CONTENTS_FLOW_6 -14 /*moves player*/
#define Q1CONTENTS_TRANS -15 /*should be solid I guess*/
#define Q1CONTENTS_LADDER -16 /*player can climb up/down*/
// !!! if this is changed, it must be changed in asm_i386.h too !!! // !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct typedef struct

View file

@ -192,11 +192,11 @@ typedef struct
void (QDECL *StripExtension) (const char *in, char *out, int outlen); void (QDECL *StripExtension) (const char *in, char *out, int outlen);
void (QDECL *ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount); void (QDECL *ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers); void *unused1;
qboolean (QDECL *RegisterPhysicsEngine)(const char *enginename, void(QDECL*World_Bullet_Start)(world_t*world)); //returns false if there's already one active. void *reserved2;
void (QDECL *UnregisterPhysicsEngine)(const char *enginename); //returns false if there's already one active. void *unused3;
qboolean (QDECL *GenerateCollisionMesh)(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter); void *unused4;
void (QDECL *ReleaseCollisionMesh) (wedict_t *ed); void *unused5;
} modplugfuncs_t; } modplugfuncs_t;
#define MODPLUGFUNCS_VERSION 2 #define MODPLUGFUNCS_VERSION 2

View file

@ -41,7 +41,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef USERBE #ifdef USERBE
#include "pr_common.h" #include "pr_common.h"
#include "com_mesh.h"
#ifndef FTEENGINE #ifndef FTEENGINE
#define BZ_Malloc malloc #define BZ_Malloc malloc
@ -67,13 +66,13 @@ static BUILTINR(dllhandle_t *, Sys_LoadLibrary, (const char *name,dllfunction_t
static BUILTIN(void, Sys_CloseLibrary, (dllhandle_t *hdl)); static BUILTIN(void, Sys_CloseLibrary, (dllhandle_t *hdl));
#undef ARGNAMES #undef ARGNAMES
#define ARGNAMES ,version #define ARGNAMES ,version
static BUILTINR(modplugfuncs_t*, Mod_GetPluginModelFuncs, (int version)); static BUILTINR(rbeplugfuncs_t*, RBE_GetPluginFuncs, (int version));
#undef ARGNAMES #undef ARGNAMES
#define ARGNAMES ,name,defaultval,flags,description,groupname #define ARGNAMES ,name,defaultval,flags,description,groupname
static BUILTINR(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname)); static BUILTINR(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname));
#undef ARGNAMES #undef ARGNAMES
static modplugfuncs_t *modfuncs; static rbeplugfuncs_t *rbefuncs;
//============================================================================ //============================================================================
// physics engine support // physics engine support
@ -1383,7 +1382,7 @@ static void QDECL World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed)
} }
ed->ode.ode_body = NULL; ed->ode.ode_body = NULL;
modfuncs->ReleaseCollisionMesh(ed); rbefuncs->ReleaseCollisionMesh(ed);
if(ed->ode.ode_massbuf) if(ed->ode.ode_massbuf)
BZ_Free(ed->ode.ode_massbuf); BZ_Free(ed->ode.ode_massbuf);
ed->ode.ode_massbuf = NULL; ed->ode.ode_massbuf = NULL;
@ -1483,7 +1482,7 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
VectorCopy(avelocity, ed->ode.ode_avelocity); VectorCopy(avelocity, ed->ode.ode_avelocity);
ed->ode.ode_gravity = dBodyGetGravityMode(body); ed->ode.ode_gravity = dBodyGetGravityMode(body);
modfuncs->LinkEdict(world, ed, true); rbefuncs->LinkEdict(world, ed, true);
} }
static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed) static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
@ -2114,7 +2113,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
World_ODE_RemoveFromEntity(world, ed); World_ODE_RemoveFromEntity(world, ed);
return; return;
} }
if (!modfuncs->GenerateCollisionMesh(world, model, ed, geomcenter)) if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
{ {
if (ed->ode.ode_physics) if (ed->ode.ode_physics)
World_ODE_RemoveFromEntity(world, ed); World_ODE_RemoveFromEntity(world, ed);
@ -2779,28 +2778,33 @@ static void World_ODE_RunCmd(world_t *world, rbecommandqueue_t *cmd)
static qintptr_t QDECL Plug_ODE_Shutdown(qintptr_t *args) static qintptr_t QDECL Plug_ODE_Shutdown(qintptr_t *args)
{ {
if (modfuncs) if (rbefuncs)
modfuncs->UnregisterPhysicsEngine("ODE"); rbefuncs->UnregisterPhysicsEngine("ODE");
World_ODE_Shutdown(); World_ODE_Shutdown();
return 0; return 0;
} }
qintptr_t Plug_Init(qintptr_t *args) qintptr_t Plug_Init(qintptr_t *args)
{ {
CHECKBUILTIN(Mod_GetPluginModelFuncs); CHECKBUILTIN(RBE_GetPluginFuncs);
CHECKBUILTIN(Cvar_GetNVFDG); CHECKBUILTIN(Cvar_GetNVFDG);
#ifndef ODE_STATIC #ifndef ODE_STATIC
CHECKBUILTIN(Sys_LoadLibrary); CHECKBUILTIN(Sys_LoadLibrary);
CHECKBUILTIN(Sys_CloseLibrary); CHECKBUILTIN(Sys_CloseLibrary);
#endif #endif
if (BUILTINISVALID(Mod_GetPluginModelFuncs)) if (BUILTINISVALID(RBE_GetPluginFuncs))
{ {
modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t)); rbefuncs = pRBE_GetPluginFuncs(sizeof(rbeplugfuncs_t));
if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION) if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION)
modfuncs = NULL; rbefuncs = NULL;
} }
if (!modfuncs || !BUILTINISVALID(Cvar_GetNVFDG)) if (!rbefuncs)
{
Con_Printf("ODE plugin failed: Engine does not support external rigid body engines.\n");
return false;
}
if (!BUILTINISVALID(Cvar_GetNVFDG))
{ {
Con_Printf("ODE plugin failed: Engine too old.\n"); Con_Printf("ODE plugin failed: Engine too old.\n");
return false; return false;
@ -2813,9 +2817,9 @@ qintptr_t Plug_Init(qintptr_t *args)
} }
#endif #endif
if (!modfuncs || !modfuncs->RegisterPhysicsEngine) if (!rbefuncs || !rbefuncs->RegisterPhysicsEngine)
Con_Printf("ODE plugin failed: Engine doesn't support physics engine plugins.\n"); Con_Printf("ODE plugin failed: Engine doesn't support physics engine plugins.\n");
else if (!modfuncs->RegisterPhysicsEngine("ODE", World_ODE_Start)) else if (!rbefuncs->RegisterPhysicsEngine("ODE", World_ODE_Start))
Con_Printf("ODE plugin failed: Engine already has a physics plugin active.\n"); Con_Printf("ODE plugin failed: Engine already has a physics plugin active.\n");
else else
{ {

View file

@ -1277,6 +1277,31 @@ qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, const qint
return bufferlen; return bufferlen;
} }
#ifdef USERBE
#include "pr_common.h"
//functions useful for rigid body engines.
qintptr_t VARGS Plug_RBE_GetPluginFuncs(void *offset, quintptr_t mask, const qintptr_t *arg)
{
static rbeplugfuncs_t funcs =
{
RBEPLUGFUNCS_VERSION,
World_RegisterPhysicsEngine,
World_UnregisterPhysicsEngine,
World_GenerateCollisionMesh,
World_ReleaseCollisionMesh,
World_LinkEdict,
VectorAngles,
AngleVectors
};
if (VM_LONG(arg[0]) >= sizeof(funcs))
return (qintptr_t)&funcs;
else
return 0;
}
#endif
void Plug_CloseAll_f(void); void Plug_CloseAll_f(void);
void Plug_List_f(void); void Plug_List_f(void);
void Plug_Close_f(void); void Plug_Close_f(void);
@ -1399,6 +1424,10 @@ void Plug_Initialise(qboolean fromgamedir)
Plug_RegisterBuiltin("Sys_LoadLibrary", Plug_Sys_LoadLibrary, PLUG_BIF_DLLONLY); Plug_RegisterBuiltin("Sys_LoadLibrary", Plug_Sys_LoadLibrary, PLUG_BIF_DLLONLY);
Plug_RegisterBuiltin("Sys_CloseLibrary", Plug_Sys_CloseLibrary, PLUG_BIF_DLLONLY); Plug_RegisterBuiltin("Sys_CloseLibrary", Plug_Sys_CloseLibrary, PLUG_BIF_DLLONLY);
#ifdef USERBE
Plug_RegisterBuiltin("RBE_GetPluginFuncs", Plug_RBE_GetPluginFuncs, PLUG_BIF_DLLONLY);
#endif
Plug_Client_Init(); Plug_Client_Init();
} }

View file

@ -540,6 +540,22 @@ pbool QDECL ED_CanFree (edict_t *ed);
#define JOINTTYPE_HINGE2 5 #define JOINTTYPE_HINGE2 5
#define JOINTTYPE_FIXED -1 #define JOINTTYPE_FIXED -1
typedef struct
{
int version;
qboolean (QDECL *RegisterPhysicsEngine)(const char *enginename, void(QDECL*World_Bullet_Start)(world_t*world)); //returns false if there's already one active.
void (QDECL *UnregisterPhysicsEngine)(const char *enginename); //returns false if there's already one active.
qboolean (QDECL *GenerateCollisionMesh)(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter);
void (QDECL *ReleaseCollisionMesh) (wedict_t *ed);
void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers);
void (QDECL *VectorAngles)(float *forward, float *up, float *result);
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
} rbeplugfuncs_t;
#define RBEPLUGFUNCS_VERSION 1
#define DAMAGE_NO 0 #define DAMAGE_NO 0
#define DAMAGE_YES 1 #define DAMAGE_YES 1
#define DAMAGE_AIM 2 #define DAMAGE_AIM 2

View file

@ -375,7 +375,7 @@ struct traceinfo_s
unsigned int solidcontents; unsigned int solidcontents;
trace_t trace; trace_t trace;
qboolean sphere; qboolean capsule;
float radius; float radius;
/*set even for sphere traces (used for bbox tests)*/ /*set even for sphere traces (used for bbox tests)*/
vec3_t mins; vec3_t mins;
@ -383,6 +383,10 @@ struct traceinfo_s
vec3_t start; vec3_t start;
vec3_t end; vec3_t end;
vec3_t up;
vec3_t capsulesize;
vec3_t extents;
}; };
static void Q1BSP_ClipToBrushes(struct traceinfo_s *traceinfo, mbrush_t *brush) static void Q1BSP_ClipToBrushes(struct traceinfo_s *traceinfo, mbrush_t *brush)
@ -409,9 +413,13 @@ static void Q1BSP_ClipToBrushes(struct traceinfo_s *traceinfo, mbrush_t *brush)
for (i = brush->numplanes, plane = brush->planes; i; i--, plane++) for (i = brush->numplanes, plane = brush->planes; i; i--, plane++)
{ {
/*calculate the distance based upon the shape of the object we're tracing for*/ /*calculate the distance based upon the shape of the object we're tracing for*/
if (traceinfo->sphere) if (traceinfo->capsule)
{ {
dist = plane->dist + traceinfo->radius; dist = DotProduct(traceinfo->up, plane->normal);
dist = dist*(traceinfo->capsulesize[(dist<0)?1:2]) - traceinfo->capsulesize[0];
dist = plane->dist - dist;
//dist = plane->dist + traceinfo->radius;
} }
else else
{ {
@ -644,8 +652,27 @@ static unsigned int Q1BSP_TranslateContents(int contents)
return FTECONTENTS_SKY; return FTECONTENTS_SKY;
case Q1CONTENTS_LADDER: case Q1CONTENTS_LADDER:
return FTECONTENTS_LADDER; return FTECONTENTS_LADDER;
case Q1CONTENTS_CLIP:
return FTECONTENTS_PLAYERCLIP;
case Q1CONTENTS_TRANS:
return FTECONTENTS_SOLID;
//q2 is better than nothing, right?
case Q1CONTENTS_FLOW_1:
return Q2CONTENTS_CURRENT_0;
case Q1CONTENTS_FLOW_2:
return Q2CONTENTS_CURRENT_90;
case Q1CONTENTS_FLOW_3:
return Q2CONTENTS_CURRENT_180;
case Q1CONTENTS_FLOW_4:
return Q2CONTENTS_CURRENT_270;
case Q1CONTENTS_FLOW_5:
return Q2CONTENTS_CURRENT_UP;
case Q1CONTENTS_FLOW_6:
return Q2CONTENTS_CURRENT_DOWN;
default: default:
Sys_Error("Q1BSP_TranslateContents: Unknown contents type - %i", contents); Con_Printf("Q1BSP_TranslateContents: Unknown contents type - %i", contents);
return FTECONTENTS_SOLID; return FTECONTENTS_SOLID;
} }
} }
@ -855,7 +882,23 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3]
VectorCopy(maxs, traceinfo.maxs); VectorCopy(maxs, traceinfo.maxs);
VectorCopy(start, traceinfo.start); VectorCopy(start, traceinfo.start);
VectorCopy(end, traceinfo.end); VectorCopy(end, traceinfo.end);
traceinfo.sphere = false; traceinfo.capsule = capsule;
if (traceinfo.capsule)
{
float ext;
traceinfo.capsulesize[0] = ((maxs[0]-mins[0]) + (maxs[1]-mins[1]))/4.0;
traceinfo.capsulesize[1] = maxs[2];
traceinfo.capsulesize[2] = mins[2];
ext = (traceinfo.capsulesize[1] > -traceinfo.capsulesize[2])?traceinfo.capsulesize[1]:-traceinfo.capsulesize[2];
traceinfo.capsulesize[1] -= traceinfo.capsulesize[0];
traceinfo.capsulesize[2] += traceinfo.capsulesize[0];
traceinfo.extents[0] = ext+1;
traceinfo.extents[1] = ext+1;
traceinfo.extents[2] = ext+1;
VectorSet(traceinfo.up, 0, 0, 1);
}
/* traceinfo.sphere = true; /* traceinfo.sphere = true;
traceinfo.radius = 48; traceinfo.radius = 48;
traceinfo.mins[0] = -traceinfo.radius; traceinfo.mins[0] = -traceinfo.radius;

View file

@ -441,13 +441,16 @@ static void LightCalcFaceExtents (llightinfo_t *l)
l->exactmins[i] = mins[i]; l->exactmins[i] = mins[i];
l->exactmaxs[i] = maxs[i]; l->exactmaxs[i] = maxs[i];
mins[i] = floor(mins[i]/16); mins[i] = floor(mins[i]/(1<<s->lmshift));
maxs[i] = ceil(maxs[i]/16); maxs[i] = ceil(maxs[i]/(1<<s->lmshift));
l->texmins[i] = mins[i]; l->texmins[i] = mins[i];
l->texsize[i] = maxs[i] - mins[i]; l->texsize[i] = maxs[i] - mins[i];
if (l->texsize[i] > 17) if (l->texsize[i] > 17)
Error ("Bad surface extents"); {
l->texsize[i] = 17;
Con_Printf("Bad surface extents");
}
} }
} }