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,
GenMatrixPosQuat4Scale,
COM_StripExtension,
Alias_ForceConvertBoneData,
#ifdef USERBE
World_LinkEdict,
World_RegisterPhysicsEngine,
World_UnregisterPhysicsEngine,
World_GenerateCollisionMesh,
World_ReleaseCollisionMesh
#else
NULL,
NULL,
NULL,
NULL,
NULL
#endif
Alias_ForceConvertBoneData
};
if (VM_LONG(arg[0]) >= sizeof(funcs))
return (qintptr_t)&funcs;

View file

@ -1435,7 +1435,10 @@ void SCR_DrawGameClock(void)
else
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)
{

View file

@ -1178,7 +1178,7 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
#endif
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"));
if (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();
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);
}
#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
@ -394,6 +430,11 @@ void V_ParseDamage (playerview_t *pv)
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
if (CSQC_Parse_Damage(armor, blood, from))
return;
@ -1871,4 +1912,8 @@ void V_Init (void)
Cvar_Register (&chase_active, VIEWVARS);
Cvar_Register (&chase_back, 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_LAVA -5
#define Q1CONTENTS_SKY -6
#define Q1CONTENTS_CLIP -8
#define Q1CONTENTS_LADDER -16
#define Q1CONTENTS_STRIPPED -7 /*not known to engine*/
#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 !!!
typedef struct

View file

@ -192,11 +192,11 @@ typedef struct
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 *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers);
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 *unused1;
void *reserved2;
void *unused3;
void *unused4;
void *unused5;
} modplugfuncs_t;
#define MODPLUGFUNCS_VERSION 2

View file

@ -41,7 +41,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef USERBE
#include "pr_common.h"
#include "com_mesh.h"
#ifndef FTEENGINE
#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));
#undef ARGNAMES
#define ARGNAMES ,version
static BUILTINR(modplugfuncs_t*, Mod_GetPluginModelFuncs, (int version));
static BUILTINR(rbeplugfuncs_t*, RBE_GetPluginFuncs, (int version));
#undef ARGNAMES
#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));
#undef ARGNAMES
static modplugfuncs_t *modfuncs;
static rbeplugfuncs_t *rbefuncs;
//============================================================================
// physics engine support
@ -1383,7 +1382,7 @@ static void QDECL World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed)
}
ed->ode.ode_body = NULL;
modfuncs->ReleaseCollisionMesh(ed);
rbefuncs->ReleaseCollisionMesh(ed);
if(ed->ode.ode_massbuf)
BZ_Free(ed->ode.ode_massbuf);
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);
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)
@ -2114,7 +2113,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
World_ODE_RemoveFromEntity(world, ed);
return;
}
if (!modfuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
{
if (ed->ode.ode_physics)
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)
{
if (modfuncs)
modfuncs->UnregisterPhysicsEngine("ODE");
if (rbefuncs)
rbefuncs->UnregisterPhysicsEngine("ODE");
World_ODE_Shutdown();
return 0;
}
qintptr_t Plug_Init(qintptr_t *args)
{
CHECKBUILTIN(Mod_GetPluginModelFuncs);
CHECKBUILTIN(RBE_GetPluginFuncs);
CHECKBUILTIN(Cvar_GetNVFDG);
#ifndef ODE_STATIC
CHECKBUILTIN(Sys_LoadLibrary);
CHECKBUILTIN(Sys_CloseLibrary);
#endif
if (BUILTINISVALID(Mod_GetPluginModelFuncs))
if (BUILTINISVALID(RBE_GetPluginFuncs))
{
modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t));
if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION)
modfuncs = NULL;
rbefuncs = pRBE_GetPluginFuncs(sizeof(rbeplugfuncs_t));
if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION)
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");
return false;
@ -2813,9 +2817,9 @@ qintptr_t Plug_Init(qintptr_t *args)
}
#endif
if (!modfuncs || !modfuncs->RegisterPhysicsEngine)
if (!rbefuncs || !rbefuncs->RegisterPhysicsEngine)
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");
else
{

View file

@ -1277,6 +1277,31 @@ qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, const qint
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_List_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_CloseLibrary", Plug_Sys_CloseLibrary, PLUG_BIF_DLLONLY);
#ifdef USERBE
Plug_RegisterBuiltin("RBE_GetPluginFuncs", Plug_RBE_GetPluginFuncs, PLUG_BIF_DLLONLY);
#endif
Plug_Client_Init();
}

View file

@ -540,6 +540,22 @@ pbool QDECL ED_CanFree (edict_t *ed);
#define JOINTTYPE_HINGE2 5
#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_YES 1
#define DAMAGE_AIM 2

View file

@ -375,7 +375,7 @@ struct traceinfo_s
unsigned int solidcontents;
trace_t trace;
qboolean sphere;
qboolean capsule;
float radius;
/*set even for sphere traces (used for bbox tests)*/
vec3_t mins;
@ -383,6 +383,10 @@ struct traceinfo_s
vec3_t start;
vec3_t end;
vec3_t up;
vec3_t capsulesize;
vec3_t extents;
};
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++)
{
/*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
{
@ -644,8 +652,27 @@ static unsigned int Q1BSP_TranslateContents(int contents)
return FTECONTENTS_SKY;
case Q1CONTENTS_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:
Sys_Error("Q1BSP_TranslateContents: Unknown contents type - %i", contents);
Con_Printf("Q1BSP_TranslateContents: Unknown contents type - %i", contents);
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(start, traceinfo.start);
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.radius = 48;
traceinfo.mins[0] = -traceinfo.radius;

View file

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