fix issue with more submodels than the precache model limit. bump model precache limit.
move some of the weird hexen2 features into a HEXEN2 define, which will be disabled by the QUAKETC define. preliminary attempt at capsule collision support. only capsule/q3bsp support, no capsule/box, box/capsule, or capsule/capsule support, yet. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4753 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
811d49720d
commit
45bafbf374
63 changed files with 1132 additions and 890 deletions
|
@ -577,8 +577,13 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
unsigned int pc;
|
||||
unsigned int modhandle = VM_LONG(arg[1]);
|
||||
model_t *mod;
|
||||
if (modhandle >= MAX_MODELS)
|
||||
if (modhandle >= MAX_PRECACHE_MODELS)
|
||||
{
|
||||
// if (modhandle == MAX_PRECACHE_MODELS+1)
|
||||
// mod = &capsule_model;
|
||||
// else
|
||||
mod = &box_model;
|
||||
}
|
||||
else
|
||||
mod = cl.model_precache[modhandle+1];
|
||||
if (mod && !mod->needload)
|
||||
|
@ -597,7 +602,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
float *origin = VM_POINTER(arg[2]);
|
||||
float *angles = VM_POINTER(arg[3]);
|
||||
model_t *mod;
|
||||
if (modhandle >= MAX_MODELS)
|
||||
if (modhandle >= MAX_PRECACHE_MODELS)
|
||||
mod = &box_model;
|
||||
else
|
||||
mod = cl.model_precache[modhandle+1];
|
||||
|
@ -626,6 +631,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
}
|
||||
break;
|
||||
|
||||
case CG_CM_TRANSFORMEDCAPSULETRACE:
|
||||
case CG_CM_TRANSFORMEDBOXTRACE:
|
||||
// void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
|
||||
// const vec3_t mins, const vec3_t maxs,
|
||||
|
@ -643,7 +649,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
float *origin = VM_POINTER(arg[7]);
|
||||
float *angles = VM_POINTER(arg[8]);
|
||||
model_t *mod;
|
||||
if (modhandle >= MAX_MODELS)
|
||||
if (modhandle >= MAX_PRECACHE_MODELS)
|
||||
mod = &box_model;
|
||||
else
|
||||
mod = cl.model_precache[modhandle+1];
|
||||
|
@ -656,13 +662,13 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
origin = vec3_origin;
|
||||
if (!angles)
|
||||
angles = vec3_origin;
|
||||
if (mod)
|
||||
#ifndef CLIENTONLY
|
||||
TransformedNativeTrace(mod, 0, 0, start, end, mins, maxs, brushmask, &tr, origin, angles);
|
||||
if (mod && !mod->needload)
|
||||
#if !defined(CLIENTONLY) || defined(CSQC_DAT)
|
||||
World_TransformedTrace(mod, 0, 0, start, end, mins, maxs, fn==CG_CM_TRANSFORMEDCAPSULETRACE, &tr, origin, angles, brushmask);
|
||||
#else
|
||||
{
|
||||
#ifdef warningmsg
|
||||
#pragma warningmsg("FIXME: G3 CGame requires TransformedNativeTrace!")
|
||||
#pragma warningmsg("FIXME: G3 CGame requires World_TransformedTrace!")
|
||||
#endif
|
||||
memset(&tr, 0, sizeof(tr));
|
||||
tr.allsolid = tr.startsolid = true;
|
||||
|
@ -685,6 +691,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
memcpy(&results->plane, &tr.plane, sizeof(cplane_t));
|
||||
}
|
||||
break;
|
||||
case CG_CM_CAPSULETRACE:
|
||||
case CG_CM_BOXTRACE:
|
||||
// void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
|
||||
// const vec3_t mins, const vec3_t maxs,
|
||||
|
@ -700,7 +707,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
unsigned int modhandle = VM_LONG(arg[5]);
|
||||
int brushmask = VM_LONG(arg[6]);
|
||||
model_t *mod;
|
||||
if (modhandle >= MAX_MODELS)
|
||||
if (modhandle >= MAX_PRECACHE_MODELS)
|
||||
mod = &box_model;
|
||||
else
|
||||
mod = cl.model_precache[modhandle+1];
|
||||
|
@ -709,7 +716,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
mins = vec3_origin;
|
||||
if (!maxs)
|
||||
maxs = vec3_origin;
|
||||
mod->funcs.NativeTrace(mod, 0, 0, NULL, start, end, mins, maxs, brushmask, &tr);
|
||||
mod->funcs.NativeTrace(mod, 0, 0, NULL, start, end, mins, maxs, fn==CG_CM_CAPSULETRACE, brushmask, &tr);
|
||||
results->allsolid = tr.allsolid;
|
||||
results->contents = tr.contents;
|
||||
results->fraction = tr.fraction;
|
||||
|
@ -754,7 +761,11 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
|
||||
case CG_CM_TEMPBOXMODEL:
|
||||
CM_TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
|
||||
VM_LONG(ret) = MAX_MODELS;
|
||||
VM_LONG(ret) = MAX_PRECACHE_MODELS;
|
||||
break;
|
||||
case CG_CM_TEMPCAPSULEMODEL:
|
||||
CM_TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
|
||||
VM_LONG(ret) = MAX_PRECACHE_MODELS+1;
|
||||
break;
|
||||
|
||||
case CG_R_MODELBOUNDS:
|
||||
|
|
|
@ -1291,10 +1291,10 @@ void CL_Record_f (void)
|
|||
|
||||
MSG_WriteByte (&buf, svc_spawnstatic);
|
||||
|
||||
for (j = 1; j < MAX_MODELS; j++)
|
||||
for (j = 1; j < MAX_PRECACHE_MODELS; j++)
|
||||
if (ent->model == cl.model_precache[j])
|
||||
break;
|
||||
if (j == MAX_MODELS)
|
||||
if (j == MAX_PRECACHE_MODELS)
|
||||
MSG_WriteByte (&buf, 0);
|
||||
else
|
||||
MSG_WriteByte (&buf, j);
|
||||
|
|
|
@ -1790,7 +1790,6 @@ void V_ClearEntity(entity_t *e)
|
|||
e->playerindex = -1;
|
||||
e->topcolour = TOP_DEFAULT;
|
||||
e->bottomcolour = BOTTOM_DEFAULT;
|
||||
e->h2playerclass = 0;
|
||||
}
|
||||
entity_t *V_AddEntity(entity_t *in)
|
||||
{
|
||||
|
@ -2477,10 +2476,29 @@ void CLQ1_AddVisibleBBoxes(void)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e->v->solid == SOLID_BSP)
|
||||
{
|
||||
VectorCopy(e->v->absmin, min);
|
||||
VectorCopy(e->v->absmax, max);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd(e->v->origin, e->v->mins, min);
|
||||
VectorAdd(e->v->origin, e->v->maxs, max);
|
||||
}
|
||||
}
|
||||
if (e->xv->geomtype == GEOMTYPE_CAPSULE)
|
||||
{
|
||||
float rad = ((e->v->maxs[0]-e->v->mins[0]) + (e->v->maxs[1]-e->v->mins[1]))/4.0;
|
||||
float height = (e->v->maxs[2]-e->v->mins[2])/2;
|
||||
float matrix[12] = {1,0,0,0,0,1,0,0,0,0,1,0};
|
||||
matrix[3] = e->v->origin[0];
|
||||
matrix[7] = e->v->origin[1];
|
||||
matrix[11] = e->v->origin[2] + (e->v->maxs[2]-height);
|
||||
CLQ1_AddOrientedCylinder(s, rad*2, height*2, true, matrix, (e->v->solid || e->v->movetype)?0.1:0, (e->v->movetype == MOVETYPE_STEP || e->v->movetype == MOVETYPE_TOSS || e->v->movetype == MOVETYPE_BOUNCE)?0.1:0, ((int)e->v->flags & (FL_ONGROUND | ((e->v->movetype == MOVETYPE_STEP)?FL_FLY:0)))?0.1:0, 1);
|
||||
}
|
||||
else
|
||||
CLQ1_AddOrientedCube(s, min, max, NULL, (e->v->solid || e->v->movetype)?0.1:0, (e->v->movetype == MOVETYPE_STEP || e->v->movetype == MOVETYPE_TOSS || e->v->movetype == MOVETYPE_BOUNCE)?0.1:0, ((int)e->v->flags & (FL_ONGROUND | ((e->v->movetype == MOVETYPE_STEP)?FL_FLY:0)))?0.1:0, 1);
|
||||
}
|
||||
}
|
||||
|
@ -3276,7 +3294,9 @@ void CL_LinkPacketEntities (void)
|
|||
ent->customskin = 0;
|
||||
ent->topcolour = TOP_DEFAULT;
|
||||
ent->bottomcolour = BOTTOM_DEFAULT;
|
||||
#ifdef HEXEN2
|
||||
ent->h2playerclass = 0;
|
||||
#endif
|
||||
ent->light_known = 0;
|
||||
ent->forcedshader = NULL;
|
||||
|
||||
|
@ -3593,12 +3613,15 @@ void CL_LinkPacketEntities (void)
|
|||
#ifdef warningmsg
|
||||
#pragma warningmsg("Replace this flag on load for hexen2 models")
|
||||
#endif
|
||||
#ifdef HEXEN2
|
||||
if (strncmp(model->name, "models/sflesh", 13))
|
||||
#endif
|
||||
{ //hmm. hexen spider gibs...
|
||||
rad = 200;
|
||||
rad += r_lightflicker.value?((flicker + state->number)&31):0;
|
||||
}
|
||||
}
|
||||
#ifdef HEXEN2
|
||||
else if (modelflags & MFH2_FIREBALL)
|
||||
{
|
||||
rad = 120 - (r_lightflicker.value?(rand() % 20):10);
|
||||
|
@ -3618,6 +3641,7 @@ void CL_LinkPacketEntities (void)
|
|||
dclr[2] = -dclr[2];
|
||||
rad = 120 - (r_lightflicker.value?(rand() % 20):10);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rad)
|
||||
{
|
||||
|
@ -3736,7 +3760,9 @@ void CL_LinkProjectiles (void)
|
|||
ent->playerindex = -1;
|
||||
ent->topcolour = TOP_DEFAULT;
|
||||
ent->bottomcolour = BOTTOM_DEFAULT;
|
||||
#ifdef HEXEN2
|
||||
ent->h2playerclass = 0;
|
||||
#endif
|
||||
#ifdef PEXT_SCALE
|
||||
ent->scale = 1;
|
||||
#endif
|
||||
|
@ -4457,7 +4483,9 @@ void CL_LinkPlayers (void)
|
|||
ent->playerindex = j;
|
||||
ent->topcolour = info->ttopcolor;
|
||||
ent->bottomcolour = info->tbottomcolor;
|
||||
#ifdef HEXEN2
|
||||
ent->h2playerclass = info->h2playerclass;
|
||||
#endif
|
||||
|
||||
#ifdef PEXT_SCALE
|
||||
ent->scale = state->scale;
|
||||
|
@ -4617,7 +4645,7 @@ void CL_LinkViewModel(void)
|
|||
if (cl.intermission)
|
||||
return;
|
||||
|
||||
if (pv->stats[STAT_WEAPON] <= 0 || pv->stats[STAT_WEAPON] >= MAX_MODELS)
|
||||
if (pv->stats[STAT_WEAPON] <= 0 || pv->stats[STAT_WEAPON] >= MAX_PRECACHE_MODELS)
|
||||
return;
|
||||
|
||||
if (r_drawviewmodel.value > 0 && r_drawviewmodel.value < 1)
|
||||
|
|
|
@ -1281,7 +1281,9 @@ void CL_ClearState (void)
|
|||
CL_ClearTEnts();
|
||||
CL_ClearCustomTEnts();
|
||||
Surf_ClearLightmaps();
|
||||
#ifdef HEXEN2
|
||||
T_FreeInfoStrings();
|
||||
#endif
|
||||
SCR_ShowPic_Clear(false);
|
||||
|
||||
if (cl.playerview[0].playernum == -1)
|
||||
|
@ -2935,7 +2937,6 @@ void CLNQ_ConnectionlessPacket(void)
|
|||
return;
|
||||
|
||||
case CCREP_REJECT:
|
||||
connectinfo.trying = false;
|
||||
s = MSG_ReadString();
|
||||
Con_Printf("Connect failed\n%s\n", s);
|
||||
return;
|
||||
|
|
|
@ -682,7 +682,7 @@ void CL_DownloadFinished(qdownload_t *dl)
|
|||
}
|
||||
}
|
||||
*/
|
||||
for (i = 0; i < MAX_MODELS; i++) //go and load this model now.
|
||||
for (i = 0; i < MAX_PRECACHE_MODELS; i++) //go and load this model now.
|
||||
{
|
||||
if (!strcmp(cl.model_name[i], filename))
|
||||
{
|
||||
|
@ -1134,7 +1134,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (i=1 ; i<MAX_MODELS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_MODELS ; i++)
|
||||
{
|
||||
if (!cl.model_name[i][0])
|
||||
continue;
|
||||
|
@ -1285,7 +1285,7 @@ int CL_LoadSounds(int stage, qboolean dontactuallyload)
|
|||
//#define atstage() ((cl.contentstage == stage++)?++cl.contentstage:false)
|
||||
//#define endstage() if (giveuptime<Sys_DoubleTime()) return -1;
|
||||
|
||||
for (i=1 ; i<MAX_SOUNDS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_SOUNDS ; i++)
|
||||
{
|
||||
if (!cl.sound_name[i][0])
|
||||
break;
|
||||
|
@ -3255,7 +3255,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
|||
str = MSG_ReadString ();
|
||||
if (!str[0])
|
||||
break;
|
||||
if (nummodels==MAX_MODELS)
|
||||
if (nummodels==MAX_PRECACHE_MODELS)
|
||||
{
|
||||
Con_TPrintf ("Server sent too many model precaches\n");
|
||||
return;
|
||||
|
@ -3272,7 +3272,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
|||
str = MSG_ReadString ();
|
||||
if (!str[0])
|
||||
break;
|
||||
if (numsounds==MAX_SOUNDS)
|
||||
if (numsounds==MAX_PRECACHE_SOUNDS)
|
||||
{
|
||||
Con_TPrintf ("Server sent too many sound precaches\n");
|
||||
return;
|
||||
|
@ -3553,7 +3553,7 @@ void CL_ParseSoundlist (qboolean lots)
|
|||
if (!str[0])
|
||||
break;
|
||||
numsounds++;
|
||||
if (numsounds >= MAX_SOUNDS)
|
||||
if (numsounds >= MAX_PRECACHE_SOUNDS)
|
||||
Host_EndGame ("Server sent too many sound_precache");
|
||||
|
||||
// if (strlen(str)>4)
|
||||
|
@ -3626,7 +3626,7 @@ void CL_ParseModellist (qboolean lots)
|
|||
if (!str[0])
|
||||
break;
|
||||
nummodels++;
|
||||
if (nummodels>=MAX_MODELS)
|
||||
if (nummodels>=MAX_PRECACHE_MODELS)
|
||||
Host_EndGame ("Server sent too many model_precache");
|
||||
strcpy (cl.model_name[nummodels], str);
|
||||
|
||||
|
@ -4466,12 +4466,14 @@ void CL_ProcessUserInfo (int slot, player_info_t *player)
|
|||
*/
|
||||
player->model = NULL;
|
||||
|
||||
#ifdef HEXEN2
|
||||
/*if we're running hexen2, they have to be some class...*/
|
||||
player->h2playerclass = atoi(Info_ValueForKey (player->userinfo, "cl_playerclass"));
|
||||
if (player->h2playerclass > 5)
|
||||
player->h2playerclass = 5;
|
||||
if (player->h2playerclass < 1)
|
||||
player->h2playerclass = 1;
|
||||
#endif
|
||||
|
||||
player->colourised = TP_FindColours(player->name);
|
||||
|
||||
|
@ -5625,7 +5627,7 @@ void CL_ParsePrecache(void)
|
|||
switch(code & PC_TYPE)
|
||||
{
|
||||
case PC_MODEL:
|
||||
if (i >= 1 && i < MAX_MODELS)
|
||||
if (i >= 1 && i < MAX_PRECACHE_MODELS)
|
||||
{
|
||||
model_t *model;
|
||||
CL_CheckOrEnqueDownloadFile(s, s, 0);
|
||||
|
@ -5638,12 +5640,12 @@ void CL_ParsePrecache(void)
|
|||
cl.model_precaches_added = true;
|
||||
}
|
||||
else
|
||||
Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS);
|
||||
Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_PRECACHE_MODELS);
|
||||
break;
|
||||
case PC_UNUSED:
|
||||
break;
|
||||
case PC_SOUND:
|
||||
if (i >= 1 && i < MAX_SOUNDS)
|
||||
if (i >= 1 && i < MAX_PRECACHE_SOUNDS)
|
||||
{
|
||||
sfx_t *sfx;
|
||||
if (S_HaveOutput())
|
||||
|
@ -5655,7 +5657,7 @@ void CL_ParsePrecache(void)
|
|||
Q_strncpyz (cl.sound_name[i], s, sizeof(cl.sound_name[i]));
|
||||
}
|
||||
else
|
||||
Con_Printf("svc_precache: sound index %i outside range %i...%i\n", i, 1, MAX_SOUNDS);
|
||||
Con_Printf("svc_precache: sound index %i outside range %i...%i\n", i, 1, MAX_PRECACHE_SOUNDS);
|
||||
break;
|
||||
case PC_PARTICLE:
|
||||
if (i >= 1 && i < MAX_SSPARTICLESPRE)
|
||||
|
|
|
@ -170,7 +170,7 @@ q2trace_t VARGS CLQ2_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end
|
|||
trace_t t;
|
||||
|
||||
// check against world
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, mins, maxs, MASK_PLAYERSOLID, &t);
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, mins, maxs, false, MASK_PLAYERSOLID, &t);
|
||||
if (t.fraction < 1.0)
|
||||
t.ent = (struct edict_s *)1;
|
||||
|
||||
|
@ -406,6 +406,7 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
|
|||
movevars.bunnyspeedcap = cl.bunnyspeedcap;
|
||||
pmove.onladder = false;
|
||||
pmove.safeorigin_known = false;
|
||||
pmove.capsule = false; //FIXME
|
||||
|
||||
VectorCopy(from->szmins, pmove.player_mins);
|
||||
VectorCopy(from->szmaxs, pmove.player_maxs);
|
||||
|
@ -666,7 +667,7 @@ static void CL_DecodeStateSize(unsigned short solid, int modelindex, vec3_t mins
|
|||
{
|
||||
if (solid == ES_SOLID_BSP)
|
||||
{
|
||||
if (modelindex < MAX_MODELS && cl.model_precache[modelindex] && !cl.model_precache[modelindex]->needload)
|
||||
if (modelindex < MAX_PRECACHE_MODELS && cl.model_precache[modelindex] && !cl.model_precache[modelindex]->needload)
|
||||
{
|
||||
VectorCopy(cl.model_precache[modelindex]->mins, mins);
|
||||
VectorCopy(cl.model_precache[modelindex]->maxs, maxs);
|
||||
|
|
|
@ -1094,7 +1094,7 @@ void SCR_CrosshairPosition(playerview_t *pview, float *x, float *y)
|
|||
|
||||
memset(&tr, 0, sizeof(tr));
|
||||
tr.fraction = 1;
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr);
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr);
|
||||
start[2]-=16;
|
||||
if (tr.fraction != 1)
|
||||
{
|
||||
|
|
|
@ -3370,7 +3370,6 @@ entity_t *CL_NewTempEntity (void)
|
|||
ent->playerindex = -1;
|
||||
ent->topcolour = TOP_DEFAULT;
|
||||
ent->bottomcolour = BOTTOM_DEFAULT;
|
||||
ent->h2playerclass = 0;
|
||||
|
||||
#ifdef PEXT_SCALE
|
||||
ent->scale = 1;
|
||||
|
|
|
@ -175,7 +175,9 @@ typedef struct player_info_s
|
|||
struct model_s *model;
|
||||
|
||||
// unsigned short vweapindex;
|
||||
#ifdef HEXEN2
|
||||
unsigned char h2playerclass;
|
||||
#endif
|
||||
|
||||
int prevcount;
|
||||
|
||||
|
@ -724,14 +726,14 @@ typedef struct
|
|||
// information that is static for the entire time connected to a server
|
||||
//
|
||||
char model_name_vwep[MAX_VWEP_MODELS][MAX_QPATH];
|
||||
char model_name[MAX_MODELS][MAX_QPATH];
|
||||
char sound_name[MAX_SOUNDS][MAX_QPATH];
|
||||
char model_name[MAX_PRECACHE_MODELS][MAX_QPATH];
|
||||
char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH];
|
||||
char *particle_ssname[MAX_SSPARTICLESPRE];
|
||||
char image_name[Q2MAX_IMAGES][MAX_QPATH];
|
||||
|
||||
struct model_s *model_precache_vwep[MAX_VWEP_MODELS];
|
||||
struct model_s *model_precache[MAX_MODELS];
|
||||
struct sfx_s *sound_precache[MAX_SOUNDS];
|
||||
struct model_s *model_precache[MAX_PRECACHE_MODELS];
|
||||
struct sfx_s *sound_precache[MAX_PRECACHE_SOUNDS];
|
||||
int particle_ssprecache[MAX_SSPARTICLESPRE]; //these are actually 1-based, so 0 can be used to lazy-init them. I cheat.
|
||||
|
||||
char model_csqcname[MAX_CSMODELS][MAX_QPATH];
|
||||
|
|
|
@ -2034,15 +2034,16 @@ void M_Menu_Main_f (void)
|
|||
}
|
||||
else if (mgt == MGT_HEXEN2)
|
||||
{
|
||||
p = R2D_SafeCachePic("gfx/menu/title0.lmp");
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
m_state = m_complex;
|
||||
Key_Dest_Add(kdm_menu);
|
||||
mainm = M_CreateMenu(0);
|
||||
mainm->key = MC_Main_Key;
|
||||
|
||||
MC_AddPicture(mainm, 16, 0, 35, 176, "gfx/menu/hplaque.lmp");
|
||||
p = R2D_SafeCachePic("gfx/menu/title0.lmp");
|
||||
if (!p)
|
||||
return;
|
||||
MC_AddCenterPicture(mainm, 0, 60, "gfx/menu/title0.lmp");
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "quakedef.h"
|
||||
#include "winquake.h"
|
||||
#include "shader.h"
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
#ifndef CLIENTONLY
|
||||
//=============================================================================
|
||||
/* LOAD/SAVE MENU */
|
||||
|
|
|
@ -185,7 +185,7 @@ void M_PrintWhite (int cx, int cy, qbyte *str)
|
|||
void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable)
|
||||
{
|
||||
int j;
|
||||
|
||||
#ifdef HEXEN2
|
||||
int pc = Cvar_Get("cl_playerclass", "1", 0, "Hexen2")->value;
|
||||
if (h2playertranslations && pc)
|
||||
{
|
||||
|
@ -207,6 +207,7 @@ void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for(j=0;j<255;j++)
|
||||
{
|
||||
|
|
|
@ -3739,7 +3739,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
|
|||
VectorSubtract(org, t2, tangent);
|
||||
VectorAdd(org, t2, t2);
|
||||
|
||||
if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace (cl.worldmodel, 0, 0, NULL, tangent, t2, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr))
|
||||
if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace (cl.worldmodel, 0, 0, NULL, tangent, t2, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr))
|
||||
{
|
||||
if (tr.fraction < dist)
|
||||
{
|
||||
|
|
|
@ -575,7 +575,7 @@ static model_t *CSQC_GetModelForIndex(int index)
|
|||
{
|
||||
if (index == 0)
|
||||
return NULL;
|
||||
else if (index > 0 && index < MAX_MODELS)
|
||||
else if (index > 0 && index < MAX_PRECACHE_MODELS)
|
||||
return cl.model_precache[index];
|
||||
else if (index < 0 && index > -MAX_CSMODELS)
|
||||
{
|
||||
|
@ -1899,7 +1899,7 @@ static int FindModel(const char *name, int *free)
|
|||
if (!strcmp(cl.model_csqcname[i], name))
|
||||
return -i;
|
||||
}
|
||||
for (i = 1; i < MAX_MODELS; i++)
|
||||
for (i = 1; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
if (!strcmp(cl.model_name[i], name))
|
||||
return i;
|
||||
|
@ -1923,7 +1923,7 @@ static void csqc_setmodel(pubprogfuncs_t *prinst, csqcedict_t *ent, int modelind
|
|||
}
|
||||
else
|
||||
{
|
||||
if (modelindex >= MAX_MODELS)
|
||||
if (modelindex >= MAX_PRECACHE_MODELS)
|
||||
return;
|
||||
ent->v->model = PR_SetString(prinst, cl.model_name[modelindex]);
|
||||
model = cl.model_precache[modelindex];
|
||||
|
@ -1981,7 +1981,7 @@ static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalv
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < MAX_MODELS; i++) //Make sure that the server specified model is loaded..
|
||||
for (i = 1; i < MAX_PRECACHE_MODELS; i++) //Make sure that the server specified model is loaded..
|
||||
{
|
||||
if (!*cl.model_name[i])
|
||||
break;
|
||||
|
@ -2531,6 +2531,7 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
|
|||
pmove.cmd.upmove = csqcg.input_movevalues[2];
|
||||
pmove.cmd.buttons = *csqcg.input_buttons;
|
||||
pmove.safeorigin_known = false;
|
||||
pmove.capsule = false; //FIXME
|
||||
|
||||
if (ent)
|
||||
{
|
||||
|
@ -3853,8 +3854,8 @@ void CSQC_PlayerStateToCSQC(int pnum, player_state_t *srcp, csqcedict_t *ent)
|
|||
// ent->v->effects = srcp->effects;
|
||||
}
|
||||
|
||||
unsigned int deltaflags[MAX_MODELS];
|
||||
func_t deltafunction[MAX_MODELS];
|
||||
unsigned int deltaflags[MAX_PRECACHE_MODELS];
|
||||
func_t deltafunction[MAX_PRECACHE_MODELS];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -3878,7 +3879,7 @@ qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state)
|
|||
{
|
||||
func_t func;
|
||||
|
||||
if (!state || state->modelindex <= 0 || state->modelindex >= MAX_MODELS)
|
||||
if (!state || state->modelindex <= 0 || state->modelindex >= MAX_PRECACHE_MODELS)
|
||||
{
|
||||
if (csqcdelta_playerents[playernum])
|
||||
{
|
||||
|
@ -4045,7 +4046,7 @@ static void QCBUILTIN PF_DeltaListen(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
if (!strcmp(mname, "*"))
|
||||
{
|
||||
//yes, even things that are not allocated yet
|
||||
for (i = 0; i < MAX_MODELS; i++)
|
||||
for (i = 0; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
deltafunction[i] = func;
|
||||
deltaflags[i] = flags;
|
||||
|
@ -4053,7 +4054,7 @@ static void QCBUILTIN PF_DeltaListen(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < MAX_MODELS; i++)
|
||||
for (i = 1; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
if (!*cl.model_name[i])
|
||||
break;
|
||||
|
@ -5491,8 +5492,6 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
|
|||
|
||||
csqcentsize = PR_InitEnts(csqcprogs, pr_csqc_maxedicts.value);
|
||||
|
||||
ED_Alloc(csqcprogs); //we need a world entity.
|
||||
|
||||
//world edict becomes readonly
|
||||
worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0);
|
||||
worldent->isfree = false;
|
||||
|
|
|
@ -227,10 +227,10 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
|
|||
{
|
||||
AngleVectors(pe->angles, axis[0], axis[1], axis[2]);
|
||||
VectorNegate(axis[1], axis[1]);
|
||||
pe->model->funcs.NativeTrace(pe->model, 0, 0, axis, ts, te, vec3_origin, vec3_origin, MASK_WORLDSOLID, &trace);
|
||||
pe->model->funcs.NativeTrace(pe->model, 0, 0, axis, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace);
|
||||
}
|
||||
else
|
||||
pe->model->funcs.NativeTrace(pe->model, 0, 0, NULL, ts, te, vec3_origin, vec3_origin, MASK_WORLDSOLID, &trace);
|
||||
pe->model->funcs.NativeTrace(pe->model, 0, 0, NULL, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace);
|
||||
if (trace.fraction<1)
|
||||
{
|
||||
VectorSubtract(trace.endpos, ts, delta);
|
||||
|
|
|
@ -2224,12 +2224,12 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
|
|||
bef = BEF_PUSHDEPTH;
|
||||
if (ent->flags & RF_ADDITIVE)
|
||||
bef |= BEF_FORCEADDITIVE;
|
||||
else if (ent->drawflags & DRF_TRANSLUCENT && r_wateralpha.value != 1)
|
||||
else if ((ent->drawflags & DRF_TRANSLUCENT) && r_wateralpha.value != 1)
|
||||
{
|
||||
bef |= BEF_FORCETRANSPARENT;
|
||||
ent->shaderRGBAf[3] = r_wateralpha.value;
|
||||
}
|
||||
else if (ent->flags & RF_TRANSLUCENT && cls.protocol != CP_QUAKE3)
|
||||
else if ((ent->flags & RF_TRANSLUCENT) && cls.protocol != CP_QUAKE3)
|
||||
bef |= BEF_FORCETRANSPARENT;
|
||||
if (ent->flags & RF_NODEPTHTEST)
|
||||
bef |= BEF_FORCENODEPTH;
|
||||
|
@ -2827,7 +2827,7 @@ void Surf_BuildLightmaps (void)
|
|||
r_oldviewcluster2 = -1;
|
||||
numlightmaps = 0;
|
||||
|
||||
for (j=1 ; j<MAX_MODELS ; j++)
|
||||
for (j=1 ; j<MAX_PRECACHE_MODELS ; j++)
|
||||
{
|
||||
m = cl.model_precache[j];
|
||||
if (!m)
|
||||
|
|
|
@ -104,7 +104,9 @@ typedef struct entity_s
|
|||
int playerindex; //for qw skins
|
||||
int topcolour; //colourmapping
|
||||
int bottomcolour; //colourmapping
|
||||
#ifdef HEXEN2
|
||||
int h2playerclass; //hexen2's quirky colourmapping
|
||||
#endif
|
||||
|
||||
// struct efrag_s *efrag; // linked list of efrags (FIXME)
|
||||
// int visframe; // last frame this entity was
|
||||
|
|
|
@ -1093,9 +1093,11 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
|
|||
BZ_Free(colormap);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (h2playertranslations)
|
||||
BZ_Free(h2playertranslations);
|
||||
h2playertranslations = FS_LoadMallocFile ("gfx/player.lmp");
|
||||
#endif
|
||||
|
||||
if (vid.fullbright < 2)
|
||||
vid.fullbright = 0; //transparent colour doesn't count.
|
||||
|
@ -1183,7 +1185,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
|
|||
SV_UnspawnServer();
|
||||
else if (svs.gametype == GT_PROGS)
|
||||
{
|
||||
for (i = 0; i < MAX_MODELS; i++)
|
||||
for (i = 0; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
if (sv.strings.model_precache[i] && *sv.strings.model_precache[i] && (!strcmp(sv.strings.model_precache[i] + strlen(sv.strings.model_precache[i]) - 4, ".bsp") || i-1 < sv.world.worldmodel->numsubmodels))
|
||||
sv.models[i] = Mod_FindName(sv.strings.model_precache[i]);
|
||||
|
@ -1211,7 +1213,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
|
|||
#ifdef Q2SERVER
|
||||
else if (svs.gametype == GT_QUAKE2)
|
||||
{
|
||||
for (i = 0; i < MAX_MODELS; i++)
|
||||
for (i = 0; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
if (sv.strings.configstring[Q2CS_MODELS+i] && *sv.strings.configstring[Q2CS_MODELS+i] && (!strcmp(sv.strings.configstring[Q2CS_MODELS+i] + strlen(sv.strings.configstring[Q2CS_MODELS+i]) - 4, ".bsp") || i-1 < sv.world.worldmodel->numsubmodels))
|
||||
sv.models[i] = Mod_FindName(sv.strings.configstring[Q2CS_MODELS+i]);
|
||||
|
@ -1276,7 +1278,7 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
|
|||
|
||||
//FIXME: this code should not be here. call CL_LoadModels instead? that does csqc loading etc though. :s
|
||||
TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
|
||||
for (i=1 ; i<MAX_MODELS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_MODELS ; i++)
|
||||
{
|
||||
if (!cl.model_name[i][0])
|
||||
break;
|
||||
|
@ -1364,7 +1366,7 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cl_static_entities[i].mdlidx < MAX_MODELS)
|
||||
if (cl_static_entities[i].mdlidx < MAX_PRECACHE_MODELS)
|
||||
cl_static_entities[i].ent.model = cl.model_precache[cl_static_entities[i].mdlidx];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,9 @@ qboolean sb_showscores;
|
|||
qboolean sb_showteamscores;
|
||||
|
||||
qboolean sbarfailed;
|
||||
#ifdef HEXEN2
|
||||
qboolean sbar_hexen2;
|
||||
#endif
|
||||
|
||||
vrect_t sbar_rect; //screen area that the sbar must fit.
|
||||
float sbar_rect_left;
|
||||
|
@ -832,8 +834,10 @@ void Sbar_Start (void) //if one of these fails, skip the entire status bar.
|
|||
sb_nums[1][i] = Sbar_PicFromWad (va("anum_%i",i));
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (sb_nums[0][0] && sb_nums[0][0]->width < 13)
|
||||
sbar_hexen2 = true;
|
||||
#endif
|
||||
|
||||
sb_nums[0][10] = Sbar_PicFromWad ("num_minus");
|
||||
sb_nums[1][10] = Sbar_PicFromWad ("anum_minus");
|
||||
|
@ -2065,6 +2069,7 @@ void Sbar_DrawScoreboard (void)
|
|||
}
|
||||
|
||||
|
||||
#ifdef HEXEN2
|
||||
static void Sbar_Hexen2DrawActiveStuff(playerview_t *pv)
|
||||
{
|
||||
int x = r_refdef.grect.x + r_refdef.grect.width;
|
||||
|
@ -2368,7 +2373,7 @@ static void Sbar_Hexen2DrawMinimal(playerview_t *pv)
|
|||
|
||||
Sbar_Hexen2DrawNum(38, y+18, pv->stats[STAT_HEALTH], 3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void Sbar_DrawTeamStatus(playerview_t *pv)
|
||||
{
|
||||
|
@ -2593,7 +2598,7 @@ void Sbar_Draw (playerview_t *pv)
|
|||
|
||||
sb_updates++;
|
||||
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (sbar_hexen2)
|
||||
{
|
||||
//hexen2 hud
|
||||
|
@ -2611,7 +2616,9 @@ void Sbar_Draw (playerview_t *pv)
|
|||
|
||||
Sbar_Hexen2DrawActiveStuff(pv);
|
||||
}
|
||||
else if (sbarfailed) //files failed to load.
|
||||
else
|
||||
#endif
|
||||
if (sbarfailed) //files failed to load.
|
||||
{
|
||||
//fallback hud
|
||||
if (pv->stats[STAT_HEALTH] > 0) //when dead, show nothing
|
||||
|
|
|
@ -467,15 +467,19 @@ void Skin_NextDownload (void)
|
|||
{
|
||||
*slash = 0;
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/tris.md2", skinname), NULL, 0);
|
||||
for (j = 0; j < MAX_MODELS; j++)
|
||||
for (j = 1; j < MAX_PRECACHE_MODELS; j++)
|
||||
{
|
||||
if (cl.model_name[j][0] == '#')
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", skinname, cl.model_name[j]+1), NULL, 0);
|
||||
if (!*cl.model_name[j])
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < MAX_SOUNDS; j++)
|
||||
for (j = 1; j < MAX_PRECACHE_SOUNDS; j++)
|
||||
{
|
||||
if (cl.sound_name[j][0] == '*')
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", skinname, cl.sound_name[j]+1), NULL, 0);
|
||||
if (!*cl.sound_name[j])
|
||||
break;
|
||||
}
|
||||
*slash = '/';
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s.pcx", skinname), NULL, 0);
|
||||
|
|
|
@ -1758,7 +1758,7 @@ void S_DoRestart (void)
|
|||
S_StopAllSounds (true);
|
||||
|
||||
|
||||
for (i=1 ; i<MAX_SOUNDS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_SOUNDS ; i++)
|
||||
{
|
||||
if (!cl.sound_name[i][0])
|
||||
break;
|
||||
|
|
|
@ -1165,6 +1165,9 @@ void V_ApplyRefdef (void)
|
|||
V_ApplyAFov(r_refdef.playerview);
|
||||
|
||||
r_refdef.dirty = 0;
|
||||
|
||||
if (chase_active.ival && cls.allow_cheats)
|
||||
CL_EditExternalModels(0, NULL, 0);
|
||||
}
|
||||
|
||||
//if the view entities differ, removes all externalmodel flags except for adding it to the new entity, and removes weaponmodels.
|
||||
|
@ -1304,18 +1307,38 @@ void V_CalcRefdef (playerview_t *pv)
|
|||
loadmodel = cl.worldmodel;
|
||||
}
|
||||
|
||||
if (chase_active.ival)
|
||||
if (chase_active.ival && cls.allow_cheats) //cheat restriction might be lifted some time when any wallhacks are solved.
|
||||
{
|
||||
vec3_t axis[3];
|
||||
vec3_t camorg;
|
||||
vec3_t camorg, camdir;
|
||||
trace_t tr;
|
||||
float len;
|
||||
AngleVectors(r_refdef.viewangles, axis[0], axis[1], axis[2]);
|
||||
VectorMA(r_refdef.vieworg, -chase_back.value, axis[0], camorg);
|
||||
VectorMA(camorg, -chase_up.value, pv->gravitydir, camorg);
|
||||
// if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, r_refdef.vieworg, camorg, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr))
|
||||
VectorCopy(camorg, r_refdef.vieworg);
|
||||
|
||||
CL_EditExternalModels(0, NULL, 0);
|
||||
VectorScale(axis[0], -chase_back.value, camdir);
|
||||
VectorMA(camdir, -chase_up.value, pv->gravitydir, camdir);
|
||||
len = VectorLength(camdir);
|
||||
VectorMA(r_refdef.vieworg, (len+128)/len, camdir, camorg); //push it 128qu further
|
||||
if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace)
|
||||
{
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, r_refdef.vieworg, camorg, vec3_origin, vec3_origin, true, MASK_WORLDSOLID, &tr);
|
||||
if (!tr.startsolid)
|
||||
{
|
||||
float extralen;
|
||||
if (tr.fraction < 1)
|
||||
{
|
||||
//we found a plane, bisect it weirdly to push 4qu infront
|
||||
float d1,d2, frac;
|
||||
VectorMA(r_refdef.vieworg, 1, camdir, camorg);
|
||||
d1 = DotProduct(r_refdef.vieworg, tr.plane.normal) - (tr.plane.dist+4);
|
||||
d2 = DotProduct(camorg, tr.plane.normal) - (tr.plane.dist+4);
|
||||
frac = d1 / (d1-d2);
|
||||
frac = bound(0, frac, 1);
|
||||
VectorMA(r_refdef.vieworg, frac, camdir, r_refdef.vieworg);
|
||||
}
|
||||
else
|
||||
VectorMA(r_refdef.vieworg, 1, camdir, r_refdef.vieworg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1775,7 +1798,7 @@ void V_Init (void)
|
|||
Cvar_Register (&v_contrast, VIEWVARS);
|
||||
Cvar_Register (&v_brightness, VIEWVARS);
|
||||
|
||||
// Cvar_Register (&chase_active, VIEWVARS);
|
||||
// Cvar_Register (&chase_back, VIEWVARS);
|
||||
// Cvar_Register (&chase_up, VIEWVARS);
|
||||
Cvar_Register (&chase_active, VIEWVARS);
|
||||
Cvar_Register (&chase_back, VIEWVARS);
|
||||
Cvar_Register (&chase_up, VIEWVARS);
|
||||
}
|
||||
|
|
|
@ -2479,7 +2479,7 @@ static item_t tp_items[] = {
|
|||
|
||||
#define NUMITEMS (sizeof(tp_items) / sizeof(tp_items[0]))
|
||||
|
||||
static item_t *model2item[MAX_MODELS];
|
||||
static item_t *model2item[MAX_PRECACHE_MODELS];
|
||||
|
||||
static void TP_FindModelNumbers (void)
|
||||
{
|
||||
|
@ -2487,7 +2487,7 @@ static void TP_FindModelNumbers (void)
|
|||
char *s;
|
||||
item_t *item;
|
||||
|
||||
for (i=0 ; i<MAX_MODELS ; i++) {
|
||||
for (i=0 ; i<MAX_PRECACHE_MODELS ; i++) {
|
||||
model2item[i] = NULL;
|
||||
s = cl.model_name[i];
|
||||
if (!s)
|
||||
|
|
|
@ -135,11 +135,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
//#define BOTLIB_STATIC
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
//needs testing on other platforms
|
||||
//#define AVAIL_OPENAL
|
||||
#endif
|
||||
|
||||
#define ODE_DYNAMIC
|
||||
|
||||
#ifdef NO_OPENAL
|
||||
|
@ -223,6 +218,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define Q2CLIENT //client can connect to q2 servers
|
||||
#define Q3CLIENT
|
||||
#define Q3SERVER
|
||||
#define HEXEN2 //technically server only
|
||||
// #define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||
// #define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
|
||||
|
@ -269,6 +265,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#endif
|
||||
|
||||
//#define QUAKETC
|
||||
|
||||
#ifdef QUAKETC
|
||||
#define NOBUILTINMENUS //kill engine menus (should be replaced with ewither csqc or menuqc)
|
||||
#undef Q2CLIENT //not useful
|
||||
|
@ -281,6 +279,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#undef VM_LUA //not useful
|
||||
#undef HALFLIFEMODELS //yuck
|
||||
#undef RUNTIMELIGHTING //presumably not useful
|
||||
#undef HEXEN2
|
||||
#endif
|
||||
|
||||
//#define QUAKESPYAPI //define this if you want the engine to be usable via gamespy/quakespy, which has been dead for a long time now.
|
||||
|
@ -473,7 +472,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// defs common to client and server
|
||||
|
||||
#ifndef PLATFORM
|
||||
#if defined(_WIN32)
|
||||
#if defined(FTE_TARGET_WEB)
|
||||
#define PLATFORM "Web"
|
||||
#elif defined(NACL)
|
||||
#define PLATFORM "Nacl"
|
||||
#elif defined(_WIN32)
|
||||
#if defined(__amd64__)
|
||||
#define PLATFORM "Win64"
|
||||
#else
|
||||
|
@ -619,8 +622,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
#define MAX_LIGHTSTYLES 255
|
||||
#define MAX_STANDARDLIGHTSTYLES 64
|
||||
#define MAX_MODELS 1024 // these are sent over the net as bytes
|
||||
#define MAX_SOUNDS 1024 // so they cannot be blindly increased
|
||||
#define MAX_PRECACHE_MODELS 2048 // these are sent over the net as bytes/shorts
|
||||
#define MAX_PRECACHE_SOUNDS 1024 // so they cannot be blindly increased
|
||||
#define MAX_SSPARTICLESPRE 1024 // precached particle effect names, for server-side pointparticles/trailparticles.
|
||||
#define MAX_VWEP_MODELS 32
|
||||
|
||||
|
|
|
@ -894,7 +894,7 @@ typedef struct
|
|||
typedef struct pvscache_s
|
||||
{
|
||||
int num_leafs;
|
||||
short leafnums[MAX_ENT_LEAFS];
|
||||
unsigned short leafnums[MAX_ENT_LEAFS];
|
||||
#if defined(Q2BSPS) || defined(TERRAIN)
|
||||
int areanum; //q2bsp
|
||||
int areanum2; //q2bsp
|
||||
|
|
|
@ -1463,8 +1463,70 @@ static void Alias_BuildSkeletalVPositionsPose(float *xyzout, skeltype_t bonetype
|
|||
#ifndef SERVERONLY
|
||||
#ifdef GLQUAKE
|
||||
#include "glquake.h"
|
||||
static void Alias_GLDrawSkeletalBones(galiasbone_t *bones, float *bonepose, int bonecount, int basebone)
|
||||
#endif
|
||||
static void Alias_DrawSkeletalBones(galiasbone_t *bones, float *bonepose, int bonecount, int basebone)
|
||||
{
|
||||
#ifndef GLQUAKE
|
||||
scenetris_t *t;
|
||||
int flags = BEF_NODLIGHT|BEF_NOSHADOWS|BEF_LINES;
|
||||
int first;
|
||||
|
||||
if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == flags)
|
||||
t = &cl_stris[cl_numstris-1];
|
||||
else
|
||||
{
|
||||
if (cl_numstris == cl_maxstris)
|
||||
{
|
||||
cl_maxstris += 8;
|
||||
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
|
||||
}
|
||||
t = &cl_stris[cl_numstris++];
|
||||
t->shader = shader;
|
||||
t->numidx = 0;
|
||||
t->numvert = 0;
|
||||
t->firstidx = cl_numstrisidx;
|
||||
t->firstvert = cl_numstrisvert;
|
||||
t->flags = flags;
|
||||
}
|
||||
if (cl_numstrisvert + bonecount*2 > cl_maxstrisvert)
|
||||
{
|
||||
cl_maxstrisvert = cl_numstrisvert + bonecount*2;
|
||||
|
||||
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
|
||||
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert);
|
||||
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert);
|
||||
}
|
||||
if (cl_maxstrisidx < cl_numstrisidx+bonecount*2)
|
||||
{
|
||||
cl_maxstrisidx = cl_numstrisidx+bonecount*2;
|
||||
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
|
||||
}
|
||||
|
||||
first = cl_numstrisvert-t->firstvert;
|
||||
for (i = 0; i < bonecount; i++)
|
||||
{
|
||||
//fixme: transform by model matrix
|
||||
cl_strisvertv[cl_numstrisvert][0] = bonepose[i*12+3];
|
||||
cl_strisvertv[cl_numstrisvert][1] = bonepose[i*12+7];
|
||||
cl_strisvertv[cl_numstrisvert][2] = bonepose[i*12+11];
|
||||
cl_strisvertt[cl_numstrisvert][0] = 0;
|
||||
cl_strisvertt[cl_numstrisvert][1] = 0;
|
||||
cl_strisvertc[cl_numstrisvert][0] = (i < basebone)?0:1;
|
||||
cl_strisvertc[cl_numstrisvert][1] = (i < basebone)?0:0;
|
||||
cl_strisvertc[cl_numstrisvert][2] = (i < basebone)?1:0;
|
||||
cl_strisvertc[cl_numstrisvert][3] = 1;
|
||||
cl_numstrisvert++;
|
||||
|
||||
p = bones[i].parent;
|
||||
if (p < 0)
|
||||
p = 0;
|
||||
cl_strisidx[cl_numstrisidx++] = first+i;
|
||||
cl_strisidx[cl_numstrisidx++] = first+p;
|
||||
}
|
||||
|
||||
t->numvert += bonecount;
|
||||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
#else
|
||||
PPL_RevertToKnownState();
|
||||
BE_SelectEntity(currententity);
|
||||
qglColor3f(1, 0, 0);
|
||||
|
@ -1529,8 +1591,8 @@ static void Alias_GLDrawSkeletalBones(galiasbone_t *bones, float *bonepose, int
|
|||
*/
|
||||
// mesh->numindexes = 0; //don't draw this mesh, as that would obscure the bones. :(
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif //GLQUAKE
|
||||
#endif //!SERVERONLY
|
||||
#endif //SKELETALMODELS
|
||||
|
||||
|
@ -1723,7 +1785,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
|
|||
meshcache.usebonepose = Alias_GetBoneInformation(inf, &e->framestate, meshcache.bonecachetype=SKEL_ABSOLUTE, meshcache.boneposebuffer1, meshcache.boneposebuffer2, MAX_BONES);
|
||||
if (qrenderer == QR_OPENGL)
|
||||
{
|
||||
Alias_GLDrawSkeletalBones(inf->ofsbones, (float *)meshcache.usebonepose, inf->numbones, e->framestate.g[0].endbone);
|
||||
Alias_DrawSkeletalBones(inf->ofsbones, (float *)meshcache.usebonepose, inf->numbones, e->framestate.g[0].endbone);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2042,7 +2104,7 @@ qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, v
|
|||
}
|
||||
|
||||
//The whole reason why model loading is supported in the server.
|
||||
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentsmask, trace_t *trace)
|
||||
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace)
|
||||
{
|
||||
galiasinfo_t *mod = Mod_Extradata(model);
|
||||
galiasgroup_t *group;
|
||||
|
@ -2592,6 +2654,7 @@ extern float r_avertexnormals[NUMVERTEXNORMALS][3];
|
|||
static void Alias_LoadPose(vecV_t *verts, vec3_t *normals, vec3_t *svec, vec3_t *tvec, dtrivertx_t *pinframe, int *seamremaps, int mdltype)
|
||||
{
|
||||
int j;
|
||||
#ifdef HEXEN2
|
||||
if (mdltype == 2)
|
||||
{
|
||||
for (j = 0; j < galias->numverts; j++)
|
||||
|
@ -2605,6 +2668,7 @@ static void Alias_LoadPose(vecV_t *verts, vec3_t *normals, vec3_t *svec, vec3_t
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (j = 0; j < pq1inmodel->numverts; j++)
|
||||
{
|
||||
|
@ -3062,7 +3126,6 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
int i, onseams;
|
||||
dstvert_t *pinstverts;
|
||||
dtriangle_t *pinq1triangles;
|
||||
dh2triangle_t *pinh2triangles;
|
||||
int *seamremap;
|
||||
index_t *indexes;
|
||||
daliasskintype_t *skinstart;
|
||||
|
@ -3072,7 +3135,10 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
unsigned int hdrsize;
|
||||
void *end;
|
||||
qboolean qtest = false;
|
||||
#ifdef HEXEN2
|
||||
dh2triangle_t *pinh2triangles;
|
||||
qboolean rapo = false;
|
||||
#endif
|
||||
|
||||
loadmodel=mod;
|
||||
|
||||
|
@ -3088,11 +3154,13 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
hdrsize = (size_t)&((dmdl_t*)NULL)->flags;
|
||||
qtest = true;
|
||||
}
|
||||
#ifdef HEXEN2
|
||||
else if (version == 50)
|
||||
{
|
||||
hdrsize = sizeof(dmdl_t);
|
||||
rapo = true;
|
||||
}
|
||||
#endif
|
||||
else if (version != ALIAS_VERSION)
|
||||
{
|
||||
Con_Printf (CON_ERROR "%s has wrong version number (%i should be %i)\n",
|
||||
|
@ -3162,6 +3230,7 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (rapo)
|
||||
{
|
||||
/*each triangle can use one coord and one st, for each vert, that's a lot of combinations*/
|
||||
|
@ -3248,6 +3317,7 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
BZ_Free(seamremap);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/*onseam means +=skinwidth/2
|
||||
verticies that are marked as onseam potentially generate two output verticies.
|
||||
|
@ -7206,7 +7276,9 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
|
|||
void Alias_Register(void)
|
||||
{
|
||||
Mod_RegisterModelFormatMagic(NULL, "Quake1 Model (mdl)", IDPOLYHEADER, Mod_LoadQ1Model);
|
||||
#ifdef HEXEN2
|
||||
Mod_RegisterModelFormatMagic(NULL, "Hexen2 Model (mdl)", RAPOLYHEADER, Mod_LoadQ1Model);
|
||||
#endif
|
||||
#ifdef MD2MODELS
|
||||
Mod_RegisterModelFormatMagic(NULL, "Quake2 Model (md2)", MD2IDALIASHEADER, Mod_LoadQ2Model);
|
||||
#endif
|
||||
|
|
|
@ -96,25 +96,7 @@ cvar_t com_modname = CVARD("com_modname", "", "dpmaster information");
|
|||
cvar_t com_parseutf8 = CVARD("com_parseutf8", "0", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
|
||||
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
|
||||
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger remote exploits in any engine (including "FULLENGINENAME"which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.\n");
|
||||
#ifdef FTE_TARGET_WEB
|
||||
cvar_t sys_platform = CVAR("sys_platform", "web");
|
||||
#elif defined(NACL)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "nacl");
|
||||
#elif defined(ANDROID)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "android");
|
||||
#elif defined(FTE_SDL)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "sdl");
|
||||
#elif defined(_WIN64)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "win64");
|
||||
#elif defined(_WIN32)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "win32");
|
||||
#elif defined(__linux__)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "linux");
|
||||
#elif defined(__APPLE__)
|
||||
cvar_t sys_platform = CVAR("sys_platform", "mac");
|
||||
#else
|
||||
cvar_t sys_platform = CVAR("sys_platform", "");
|
||||
#endif
|
||||
cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
|
||||
|
||||
qboolean com_modified; // set true if using non-id files
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ qboolean Mod_LoadSurfedges (lump_t *l);
|
|||
void Mod_LoadLighting (lump_t *l);
|
||||
|
||||
|
||||
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace);
|
||||
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace);
|
||||
static unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
|
||||
static unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p);
|
||||
static int CM_PointCluster (model_t *mod, vec3_t p);
|
||||
|
@ -180,7 +180,12 @@ qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out);
|
|||
extern model_t *loadmodel;
|
||||
extern qbyte *mod_base;
|
||||
|
||||
|
||||
#define capsuledist(dist,plane,mins,maxs) \
|
||||
case shape_iscapsule: \
|
||||
dist = DotProduct(trace_up, plane->normal); \
|
||||
dist = dist*(trace_capsulesize[(dist<0)?1:2]) - trace_capsulesize[0]; \
|
||||
dist = plane->dist - dist; \
|
||||
break;
|
||||
|
||||
|
||||
unsigned char d_q28to24table[1024];
|
||||
|
@ -4796,12 +4801,19 @@ static vec3_t trace_start, trace_end;
|
|||
static vec3_t trace_mins, trace_maxs;
|
||||
static vec3_t trace_extents;
|
||||
static vec3_t trace_absmins, trace_absmaxs;
|
||||
static vec3_t trace_up; //capsule points upwards in this direction
|
||||
static vec3_t trace_capsulesize; //radius, up, down
|
||||
static float trace_truefraction;
|
||||
static float trace_nearfraction;
|
||||
|
||||
static trace_t trace_trace;
|
||||
static int trace_contents;
|
||||
static qboolean trace_ispoint; // optimized case
|
||||
static enum
|
||||
{
|
||||
shape_isbox,
|
||||
shape_iscapsule,
|
||||
shape_ispoint
|
||||
} trace_shape; // optimized case
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -4838,11 +4850,10 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
|
|||
side = brush->brushside+i;
|
||||
plane = side->plane;
|
||||
|
||||
// FIXME: special case for axial
|
||||
|
||||
if (!trace_ispoint)
|
||||
{ // general box case
|
||||
|
||||
switch(trace_shape)
|
||||
{
|
||||
default:
|
||||
case shape_isbox: // general box case
|
||||
// push the plane out apropriately for mins/maxs
|
||||
|
||||
// FIXME: use signbits into 8 way lookup for each mins/maxs
|
||||
|
@ -4855,10 +4866,11 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
|
|||
}
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
}
|
||||
else
|
||||
{ // special point case
|
||||
break;
|
||||
capsuledist(dist,plane,mins,maxs)
|
||||
case shape_ispoint: // special point case
|
||||
dist = plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
d1 = DotProduct (p1, plane->normal) - dist;
|
||||
|
@ -4953,12 +4965,13 @@ static void CM_ClipBoxToPlanes (vec3_t trmins, vec3_t trmaxs, vec3_t p1, vec3_t
|
|||
|
||||
for (i=0 ; i<numplanes ; i++, plane++)
|
||||
{
|
||||
// FIXME: special case for axial
|
||||
if (!trace_ispoint)
|
||||
{ // general box case
|
||||
|
||||
switch(trace_shape)
|
||||
{
|
||||
default:
|
||||
case shape_isbox: // general box case
|
||||
// push the plane out apropriately for mins/maxs
|
||||
|
||||
// FIXME: special case for axial
|
||||
// FIXME: use signbits into 8 way lookup for each mins/maxs
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
|
@ -4969,10 +4982,11 @@ static void CM_ClipBoxToPlanes (vec3_t trmins, vec3_t trmaxs, vec3_t p1, vec3_t
|
|||
}
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
}
|
||||
else
|
||||
{ // special point case
|
||||
break;
|
||||
capsuledist(dist,plane,trmins,trmaxs)
|
||||
case shape_ispoint: // special point case
|
||||
dist = plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
d1 = DotProduct (p1, plane->normal) - dist;
|
||||
|
@ -5187,11 +5201,11 @@ static void CM_ClipBoxToPatch (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
|
|||
side = brush->brushside+i;
|
||||
plane = side->plane;
|
||||
|
||||
if (!trace_ispoint)
|
||||
{ // general box case
|
||||
|
||||
// push the plane out apropriately for mins/maxs
|
||||
|
||||
switch(trace_shape)
|
||||
{
|
||||
default:
|
||||
case shape_isbox: // general box case
|
||||
// FIXME: use signbits into 8 way lookup for each mins/maxs
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
|
@ -5202,10 +5216,11 @@ static void CM_ClipBoxToPatch (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
|
|||
}
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
}
|
||||
else
|
||||
{ // special point case
|
||||
break;
|
||||
capsuledist(dist,plane,mins,maxs)
|
||||
case shape_ispoint: // special point case
|
||||
dist = plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
d1 = DotProduct (p1, plane->normal) - dist;
|
||||
|
@ -5290,9 +5305,10 @@ static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1,
|
|||
side = brush->brushside+i;
|
||||
plane = side->plane;
|
||||
|
||||
// FIXME: special case for axial
|
||||
|
||||
// general box case
|
||||
switch(trace_shape)
|
||||
{
|
||||
default:
|
||||
case shape_isbox: // general box case
|
||||
|
||||
// push the plane out apropriately for mins/maxs
|
||||
|
||||
|
@ -5306,6 +5322,12 @@ static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1,
|
|||
}
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
break;
|
||||
capsuledist(dist,plane,mins,maxs)
|
||||
case shape_ispoint:
|
||||
dist = plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
d1 = DotProduct (p1, plane->normal) - dist;
|
||||
|
||||
|
@ -5339,6 +5361,10 @@ static void CM_TestBoxInPatch (vec3_t mins, vec3_t maxs, vec3_t p1,
|
|||
side = brush->brushside+i;
|
||||
plane = side->plane;
|
||||
|
||||
switch(trace_shape)
|
||||
{
|
||||
default:
|
||||
case shape_isbox:
|
||||
// general box case
|
||||
|
||||
// push the plane out apropriately for mins/maxs
|
||||
|
@ -5354,6 +5380,12 @@ static void CM_TestBoxInPatch (vec3_t mins, vec3_t maxs, vec3_t p1,
|
|||
|
||||
dist = DotProduct (ofs, plane->normal);
|
||||
dist = plane->dist - dist;
|
||||
break;
|
||||
capsuledist(dist,plane,mins,maxs)
|
||||
case shape_ispoint:
|
||||
dist = plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
d1 = DotProduct (p1, plane->normal) - dist;
|
||||
|
||||
|
@ -5567,7 +5599,7 @@ static void CM_RecursiveHullCheck (model_t *mod, int num, float p1f, float p2f,
|
|||
{
|
||||
t1 = DotProduct (plane->normal, p1) - plane->dist;
|
||||
t2 = DotProduct (plane->normal, p2) - plane->dist;
|
||||
if (trace_ispoint)
|
||||
if (trace_shape == shape_ispoint)
|
||||
offset = 0;
|
||||
else
|
||||
offset = fabs(trace_extents[0]*plane->normal[0]) +
|
||||
|
@ -5651,7 +5683,7 @@ CM_BoxTrace
|
|||
==================
|
||||
*/
|
||||
static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
||||
vec3_t mins, vec3_t maxs,
|
||||
vec3_t mins, vec3_t maxs, qboolean capsule,
|
||||
int brushmask)
|
||||
{
|
||||
int i;
|
||||
|
@ -5679,6 +5711,43 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
|
||||
// build a bounding box of the entire move (for patches)
|
||||
ClearBounds (trace_absmins, trace_absmaxs);
|
||||
|
||||
//determine the type of trace that we're going to use, and the max extents
|
||||
if (trace_mins[0] == 0 && trace_mins[1] == 0 && trace_mins[2] == 0 && trace_maxs[0] == 0 && trace_maxs[1] == 0 && trace_maxs[2] == 0)
|
||||
{
|
||||
trace_shape = shape_ispoint;
|
||||
VectorSet (trace_extents, 1/32.0, 1/32.0, 1/32.0);
|
||||
//acedemic
|
||||
AddPointToBounds (start, trace_absmins, trace_absmaxs);
|
||||
AddPointToBounds (end, trace_absmins, trace_absmaxs);
|
||||
}
|
||||
else if (capsule)
|
||||
{
|
||||
float ext;
|
||||
trace_shape = shape_iscapsule;
|
||||
//determine the capsule sizes
|
||||
trace_capsulesize[0] = ((maxs[0]-mins[0]) + (maxs[1]-mins[1]))/4.0;
|
||||
trace_capsulesize[1] = maxs[2];
|
||||
trace_capsulesize[2] = mins[2];
|
||||
ext = (trace_capsulesize[1] > -trace_capsulesize[2])?trace_capsulesize[1]:-trace_capsulesize[2];
|
||||
trace_capsulesize[1] -= trace_capsulesize[0];
|
||||
trace_capsulesize[2] += trace_capsulesize[0];
|
||||
trace_extents[0] = ext+1;
|
||||
trace_extents[1] = ext+1;
|
||||
trace_extents[2] = ext+1;
|
||||
|
||||
//determine the total range
|
||||
VectorSubtract (start, trace_extents, point);
|
||||
AddPointToBounds (point, trace_absmins, trace_absmaxs);
|
||||
VectorAdd (start, trace_extents, point);
|
||||
AddPointToBounds (point, trace_absmins, trace_absmaxs);
|
||||
VectorSubtract (end, trace_extents, point);
|
||||
AddPointToBounds (point, trace_absmins, trace_absmaxs);
|
||||
VectorAdd (end, trace_extents, point);
|
||||
AddPointToBounds (point, trace_absmins, trace_absmaxs);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd (start, trace_mins, point);
|
||||
AddPointToBounds (point, trace_absmins, trace_absmaxs);
|
||||
VectorAdd (start, trace_maxs, point);
|
||||
|
@ -5688,6 +5757,13 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
VectorAdd (end, trace_maxs, point);
|
||||
AddPointToBounds (point, trace_absmins, trace_absmaxs);
|
||||
|
||||
trace_shape = shape_isbox;
|
||||
trace_extents[0] = ((-trace_mins[0] > trace_maxs[0]) ? -trace_mins[0] : trace_maxs[0])+1;
|
||||
trace_extents[1] = ((-trace_mins[1] > trace_maxs[1]) ? -trace_mins[1] : trace_maxs[1])+1;
|
||||
trace_extents[2] = ((-trace_mins[2] > trace_maxs[2]) ? -trace_mins[2] : trace_maxs[2])+1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (0)
|
||||
{ //treat *ALL* tests against the actual geometry instead of using any brushes.
|
||||
//also ignores the bsp etc. not fast. testing only.
|
||||
|
@ -5710,6 +5786,7 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
CM_TraceToLeaf(&mod->leafs[i]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
//
|
||||
// check for position test special case
|
||||
//
|
||||
|
@ -5739,24 +5816,10 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
return trace_trace;
|
||||
}
|
||||
//
|
||||
// check for point special case
|
||||
//
|
||||
else if (trace_mins[0] == 0 && trace_mins[1] == 0 && trace_mins[2] == 0
|
||||
&& trace_maxs[0] == 0 && trace_maxs[1] == 0 && trace_maxs[2] == 0)
|
||||
{
|
||||
trace_ispoint = true;
|
||||
VectorClear (trace_extents);
|
||||
CM_RecursiveHullCheck (mod, mod->hulls[0].firstclipnode, 0, 1, trace_start, trace_end);
|
||||
}
|
||||
//
|
||||
// general aabb trace
|
||||
//
|
||||
else
|
||||
{
|
||||
trace_ispoint = false;
|
||||
trace_extents[0] = ((-trace_mins[0] > trace_maxs[0]) ? -trace_mins[0] : trace_maxs[0])+1;
|
||||
trace_extents[1] = ((-trace_mins[1] > trace_maxs[1]) ? -trace_mins[1] : trace_maxs[1])+1;
|
||||
trace_extents[2] = ((-trace_mins[2] > trace_maxs[2]) ? -trace_mins[2] : trace_maxs[2])+1;
|
||||
CM_RecursiveHullCheck (mod, mod->hulls[0].firstclipnode, 0, 1, trace_start, trace_end);
|
||||
}
|
||||
|
||||
|
@ -5776,7 +5839,7 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
return trace_trace;
|
||||
}
|
||||
|
||||
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace)
|
||||
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace)
|
||||
{
|
||||
if (axis)
|
||||
{
|
||||
|
@ -5788,12 +5851,13 @@ static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3
|
|||
end_l[0] = DotProduct(end, axis[0]);
|
||||
end_l[1] = DotProduct(end, axis[1]);
|
||||
end_l[2] = DotProduct(end, axis[2]);
|
||||
*trace = CM_BoxTrace(model, start_l, end_l, mins, maxs, contents);
|
||||
VectorSet(trace_up, axis[0][2], -axis[1][2], axis[2][2]);
|
||||
*trace = CM_BoxTrace(model, start_l, end_l, mins, maxs, capsule, contents);
|
||||
#ifdef TERRAIN
|
||||
if (model->terrain)
|
||||
{
|
||||
trace_t hmt;
|
||||
Heightmap_Trace(model, forcehullnum, frame, NULL, start, end, mins, maxs, contents, &hmt);
|
||||
Heightmap_Trace(model, forcehullnum, frame, NULL, start, end, mins, maxs, capsule, contents, &hmt);
|
||||
if (hmt.fraction < trace->fraction)
|
||||
*trace = hmt;
|
||||
}
|
||||
|
@ -5819,12 +5883,13 @@ static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3
|
|||
}
|
||||
else
|
||||
{
|
||||
*trace = CM_BoxTrace(model, start, end, mins, maxs, contents);
|
||||
VectorSet(trace_up, 0, 0, 1);
|
||||
*trace = CM_BoxTrace(model, start, end, mins, maxs, capsule, contents);
|
||||
#ifdef TERRAIN
|
||||
if (model->terrain)
|
||||
{
|
||||
trace_t hmt;
|
||||
Heightmap_Trace(model, forcehullnum, frame, NULL, start, end, mins, maxs, contents, &hmt);
|
||||
Heightmap_Trace(model, forcehullnum, frame, NULL, start, end, mins, maxs, capsule, contents, &hmt);
|
||||
if (hmt.fraction < trace->fraction)
|
||||
*trace = hmt;
|
||||
}
|
||||
|
@ -5860,6 +5925,7 @@ trace_t CM_TransformedBoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
vec3_t forward, right, up;
|
||||
vec3_t temp;
|
||||
qboolean rotated;
|
||||
qboolean capsule = false;
|
||||
|
||||
// subtract origin offset
|
||||
VectorSubtract (start, origin, start_l);
|
||||
|
@ -5885,10 +5951,16 @@ trace_t CM_TransformedBoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
end_l[0] = DotProduct (temp, forward);
|
||||
end_l[1] = -DotProduct (temp, right);
|
||||
end_l[2] = DotProduct (temp, up);
|
||||
|
||||
VectorSet(trace_up, forward[2], -right[2], up[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet(trace_up, 0, 0, 1);
|
||||
}
|
||||
|
||||
// sweep the box through the model
|
||||
trace = CM_BoxTrace (mod, start_l, end_l, mins, maxs, brushmask);
|
||||
trace = CM_BoxTrace (mod, start_l, end_l, mins, maxs, capsule, brushmask);
|
||||
|
||||
if (rotated && trace.fraction != 1.0)
|
||||
{
|
||||
|
|
|
@ -921,7 +921,7 @@ void PM_CategorizePosition (void)
|
|||
|
||||
VectorMA (pmove.origin, 24, flatforward, fwd1);
|
||||
|
||||
pmove.physents[0].model->funcs.NativeTrace(pmove.physents[0].model, 0, 0, NULL, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, MASK_PLAYERSOLID, &t);
|
||||
pmove.physents[0].model->funcs.NativeTrace(pmove.physents[0].model, 0, 0, NULL, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, pmove.capsule, MASK_PLAYERSOLID, &t);
|
||||
if (t.surface && t.surface->flags & Q3SURF_LADDER)
|
||||
{
|
||||
pmove.onladder = true;
|
||||
|
|
|
@ -67,6 +67,7 @@ typedef struct
|
|||
int pm_type;
|
||||
vec3_t player_mins;
|
||||
vec3_t player_maxs;
|
||||
qboolean capsule;
|
||||
|
||||
// world state
|
||||
int numphysent;
|
||||
|
|
|
@ -226,7 +226,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
|
|||
{
|
||||
AngleVectors (angles, axis[0], axis[1], axis[2]);
|
||||
VectorNegate(axis[1], axis[1]);
|
||||
model->funcs.NativeTrace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, MASK_PLAYERSOLID, trace);
|
||||
model->funcs.NativeTrace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, pmove.capsule, MASK_PLAYERSOLID, trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -237,7 +237,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
|
|||
if (start_l[i]+player_maxs[i] < model->mins[i] && end_l[i] + player_maxs[i] < model->mins[i])
|
||||
return false;
|
||||
}
|
||||
model->funcs.NativeTrace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, MASK_PLAYERSOLID, trace);
|
||||
model->funcs.NativeTrace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, pmove.capsule, MASK_PLAYERSOLID, trace);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3911,11 +3911,7 @@ void QCBUILTIN PF_argescape(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
|
||||
void QCBUILTIN PF_random (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float num;
|
||||
|
||||
num = (rand ()&0x7fff) / ((float)0x8000);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = num;
|
||||
G_FLOAT(OFS_RETURN) = (rand ()&0x7fff) / ((float)0x8000);
|
||||
}
|
||||
|
||||
//float(float number, float quantity) bitshift = #218;
|
||||
|
@ -4284,15 +4280,14 @@ void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
//float(vector) vlen
|
||||
void QCBUILTIN PF_vlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float *value1;
|
||||
float newv;
|
||||
|
||||
value1 = G_VECTOR(OFS_PARM0);
|
||||
|
||||
newv = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
|
||||
newv = sqrt(newv);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = newv;
|
||||
float *value1 = G_VECTOR(OFS_PARM0);
|
||||
G_FLOAT(OFS_RETURN) = sqrt(DotProduct(value1, value1));
|
||||
}
|
||||
//float(vector) vhlen
|
||||
void QCBUILTIN PF_vhlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float *value1 = G_VECTOR(OFS_PARM0);
|
||||
G_FLOAT(OFS_RETURN) = sqrt(DotProduct2(value1, value1));
|
||||
}
|
||||
|
||||
//vector vectoangles(vector)
|
||||
|
|
|
@ -144,6 +144,7 @@ void QCBUILTIN PF_fputs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
|
|||
void QCBUILTIN PF_fgets (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_normalize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_vlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_vhlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
@ -435,8 +436,8 @@ void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored);
|
|||
|
||||
/*these are server ones, provided by pr_cmds.c, as required by pr_q1qvm.c*/
|
||||
#ifdef VM_Q1
|
||||
void PR_SV_FillWorldGlobals(world_t *w);
|
||||
model_t *SVPR_GetCModel(world_t *w, int modelindex);
|
||||
void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o);
|
||||
void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "pr_common.h"
|
||||
|
||||
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentmask, trace_t *trace);
|
||||
/*
|
||||
|
||||
============================================================================
|
||||
|
@ -840,7 +839,7 @@ hull_t *Q1BSP_ChooseHull(model_t *model, int forcehullnum, vec3_t mins, vec3_t m
|
|||
VectorSubtract (hull->clip_mins, mins, offset);
|
||||
return hull;
|
||||
}
|
||||
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, trace_t *trace)
|
||||
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int hitcontentsmask, trace_t *trace)
|
||||
{
|
||||
hull_t *hull;
|
||||
vec3_t start_l, end_l;
|
||||
|
@ -942,7 +941,7 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3]
|
|||
if (model->terrain && trace->fraction)
|
||||
{
|
||||
trace_t hmt;
|
||||
Heightmap_Trace(model, forcehullnum, frame, axis, start, end, mins, maxs, hitcontentsmask, &hmt);
|
||||
Heightmap_Trace(model, forcehullnum, frame, axis, start, end, mins, maxs, capsule, hitcontentsmask, &hmt);
|
||||
if (hmt.fraction < trace->fraction)
|
||||
*trace = hmt;
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ void TL_InitLanguages(void)
|
|||
|
||||
|
||||
|
||||
//#ifndef CLIENTONLY
|
||||
#ifdef HEXEN2
|
||||
//this stuff is for hexen2 translation strings.
|
||||
//(hexen2 is uuuuggllyyyy...)
|
||||
static char *strings_list;
|
||||
|
@ -213,7 +213,6 @@ char *T_GetString(int num)
|
|||
|
||||
return strings_table[num];
|
||||
}
|
||||
//#endif
|
||||
|
||||
#ifndef SERVERONLY
|
||||
//for hexen2's objectives and stuff.
|
||||
|
@ -281,6 +280,7 @@ char *T_GetInfoString(int num)
|
|||
return info_strings_table[num];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct poline_s
|
||||
{
|
||||
|
|
|
@ -248,6 +248,8 @@ int World_PointContents (world_t *w, vec3_t p);
|
|||
|
||||
wedict_t *World_TestEntityPosition (world_t *w, wedict_t *ent);
|
||||
|
||||
qboolean World_TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, struct trace_s *trace, vec3_t origin, vec3_t angles, unsigned int hitcontentsmask);
|
||||
|
||||
/*
|
||||
World_Move:
|
||||
mins and maxs are reletive
|
||||
|
|
|
@ -2743,6 +2743,7 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
|
|||
|
||||
if (e->scale != 1 && e->scale != 0) //hexen 2 stuff
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
float z;
|
||||
float escale;
|
||||
escale = e->scale;
|
||||
|
@ -2778,6 +2779,11 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
VectorScale((m+0), e->scale, (m+0));
|
||||
VectorScale((m+4), e->scale, (m+4));
|
||||
VectorScale((m+8), e->scale, (m+8));
|
||||
#endif
|
||||
}
|
||||
else if (mod && !strcmp(mod->name, "progs/eyes.mdl"))
|
||||
{
|
||||
|
|
|
@ -2614,6 +2614,7 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
|
|||
|
||||
if (e->scale != 1 && e->scale != 0) //hexen 2 stuff
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
float z;
|
||||
float escale;
|
||||
escale = e->scale;
|
||||
|
@ -2649,6 +2650,11 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
VectorScale((m+0), e->scale, (m+0));
|
||||
VectorScale((m+4), e->scale, (m+4));
|
||||
VectorScale((m+8), e->scale, (m+8));
|
||||
#endif
|
||||
}
|
||||
else if (mod && !strcmp(mod->name, "progs/eyes.mdl"))
|
||||
{
|
||||
|
|
|
@ -601,7 +601,11 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
}
|
||||
tc = e->topcolour;
|
||||
bc = e->bottomcolour;
|
||||
#ifdef HEXEN2
|
||||
pc = e->h2playerclass;
|
||||
#else
|
||||
pc = 0;
|
||||
#endif
|
||||
|
||||
if (forced || tc != TOP_DEFAULT || bc != BOTTOM_DEFAULT || plskin)
|
||||
{
|
||||
|
@ -690,7 +694,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
Hash_Add(&skincolourmapped, cm->name, cm, &cm->bucket);
|
||||
cm->tcolour = tc;
|
||||
cm->bcolour = bc;
|
||||
cm->pclass = pc;
|
||||
cm->pclass = pc; //is this needed? surely it'll be baked as part of the modelname?
|
||||
cm->skinnum = e->skinnum;
|
||||
cm->subframe = subframe;
|
||||
cm->texnum.fullbright = r_nulltex;
|
||||
|
@ -828,6 +832,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
if (scaled_height < 4)
|
||||
scaled_height = 4;
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (h2playertranslations && pc)
|
||||
{
|
||||
unsigned int color_offsets[5] = {2*14*256,0,1*14*256,2*14*256,2*14*256};
|
||||
|
@ -847,6 +852,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
translate32[0] = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (i=0 ; i<256 ; i++)
|
||||
translate32[i] = d_8to24rgbtable[i];
|
||||
|
|
|
@ -3200,6 +3200,7 @@ typedef struct {
|
|||
vec4_t plane;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
qboolean capsule;
|
||||
float frac;
|
||||
float htilesize;
|
||||
heightmap_t *hm;
|
||||
|
@ -3357,7 +3358,7 @@ static void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
|
|||
//do the trace
|
||||
memset(&etr, 0, sizeof(etr));
|
||||
etr.fraction = 1;
|
||||
model->funcs.NativeTrace (model, 0, frame, s->ents[i]->ent.axis, start_l, end_l, tr->mins, tr->maxs, tr->hitcontentsmask, &etr);
|
||||
model->funcs.NativeTrace (model, 0, frame, s->ents[i]->ent.axis, start_l, end_l, tr->mins, tr->maxs, tr->capsule, tr->hitcontentsmask, &etr);
|
||||
|
||||
tr->result->startsolid |= etr.startsolid;
|
||||
tr->result->allsolid |= etr.allsolid;
|
||||
|
@ -3528,7 +3529,7 @@ Why is recursion good?
|
|||
|
||||
Obviously, we don't care all that much about 1
|
||||
*/
|
||||
qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec3_t mataxis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace)
|
||||
qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec3_t mataxis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
|
||||
{
|
||||
vec2_t pos, npos;
|
||||
qboolean nudge[2];
|
||||
|
@ -3551,6 +3552,7 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
|
|||
hmtrace.plane[1] = 0;
|
||||
hmtrace.plane[2] = 0;
|
||||
hmtrace.plane[3] = 0;
|
||||
hmtrace.capsule = capsule;
|
||||
|
||||
memset(trace, 0, sizeof(*trace));
|
||||
trace->fraction = 1;
|
||||
|
|
|
@ -205,7 +205,7 @@ typedef struct {
|
|||
unsigned int (*BoxContents) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
|
||||
|
||||
//deals with whatever is native for the bsp (gamecode is expected to distinguish this).
|
||||
qboolean (*NativeTrace) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace);
|
||||
qboolean (*NativeTrace) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace);
|
||||
unsigned int (*NativeContents)(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
|
||||
|
||||
unsigned int (*FatPVS) (struct model_s *model, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean merge);
|
||||
|
@ -499,7 +499,6 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen
|
|||
|
||||
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
|
||||
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, struct trace_s *trace);
|
||||
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
|
||||
qbyte *Q1BSP_LeafPVS (struct model_s *model, mleaf_t *leaf, qbyte *buffer, unsigned int buffersize);
|
||||
|
||||
|
@ -976,7 +975,7 @@ void Terr_FreeModel(model_t *mod);
|
|||
void Terr_PurgeTerrainModel(model_t *hm, qboolean lightmapsonly, qboolean lightmapreusable);
|
||||
void *Mod_LoadTerrainInfo(model_t *mod, char *loadname, qboolean force); //call this after loading a bsp
|
||||
qboolean Terrain_LocateSection(char *name, flocation_t *loc); //used on servers to generate sections for download.
|
||||
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentmask, struct trace_s *trace);
|
||||
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentmask, struct trace_s *trace);
|
||||
unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org);
|
||||
struct fragmentdecal_s;
|
||||
void Terrain_ClipDecal(struct fragmentdecal_s *dec, float *center, float radius, model_t *model);
|
||||
|
|
|
@ -312,6 +312,7 @@ void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const mod
|
|||
|
||||
if (e->scale != 1 && e->scale != 0) //hexen 2 stuff
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
float z;
|
||||
float escale;
|
||||
escale = e->scale;
|
||||
|
@ -347,6 +348,11 @@ void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const mod
|
|||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
VectorScale((m+0), e->scale, (m+0));
|
||||
VectorScale((m+4), e->scale, (m+4));
|
||||
VectorScale((m+8), e->scale, (m+8));
|
||||
#endif
|
||||
}
|
||||
else if (mod && !strcmp(mod->name, "progs/eyes.mdl"))
|
||||
{
|
||||
|
|
|
@ -61,7 +61,7 @@ vec_t CastRay (vec3_t p1, vec3_t p2)
|
|||
trace_t trace;
|
||||
vec3_t move;
|
||||
|
||||
lightmodel->funcs.NativeTrace (lightmodel, 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &trace);
|
||||
lightmodel->funcs.NativeTrace (lightmodel, 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &trace);
|
||||
if (trace.fraction < 1)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#define fakeop fakeop16
|
||||
#define dstatement_t dstatement16_t
|
||||
#define sofs signed short
|
||||
#define uofs unsigned short
|
||||
#elif INTSIZE == 32
|
||||
#define cont cont32
|
||||
#define reeval reeval32
|
||||
|
@ -26,7 +25,6 @@
|
|||
#define fakeop fakeop32
|
||||
#define dstatement_t dstatement32_t
|
||||
#define sofs signed int
|
||||
#define uofs unsigned int
|
||||
#elif INTSIZE == 24
|
||||
#error INTSIZE should be set to 32.
|
||||
#else
|
||||
|
@ -397,109 +395,6 @@ reeval:
|
|||
*(unsigned char *)ptr = (char)OPA->_float;
|
||||
break;
|
||||
|
||||
case OP_MULSTORE_F: // f *= f
|
||||
OPB->_float *= OPA->_float;
|
||||
break;
|
||||
case OP_MULSTORE_VF: // v *= f
|
||||
tmpf = OPA->_float;
|
||||
OPB->_vector[0] *= tmpf;
|
||||
OPB->_vector[1] *= tmpf;
|
||||
OPB->_vector[2] *= tmpf;
|
||||
break;
|
||||
case OP_MULSTOREP_F: // e.f *= f
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = (ptr->_float *= OPA->_float);
|
||||
break;
|
||||
case OP_MULSTOREP_VF: // e.v *= f
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
tmpf = OPA->_float;
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_vector[0] = (ptr->_vector[0] *= tmpf);
|
||||
OPC->_vector[1] = (ptr->_vector[1] *= tmpf);
|
||||
OPC->_vector[2] = (ptr->_vector[2] *= tmpf);
|
||||
break;
|
||||
|
||||
case OP_DIVSTORE_F: // f /= f
|
||||
OPB->_float /= OPA->_float;
|
||||
break;
|
||||
case OP_DIVSTOREP_F: // e.f /= f
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = (ptr->_float /= OPA->_float);
|
||||
break;
|
||||
|
||||
case OP_ADDSTORE_F: // f += f
|
||||
OPB->_float += OPA->_float;
|
||||
break;
|
||||
case OP_ADDSTORE_V: // v += v
|
||||
OPB->_vector[0] += OPA->_vector[0];
|
||||
OPB->_vector[1] += OPA->_vector[1];
|
||||
OPB->_vector[2] += OPA->_vector[2];
|
||||
break;
|
||||
case OP_ADDSTOREP_F: // e.f += f
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = (ptr->_float += OPA->_float);
|
||||
break;
|
||||
case OP_ADDSTOREP_V: // e.v += v
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_vector[0] = (ptr->_vector[0] += OPA->_vector[0]);
|
||||
OPC->_vector[1] = (ptr->_vector[1] += OPA->_vector[1]);
|
||||
OPC->_vector[2] = (ptr->_vector[2] += OPA->_vector[2]);
|
||||
break;
|
||||
|
||||
case OP_SUBSTORE_F: // f -= f
|
||||
OPB->_float -= OPA->_float;
|
||||
break;
|
||||
case OP_SUBSTORE_V: // v -= v
|
||||
OPB->_vector[0] -= OPA->_vector[0];
|
||||
OPB->_vector[1] -= OPA->_vector[1];
|
||||
OPB->_vector[2] -= OPA->_vector[2];
|
||||
break;
|
||||
case OP_SUBSTOREP_F: // e.f -= f
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = (ptr->_float -= OPA->_float);
|
||||
break;
|
||||
case OP_SUBSTOREP_V: // e.v -= v
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_vector[0] = (ptr->_vector[0] -= OPA->_vector[0]);
|
||||
OPC->_vector[1] = (ptr->_vector[1] -= OPA->_vector[1]);
|
||||
OPC->_vector[2] = (ptr->_vector[2] -= OPA->_vector[2]);
|
||||
break;
|
||||
|
||||
|
||||
//get a pointer to a field var
|
||||
case OP_ADDRESS:
|
||||
if ((unsigned)OPA->edict >= (unsigned)sv_num_edicts)
|
||||
|
@ -941,30 +836,31 @@ reeval:
|
|||
OPC->_int = OPA->_int << OPB->_int;
|
||||
break;
|
||||
|
||||
|
||||
//hexen2 arrays contain a prefix global set to (arraysize-1) inserted before the actual array data
|
||||
//for vectors, this prefix is the number of vectors rather than the number of globals. this can cause issues with using OP_FETCH_GBL_V within structs.
|
||||
case OP_FETCH_GBL_F:
|
||||
case OP_FETCH_GBL_S:
|
||||
case OP_FETCH_GBL_E:
|
||||
case OP_FETCH_GBL_FNC:
|
||||
i = (int)OPB->_float;
|
||||
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
|
||||
i = OPB->_float;
|
||||
if((unsigned)i > (unsigned)((eval_t *)&glob[st->a-1])->_int)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError(&progfuncs->funcs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int);
|
||||
}
|
||||
t = (eval_t *)&glob[(uofs)st->a + i];
|
||||
OPC->_int = t->_int;
|
||||
OPC->_int = ((eval_t *)&glob[st->a + i])->_int;
|
||||
break;
|
||||
case OP_FETCH_GBL_V:
|
||||
i = (int)OPB->_float;
|
||||
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
|
||||
i = OPB->_float;
|
||||
if((unsigned)i > (unsigned)((eval_t *)&glob[st->a-1])->_int)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError(&progfuncs->funcs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
|
||||
}
|
||||
t = (eval_t *)&glob[(uofs)st->a + i*3];
|
||||
OPC->_vector[0] = t->_vector[0];
|
||||
OPC->_vector[1] = t->_vector[1];
|
||||
OPC->_vector[2] = t->_vector[2];
|
||||
ptr = (eval_t *)&glob[st->a + i*3];
|
||||
OPC->_vector[0] = ptr->_vector[0];
|
||||
OPC->_vector[1] = ptr->_vector[1];
|
||||
OPC->_vector[2] = ptr->_vector[2];
|
||||
break;
|
||||
|
||||
case OP_CSTATE:
|
||||
|
@ -979,146 +875,186 @@ reeval:
|
|||
externs->thinktimeop(&progfuncs->funcs, (struct edict_s *)PROG_TO_EDICT(progfuncs, OPA->edict), OPB->_float);
|
||||
break;
|
||||
|
||||
|
||||
case OP_BITSETSTORE_F: // b (+) a
|
||||
OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
|
||||
case OP_MULSTORE_F:
|
||||
/*OPC->_float = */OPB->_float *= OPA->_float;
|
||||
break;
|
||||
case OP_BITSETSTOREP_F: // .b (+) a
|
||||
case OP_MULSTORE_VF:
|
||||
tmpf = OPA->_float; //don't break on vec*=vec_x;
|
||||
/*OPC->_vector[0] = */OPB->_vector[0] *= tmpf;
|
||||
/*OPC->_vector[1] = */OPB->_vector[1] *= tmpf;
|
||||
/*OPC->_vector[2] = */OPB->_vector[2] *= tmpf;
|
||||
break;
|
||||
case OP_MULSTOREP_F:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
ptr->_float = (float)((int)ptr->_float | (int)OPA->_float);
|
||||
OPC->_float = ptr->_float *= OPA->_float;
|
||||
break;
|
||||
case OP_BITCLRSTORE_F: // b (-) a
|
||||
OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
|
||||
break;
|
||||
case OP_BITCLRSTOREP_F: // .b (-) a
|
||||
case OP_MULSTOREP_VF:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float));
|
||||
tmpf = OPA->_float; //don't break on vec*=vec_x;
|
||||
OPC->_vector[0] = ptr->_vector[0] *= tmpf;
|
||||
OPC->_vector[1] = ptr->_vector[1] *= tmpf;
|
||||
OPC->_vector[2] = ptr->_vector[2] *= tmpf;
|
||||
break;
|
||||
case OP_DIVSTORE_F:
|
||||
/*OPC->_float = */OPB->_float /= OPA->_float;
|
||||
break;
|
||||
case OP_DIVSTOREP_F:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = ptr->_float /= OPA->_float;
|
||||
break;
|
||||
case OP_ADDSTORE_F:
|
||||
/*OPC->_float = */OPB->_float += OPA->_float;
|
||||
break;
|
||||
case OP_ADDSTORE_V:
|
||||
/*OPC->_vector[0] =*/ OPB->_vector[0] += OPA->_vector[0];
|
||||
/*OPC->_vector[1] =*/ OPB->_vector[1] += OPA->_vector[1];
|
||||
/*OPC->_vector[2] =*/ OPB->_vector[2] += OPA->_vector[2];
|
||||
break;
|
||||
case OP_ADDSTOREP_F:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = ptr->_float += OPA->_float;
|
||||
break;
|
||||
case OP_ADDSTOREP_V:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_vector[0] = ptr->_vector[0] += OPA->_vector[0];
|
||||
OPC->_vector[1] = ptr->_vector[1] += OPA->_vector[1];
|
||||
OPC->_vector[2] = ptr->_vector[2] += OPA->_vector[2];
|
||||
break;
|
||||
case OP_SUBSTORE_F:
|
||||
/*OPC->_float = */OPB->_float -= OPA->_float;
|
||||
break;
|
||||
case OP_SUBSTORE_V:
|
||||
/*OPC->_vector[0] = */OPB->_vector[0] -= OPA->_vector[0];
|
||||
/*OPC->_vector[1] = */OPB->_vector[1] -= OPA->_vector[1];
|
||||
/*OPC->_vector[2] = */OPB->_vector[2] -= OPA->_vector[2];
|
||||
break;
|
||||
case OP_SUBSTOREP_F:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_float = ptr->_float -= OPA->_float;
|
||||
break;
|
||||
case OP_SUBSTOREP_V:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
OPC->_vector[0] = ptr->_vector[0] -= OPA->_vector[0];
|
||||
OPC->_vector[1] = ptr->_vector[1] -= OPA->_vector[1];
|
||||
OPC->_vector[2] = ptr->_vector[2] -= OPA->_vector[2];
|
||||
break;
|
||||
case OP_BITSETSTORE_F:
|
||||
OPB->_float = (int)OPB->_float | (int)OPA->_float;
|
||||
break;
|
||||
case OP_BITSETSTOREP_F:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
ptr->_float = (int)ptr->_float | (int)OPA->_float;
|
||||
break;
|
||||
case OP_BITCLRSTORE_F:
|
||||
OPB->_float = (int)OPB->_float & ~(int)OPA->_float;
|
||||
break;
|
||||
case OP_BITCLRSTOREP_F:
|
||||
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
ptr->_float = (int)ptr->_float & ~(int)OPA->_float;
|
||||
break;
|
||||
|
||||
//for scaler randoms, prevent the random value from ever reaching 1
|
||||
//this avoids issues when array[random()*array.length]
|
||||
case OP_RAND0:
|
||||
OPC->_float = (rand()&0x7fff)/((float)0x7fff);
|
||||
OPC->_float = (rand ()&0x7fff) / ((float)0x8000);
|
||||
break;
|
||||
case OP_RAND1:
|
||||
OPC->_float = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
|
||||
OPC->_float = (rand ()&0x7fff) / ((float)0x8000)*OPA->_float;
|
||||
break;
|
||||
case OP_RAND2:
|
||||
if(OPA->_float < OPB->_float)
|
||||
{
|
||||
OPC->_float = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
|
||||
*(OPB->_float-OPA->_float));
|
||||
}
|
||||
else
|
||||
{
|
||||
OPC->_float = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
|
||||
*(OPA->_float-OPB->_float));
|
||||
}
|
||||
case OP_RAND2: //backwards range shouldn't matter (except that it is b that is never reached, rather than the higher of the two)
|
||||
OPC->_float = OPA->_float + (rand ()&0x7fff) / ((float)0x8000)*(OPB->_float-OPA->_float);
|
||||
break;
|
||||
//random vectors DO result in 0 to 1 inclusive, to try to ensure a more balanced range
|
||||
case OP_RANDV0:
|
||||
OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff);
|
||||
OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff);
|
||||
OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff);
|
||||
OPC->_vector[0] = (rand ()&0x7fff) / ((float)0x7fff);
|
||||
OPC->_vector[1] = (rand ()&0x7fff) / ((float)0x7fff);
|
||||
OPC->_vector[2] = (rand ()&0x7fff) / ((float)0x7fff);
|
||||
break;
|
||||
case OP_RANDV1:
|
||||
OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
|
||||
OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
|
||||
OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
|
||||
OPC->_vector[0] = (rand ()&0x7fff) / ((float)0x7fff)*OPA->_vector[0];
|
||||
OPC->_vector[1] = (rand ()&0x7fff) / ((float)0x7fff)*OPA->_vector[1];
|
||||
OPC->_vector[2] = (rand ()&0x7fff) / ((float)0x7fff)*OPA->_vector[2];
|
||||
break;
|
||||
case OP_RANDV2:
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
if(OPA->_vector[i] < OPB->_vector[i])
|
||||
{
|
||||
OPC->_vector[i] = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
|
||||
*(OPB->_vector[i]-OPA->_vector[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
OPC->_vector[i] = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
|
||||
*(OPA->_vector[i]-OPB->_vector[i]));
|
||||
}
|
||||
}
|
||||
case OP_RANDV2: //backwards range shouldn't matter
|
||||
OPC->_vector[0] = OPA->_vector[0] + (rand ()&0x7fff) / ((float)0x7fff)*(OPB->_vector[0]-OPA->_vector[0]);
|
||||
OPC->_vector[1] = OPA->_vector[1] + (rand ()&0x7fff) / ((float)0x7fff)*(OPB->_vector[1]-OPA->_vector[1]);
|
||||
OPC->_vector[2] = OPA->_vector[2] + (rand ()&0x7fff) / ((float)0x7fff)*(OPB->_vector[2]-OPA->_vector[2]);
|
||||
break;
|
||||
|
||||
|
||||
case OP_SWITCH_F:
|
||||
case OP_SWITCH_V:
|
||||
case OP_SWITCH_S:
|
||||
case OP_SWITCH_E:
|
||||
case OP_SWITCH_FNC:
|
||||
swtch = OPA;
|
||||
swtchtype = OPCODE;
|
||||
//the case opcodes depend upon the preceding switch.
|
||||
//otherwise the switch itself is much like a goto
|
||||
//don't embed the case/caserange checks directly into the switch so that custom caseranges can be potentially be implemented with hybrid emulation.
|
||||
switchcomparison = OPCODE - OP_SWITCH_F;
|
||||
switchref = OPA;
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->b - 1; // offset the st++
|
||||
st += (sofs)st->b - 1; // offset the s++
|
||||
break;
|
||||
case OP_CASE:
|
||||
switch(swtchtype)
|
||||
{
|
||||
case OP_SWITCH_F:
|
||||
if (swtch->_float == OPA->_float)
|
||||
//if the comparison is true, jump (back up) to the relevent code block
|
||||
if (casecmp[switchcomparison](progfuncs, switchref, OPA))
|
||||
{
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->b-1; // -1 to offset the s++
|
||||
}
|
||||
break;
|
||||
case OP_SWITCH_E:
|
||||
case OP_SWITCH_FNC:
|
||||
if (swtch->_int == OPA->_int)
|
||||
{
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->b-1; // -1 to offset the s++
|
||||
}
|
||||
break;
|
||||
case OP_SWITCH_S:
|
||||
if (swtch->_int == OPA->_int)
|
||||
{
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->b-1; // -1 to offset the s++
|
||||
}
|
||||
if ((!swtch->_int && PR_StringToNative(&progfuncs->funcs, OPA->string)) || (!OPA->_int && PR_StringToNative(&progfuncs->funcs, swtch->string))) //one is null (cannot be not both).
|
||||
break;
|
||||
if (!strcmp(PR_StringToNative(&progfuncs->funcs, swtch->string), PR_StringToNative(&progfuncs->funcs, OPA->string)))
|
||||
{
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->b-1; // -1 to offset the s++
|
||||
}
|
||||
break;
|
||||
case OP_SWITCH_V:
|
||||
if (swtch->_vector[0] == OPA->_vector[0] && swtch->_vector[1] == OPA->_vector[1] && swtch->_vector[2] == OPA->_vector[2])
|
||||
{
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->b-1; // -1 to offset the s++
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PR_RunError (&progfuncs->funcs, "OP_CASE with bad/missing OP_SWITCH %i", swtchtype);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OP_CASERANGE:
|
||||
switch(swtchtype)
|
||||
{
|
||||
case OP_SWITCH_F:
|
||||
if (swtch->_float >= OPA->_float && swtch->_float <= OPB->_float)
|
||||
//if the comparison is true, jump (back up) to the relevent code block
|
||||
if (casecmprange[switchcomparison](progfuncs, switchref, OPA, OPC))
|
||||
{
|
||||
RUNAWAYCHECK();
|
||||
st += (sofs)st->c-1; // -1 to offset the s++
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PR_RunError (&progfuncs->funcs, "OP_CASERANGE with bad/missing OP_SWITCH %i", swtchtype);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1316,7 +1252,6 @@ reeval:
|
|||
#undef fakeop
|
||||
#undef dstatement_t
|
||||
#undef sofs
|
||||
#undef uofs
|
||||
#undef OPCODE
|
||||
|
||||
#undef ENGINEPOINTER
|
||||
|
|
|
@ -755,7 +755,7 @@ pbool LocateDebugTerm(progfuncs_t *progfuncs, char *key, eval_t **result, etype_
|
|||
ed = PROG_TO_EDICT(progfuncs, val->_int);
|
||||
if (!ed)
|
||||
return false;
|
||||
if (fofs < 0 || fofs >= max_fields_size)
|
||||
if (fofs < 0 || fofs >= (int)max_fields_size)
|
||||
return false;
|
||||
val = (eval_t *) (((char *)ed->fields) + fofs*4);
|
||||
}
|
||||
|
@ -1240,6 +1240,41 @@ static char *lastfile = 0;
|
|||
return statement;
|
||||
}
|
||||
|
||||
static pbool casecmp_f(progfuncs_t *progfuncs, eval_t *ref, eval_t *val) {return ref->_float == val->_float;}
|
||||
static pbool casecmp_i(progfuncs_t *progfuncs, eval_t *ref, eval_t *val) {return ref->_int == val->_int;}
|
||||
static pbool casecmp_v(progfuncs_t *progfuncs, eval_t *ref, eval_t *val) {return ref->_vector[0] == val->_vector[0] &&
|
||||
ref->_vector[1] == val->_vector[1] &&
|
||||
ref->_vector[2] == val->_vector[2];}
|
||||
static pbool casecmp_s(progfuncs_t *progfuncs, eval_t *ref, eval_t *val) { const char *refs = PR_StringToNative(&progfuncs->funcs, ref->string);
|
||||
const char *vals = PR_StringToNative(&progfuncs->funcs, val->string);
|
||||
return !strcmp(refs, vals);}
|
||||
static pbool casecmprange_f(progfuncs_t *progfuncs, eval_t *ref, eval_t *min, eval_t *max) {return ref->_float >= min->_float && ref->_float <= max->_float;}
|
||||
static pbool casecmprange_i(progfuncs_t *progfuncs, eval_t *ref, eval_t *min, eval_t *max) {return ref->_int >= min->_int && ref->_int <= max->_int;}
|
||||
static pbool casecmprange_v(progfuncs_t *progfuncs, eval_t *ref, eval_t *min, eval_t *max) {return ref->_vector[0] >= min->_vector[0] && ref->_vector[0] <= max->_vector[0] &&
|
||||
ref->_vector[1] >= min->_vector[1] && ref->_vector[1] <= max->_vector[1] &&
|
||||
ref->_vector[2] >= min->_vector[2] && ref->_vector[2] <= max->_vector[2];}
|
||||
static pbool casecmprange_bad(progfuncs_t *progfuncs, eval_t *ref, eval_t *min, eval_t *max){ PR_RunError (&progfuncs->funcs, "OP_CASERANGE type not supported");//BUG: pr_xstatement will not be correct.
|
||||
return false;}
|
||||
typedef pbool (*casecmp_t)(progfuncs_t *progfuncs, eval_t *ref, eval_t *val);
|
||||
typedef pbool (*casecmprange_t)(progfuncs_t *progfuncs, eval_t *ref, eval_t *min, eval_t *max);
|
||||
static casecmp_t casecmp[] =
|
||||
{
|
||||
casecmp_f, //float
|
||||
casecmp_v, //vector
|
||||
casecmp_s, //string
|
||||
casecmp_i, //ent
|
||||
casecmp_i //func
|
||||
//pointer, field, int, etc are emulated with func or something. I dunno
|
||||
};
|
||||
static casecmprange_t casecmprange[] =
|
||||
{
|
||||
casecmprange_f, //float
|
||||
casecmprange_v, //vector - I'm using a bbox, not really sure what it should be
|
||||
casecmprange_bad, //string - should it use stof? string ranges don't relly make sense, at all.
|
||||
casecmprange_i, //ent - doesn't really make sense, but as ints/pointers/fields/etc might be emulated with this, allow it anyway, as an int type.
|
||||
casecmprange_i //func
|
||||
};
|
||||
|
||||
#define RUNAWAYCHECK() \
|
||||
if (!--*runaway) \
|
||||
{ \
|
||||
|
@ -1255,9 +1290,7 @@ static char *lastfile = 0;
|
|||
|
||||
static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *fte_restrict runaway)
|
||||
{
|
||||
eval_t *t, *swtch=NULL;
|
||||
|
||||
int swtchtype = 0; //warning about not being initialized before use
|
||||
unsigned int switchcomparison = 0;
|
||||
const dstatement16_t *fte_restrict st;
|
||||
mfunction_t *fte_restrict newf;
|
||||
int i;
|
||||
|
@ -1268,6 +1301,8 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
|
|||
float tmpf;
|
||||
int tmpi;
|
||||
|
||||
eval_t *switchref = (eval_t*)glob;
|
||||
|
||||
#define OPA ((eval_t *)&glob[st->a])
|
||||
#define OPB ((eval_t *)&glob[st->b])
|
||||
#define OPC ((eval_t *)&glob[st->c])
|
||||
|
@ -1312,9 +1347,7 @@ static int PR_ExecuteCode32 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
|
|||
return -1;
|
||||
#else
|
||||
|
||||
eval_t *t, *swtch=NULL;
|
||||
|
||||
int swtchtype = 0; //warning about not being initialized before use
|
||||
unsigned int switchcomparison = 0;
|
||||
const dstatement32_t *fte_restrict st;
|
||||
mfunction_t *fte_restrict newf;
|
||||
int i;
|
||||
|
@ -1324,6 +1357,7 @@ static int PR_ExecuteCode32 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
|
|||
float *fte_restrict glob = pr_globals;
|
||||
float tmpf;
|
||||
int tmpi;
|
||||
eval_t *switchref = (eval_t*)glob;
|
||||
|
||||
#define OPA ((eval_t *)&glob[st->a])
|
||||
#define OPB ((eval_t *)&glob[st->b])
|
||||
|
|
|
@ -662,17 +662,19 @@ void NPP_NQFlush(void)
|
|||
{
|
||||
if (cl->state == cs_spawned && ISQWCLIENT(cl))
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
char *h2finale = NULL;
|
||||
char *h2title = NULL;
|
||||
/*
|
||||
if (cl->zquake_extensions & Z_EXT_SERVERTIME)
|
||||
{
|
||||
/* ClientReliableCheckBlock(cl, 6);
|
||||
ClientReliableCheckBlock(cl, 6);
|
||||
ClientReliableWrite_Byte(cl, svc_updatestatlong);
|
||||
ClientReliableWrite_Byte(cl, STAT_TIME);
|
||||
ClientReliableWrite_Long(cl, (int)(sv.world.physicstime * 1000));
|
||||
cl->nextservertimeupdate = sv.world.physicstime+10;
|
||||
*/ }
|
||||
|
||||
}
|
||||
*/
|
||||
if (progstype == PROG_H2)
|
||||
{
|
||||
/*hexen2 does something like this in the client, but we don't support those protocols, so translate to something usable*/
|
||||
|
@ -699,6 +701,7 @@ void NPP_NQFlush(void)
|
|||
ClientReliableWrite_String(cl, h2finale);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ClientReliableCheckBlock(cl, 16);
|
||||
ClientReliableWrite_Byte(cl, svc_intermission);
|
||||
|
|
|
@ -274,7 +274,7 @@ pbool PDECL ED_CanFree (edict_t *ed)
|
|||
return true;
|
||||
}
|
||||
|
||||
void ASMCALL StateOp (pubprogfuncs_t *prinst, float var, func_t func)
|
||||
static void ASMCALL StateOp (pubprogfuncs_t *prinst, float var, func_t func)
|
||||
{
|
||||
stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
|
||||
if (progstype == PROG_H2)
|
||||
|
@ -284,87 +284,98 @@ void ASMCALL StateOp (pubprogfuncs_t *prinst, float var, func_t func)
|
|||
vars->think = func;
|
||||
vars->frame = var;
|
||||
}
|
||||
void ASMCALL CStateOp (pubprogfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc)
|
||||
#ifdef HEXEN2
|
||||
static void ASMCALL CStateOp (pubprogfuncs_t *prinst, float first, float last, func_t currentfunc)
|
||||
{
|
||||
stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
|
||||
float min, max;
|
||||
float step;
|
||||
wedict_t *e = PROG_TO_WEDICT(prinst, pr_global_struct->self);
|
||||
float frame = e->v->frame;
|
||||
|
||||
if (progstype == PROG_H2)
|
||||
e->v->nextthink = pr_global_struct->time+0.05;
|
||||
else
|
||||
e->v->nextthink = pr_global_struct->time+0.1;
|
||||
e->v->think = currentfunc;
|
||||
|
||||
vars->nextthink = pr_global_struct->time+0.05;
|
||||
vars->think = currentfunc;
|
||||
pr_global_struct->cycle_wrapped = false;
|
||||
|
||||
if(startFrame <= endFrame)
|
||||
{ // Increment
|
||||
if(vars->frame < startFrame || vars->frame > endFrame)
|
||||
{
|
||||
vars->frame = startFrame;
|
||||
return;
|
||||
if (first > last)
|
||||
{ //going backwards
|
||||
min = last;
|
||||
max = first;
|
||||
step = -1.0;
|
||||
}
|
||||
vars->frame++;
|
||||
if(vars->frame > endFrame)
|
||||
else
|
||||
{ //forwards
|
||||
min = first;
|
||||
max = last;
|
||||
step = 1.0;
|
||||
}
|
||||
if (frame < min || frame > max)
|
||||
frame = first; //started out of range, must have been a different animation
|
||||
else
|
||||
{
|
||||
frame += step;
|
||||
if (frame < min || frame > max)
|
||||
{ //became out of range, must have wrapped
|
||||
pr_global_struct->cycle_wrapped = true;
|
||||
vars->frame = startFrame;
|
||||
frame = first;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Decrement
|
||||
if(vars->frame > startFrame || vars->frame < endFrame)
|
||||
{
|
||||
vars->frame = startFrame;
|
||||
return;
|
||||
}
|
||||
vars->frame--;
|
||||
if(vars->frame < endFrame)
|
||||
{
|
||||
pr_global_struct->cycle_wrapped = true;
|
||||
vars->frame = startFrame;
|
||||
}
|
||||
e->v->frame = frame;
|
||||
}
|
||||
void ASMCALL CWStateOp (pubprogfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc)
|
||||
static void ASMCALL CWStateOp (pubprogfuncs_t *prinst, float first, float last, func_t currentfunc)
|
||||
{
|
||||
stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v;
|
||||
float min, max;
|
||||
float step;
|
||||
wedict_t *e = PROG_TO_WEDICT(prinst, pr_global_struct->self);
|
||||
float frame = e->v->weaponframe;
|
||||
|
||||
if (progstype == PROG_H2)
|
||||
e->v->nextthink = pr_global_struct->time+0.05;
|
||||
else
|
||||
e->v->nextthink = pr_global_struct->time+0.1;
|
||||
e->v->think = currentfunc;
|
||||
|
||||
vars->nextthink = pr_global_struct->time+0.05;
|
||||
vars->think = currentfunc;
|
||||
pr_global_struct->cycle_wrapped = false;
|
||||
|
||||
if(startFrame <= endFrame)
|
||||
{ // Increment
|
||||
if(vars->weaponframe < startFrame || vars->weaponframe > endFrame)
|
||||
{
|
||||
vars->weaponframe = startFrame;
|
||||
return;
|
||||
if (first > last)
|
||||
{ //going backwards
|
||||
min = last;
|
||||
max = first;
|
||||
step = -1.0;
|
||||
}
|
||||
vars->weaponframe++;
|
||||
if(vars->weaponframe > endFrame)
|
||||
else
|
||||
{ //forwards
|
||||
min = first;
|
||||
max = last;
|
||||
step = 1.0;
|
||||
}
|
||||
if (frame < min || frame > max)
|
||||
frame = first; //started out of range, must have been a different animation
|
||||
else
|
||||
{
|
||||
frame += step;
|
||||
if (frame < min || frame > max)
|
||||
{ //became out of range, must have wrapped
|
||||
pr_global_struct->cycle_wrapped = true;
|
||||
vars->weaponframe = startFrame;
|
||||
frame = first;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Decrement
|
||||
if(vars->weaponframe > startFrame || vars->weaponframe < endFrame)
|
||||
{
|
||||
vars->weaponframe = startFrame;
|
||||
return;
|
||||
}
|
||||
vars->weaponframe--;
|
||||
if(vars->weaponframe < endFrame)
|
||||
{
|
||||
pr_global_struct->cycle_wrapped = true;
|
||||
vars->weaponframe = startFrame;
|
||||
}
|
||||
e->v->weaponframe = frame;
|
||||
}
|
||||
|
||||
void ASMCALL ThinkTimeOp (pubprogfuncs_t *prinst, edict_t *ed, float var)
|
||||
static void ASMCALL ThinkTimeOp (pubprogfuncs_t *prinst, edict_t *ed, float var)
|
||||
{
|
||||
stdentvars_t *vars = ed->v;
|
||||
vars->nextthink = pr_global_struct->time+var;
|
||||
}
|
||||
#endif
|
||||
|
||||
pbool PDECL SV_BadField(pubprogfuncs_t *inst, edict_t *foo, const char *keyname, const char *value)
|
||||
static pbool PDECL SV_BadField(pubprogfuncs_t *inst, edict_t *foo, const char *keyname, const char *value)
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
/*Worldspawn only fields...*/
|
||||
if (NUM_FOR_EDICT(inst, foo) == 0)
|
||||
{
|
||||
|
@ -381,6 +392,7 @@ pbool PDECL SV_BadField(pubprogfuncs_t *inst, edict_t *foo, const char *keyname,
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//don't spam warnings about missing fields if we failed to load the progs.
|
||||
if (!svs.numprogs)
|
||||
|
@ -403,9 +415,11 @@ void PR_SV_FillWorldGlobals(world_t *w)
|
|||
w->g.v_up = *pr_global_ptrs->v_up;
|
||||
}
|
||||
|
||||
void PDECL PR_SSQC_Relocated(pubprogfuncs_t *pr, char *oldb, char *newb, int oldlen)
|
||||
static void PDECL PR_SSQC_Relocated(pubprogfuncs_t *pr, char *oldb, char *newb, int oldlen)
|
||||
{
|
||||
#ifdef VM_Q1
|
||||
edict_t *ent;
|
||||
#endif
|
||||
int i;
|
||||
union {
|
||||
globalptrs_t *g;
|
||||
|
@ -449,7 +463,7 @@ extern int pr_numbuiltins;
|
|||
|
||||
model_t *SVPR_GetCModel(world_t *w, int modelindex)
|
||||
{
|
||||
if ((unsigned int)modelindex < MAX_MODELS)
|
||||
if ((unsigned int)modelindex < MAX_PRECACHE_MODELS)
|
||||
{
|
||||
if (!sv.models[modelindex] && sv.strings.model_precache[modelindex])
|
||||
sv.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], MLV_WARN);
|
||||
|
@ -458,13 +472,13 @@ model_t *SVPR_GetCModel(world_t *w, int modelindex)
|
|||
else
|
||||
return NULL;
|
||||
}
|
||||
void SVPR_Get_FrameState(world_t *w, wedict_t *ent, framestate_t *fstate)
|
||||
static void SVPR_Get_FrameState(world_t *w, wedict_t *ent, framestate_t *fstate)
|
||||
{
|
||||
memset(fstate, 0, sizeof(*fstate));
|
||||
fstate->g[FS_REG].frame[0] = ent->v->frame;
|
||||
}
|
||||
|
||||
void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
|
||||
static void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
|
||||
{
|
||||
int oself = pr_global_struct->self;
|
||||
int oother = pr_global_struct->other;
|
||||
|
@ -478,7 +492,7 @@ void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
|
|||
pr_global_struct->other = oother;
|
||||
}
|
||||
|
||||
void SVPR_Event_Think(world_t *w, wedict_t *s)
|
||||
static void SVPR_Event_Think(world_t *w, wedict_t *s)
|
||||
{
|
||||
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
|
||||
pr_global_struct->other = EDICT_TO_PROG(w->progs, w->edicts);
|
||||
|
@ -488,7 +502,7 @@ void SVPR_Event_Think(world_t *w, wedict_t *s)
|
|||
PR_ExecuteProgram (w->progs, s->v->think);
|
||||
}
|
||||
|
||||
qboolean SVPR_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype)
|
||||
static qboolean SVPR_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype)
|
||||
{
|
||||
if (ent->xv->contentstransition)
|
||||
{
|
||||
|
@ -518,9 +532,11 @@ void Q_SetProgsParms(qboolean forcompiler)
|
|||
svprogparms.entspawn = ED_Spawned;//void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set
|
||||
svprogparms.entcanfree = ED_CanFree;//bool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed
|
||||
svprogparms.stateop = StateOp;//void (*stateop) (float var, func_t func);
|
||||
#ifdef HEXEN2
|
||||
svprogparms.cstateop = CStateOp;
|
||||
svprogparms.cwstateop = CWStateOp;
|
||||
svprogparms.thinktimeop = ThinkTimeOp;
|
||||
#endif
|
||||
|
||||
//used when loading a game
|
||||
svprogparms.builtinsfor = NULL;//builtin_t *(*builtinsfor) (int num); //must return a pointer to the builtins that were used before the state was saved.
|
||||
|
@ -810,6 +826,7 @@ void PR_LoadGlabalStruct(void)
|
|||
|
||||
PR_SV_FillWorldGlobals(&sv.world);
|
||||
|
||||
#ifdef HEXEN2
|
||||
/*Hexen2 has lots of extra stats, which I don't want special support for, so list them here and send them as for csqc*/
|
||||
if (progstype == PROG_H2)
|
||||
{
|
||||
|
@ -868,6 +885,7 @@ void PR_LoadGlabalStruct(void)
|
|||
SV_QCStatPtr(ev_integer, &h2infoplaque[0], STAT_H2_OBJECTIVE1);
|
||||
SV_QCStatPtr(ev_integer, &h2infoplaque[1], STAT_H2_OBJECTIVE2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
progsnum_t AddProgs(const char *name)
|
||||
|
@ -1679,8 +1697,9 @@ void Q_InitProgs(void)
|
|||
sv.world.defaultgravityscale = 0;
|
||||
else
|
||||
sv.world.defaultgravityscale = 1;
|
||||
|
||||
#ifdef HEXEN2
|
||||
SV_RegisterH2CustomTents();
|
||||
#endif
|
||||
|
||||
#ifdef USEODE
|
||||
World_ODE_Start(&sv.world);
|
||||
|
@ -2050,7 +2069,7 @@ static void SV_Effect(vec3_t org, int mdlidx, int startframe, int endframe, int
|
|||
SV_Multicast(org, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HEXEN2
|
||||
static int SV_CustomTEnt_Register(char *effectname, int nettype, float *stain_rgb, float stain_radius, float *dl_rgb, float dl_radius, float dl_time, float *dl_fade)
|
||||
{
|
||||
int i;
|
||||
|
@ -2147,7 +2166,7 @@ static int SV_CustomTEnt_Spawn(int index, float *org, float *org2, int count, fl
|
|||
|
||||
return persist_id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -2350,9 +2369,9 @@ void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, const char *m)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i==MAX_MODELS || !sv.strings.model_precache[i])
|
||||
if (i==MAX_PRECACHE_MODELS || !sv.strings.model_precache[i])
|
||||
{
|
||||
if (i!=MAX_MODELS)
|
||||
if (i!=MAX_PRECACHE_MODELS)
|
||||
{
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
|
@ -2479,6 +2498,7 @@ static void QCBUILTIN PF_setmodel (pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
PF_setmodel_Internal(prinst, e, m);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
static void QCBUILTIN PF_h2set_puzzle_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //qc/hc lacks string manipulation.
|
||||
edict_t *e;
|
||||
|
@ -2490,6 +2510,7 @@ static void QCBUILTIN PF_h2set_puzzle_model (pubprogfuncs_t *prinst, struct glob
|
|||
snprintf(fullname, sizeof(fullname)-1, "models/puzzle/%s.mdl", shortname);
|
||||
PF_setmodel_Internal(prinst, e, fullname);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -2646,26 +2667,6 @@ static void QCBUILTIN PF_centerprint (pubprogfuncs_t *prinst, struct globalvars_
|
|||
PF_centerprint_Internal(entnum, false, s);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_vhlen
|
||||
|
||||
scalar vhlen(vector)
|
||||
=================
|
||||
*/
|
||||
static void QCBUILTIN PF_vhlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float *value1;
|
||||
float newv;
|
||||
|
||||
value1 = G_VECTOR(OFS_PARM0);
|
||||
|
||||
newv = value1[0] * value1[0] + value1[1] * value1[1];
|
||||
newv = sqrt(newv);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = newv;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_particle
|
||||
|
@ -2797,6 +2798,7 @@ static void QCBUILTIN PF_te_blooddp (pubprogfuncs_t *prinst, globalvars_t *pr_gl
|
|||
SV_Multicast(org, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
/*
|
||||
=================
|
||||
PF_particle2 - hexen2
|
||||
|
@ -2929,6 +2931,7 @@ static void QCBUILTIN PF_h2particleexplosion(pubprogfuncs_t *prinst, struct glob
|
|||
|
||||
SV_MulticastProtExt (org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_HEXEN2, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -2968,7 +2971,7 @@ void PF_ambientsound_Internal (float *pos, const char *samp, float vol, float at
|
|||
for (i=0 ; i<3 ; i++)
|
||||
MSG_WriteCoord(msg, pos[i]);
|
||||
MSG_WriteByte (msg, soundnum);
|
||||
MSG_WriteByte (msg, vol*255);
|
||||
MSG_WriteByte (msg, bound(0, (int)(vol*255), 255));
|
||||
MSG_WriteByte (msg, attenuation*64);
|
||||
}
|
||||
SV_Multicast(pos, MULTICAST_ALL_R);
|
||||
|
@ -3162,6 +3165,7 @@ void QCBUILTIN PF_svtraceline (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
set_trace_globals(&trace, pr_globals);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
static void QCBUILTIN PF_traceboxh2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float *v1, *v2, *mins, *maxs;
|
||||
|
@ -3184,6 +3188,7 @@ static void QCBUILTIN PF_traceboxh2 (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
|
||||
set_trace_globals(&trace, pr_globals);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void QCBUILTIN PF_traceboxdp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -3587,6 +3592,7 @@ static void QCBUILTIN PF_sv_getlight (pubprogfuncs_t *prinst, struct globalvars_
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef QUAKETC
|
||||
/*
|
||||
=========
|
||||
PF_conprint
|
||||
|
@ -3596,20 +3602,17 @@ static void QCBUILTIN PF_conprint (pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
{
|
||||
Sys_Printf ("%s",PF_VarString(prinst, 0, pr_globals));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HEXEN2
|
||||
//dprintf("foo %s\n", 5.0) - its stupid and potentially unsafe
|
||||
static void QCBUILTIN PF_h2dprintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
char temp[256];
|
||||
char printable[2048];
|
||||
float v;
|
||||
char *pct;
|
||||
|
||||
v = G_FLOAT(OFS_PARM1);
|
||||
|
||||
if (v == (int)v)
|
||||
sprintf (temp, "%d",(int)v);
|
||||
else
|
||||
sprintf (temp, "%5.1f",v);
|
||||
sprintf (temp, "%g", G_FLOAT(OFS_PARM1));
|
||||
|
||||
Q_strncpyz(printable, PR_GetStringOfs(prinst, OFS_PARM0), sizeof(printable));
|
||||
while((pct = strstr(printable, "%s")))
|
||||
|
@ -3628,7 +3631,7 @@ static void QCBUILTIN PF_h2dprintv (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
char printable[2048];
|
||||
char *pct;
|
||||
|
||||
sprintf (temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM1)[0], G_VECTOR(OFS_PARM1)[1], G_VECTOR(OFS_PARM1)[2]);
|
||||
sprintf (temp, "'%g %g %g'", G_VECTOR(OFS_PARM1)[0], G_VECTOR(OFS_PARM1)[1], G_VECTOR(OFS_PARM1)[2]);
|
||||
|
||||
Q_strncpyz(printable, PR_GetStringOfs(prinst, OFS_PARM0), sizeof(printable));
|
||||
while((pct = strstr(printable, "%s")))
|
||||
|
@ -3647,6 +3650,7 @@ static void QCBUILTIN PF_h2spawn_temp (pubprogfuncs_t *prinst, struct globalvars
|
|||
ed = ED_Alloc(prinst);
|
||||
RETURN_EDICT(prinst, ed);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void QCBUILTIN PF_Remove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -3751,7 +3755,7 @@ void PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i=1 ; i<MAX_SOUNDS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_SOUNDS ; i++)
|
||||
{
|
||||
if (!*sv.strings.sound_precache[i])
|
||||
{
|
||||
|
@ -3800,7 +3804,7 @@ int PF_precache_model_Internal (pubprogfuncs_t *prinst, const char *s, qboolean
|
|||
return 0;
|
||||
}
|
||||
|
||||
for (i=1 ; i<MAX_MODELS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_MODELS ; i++)
|
||||
{
|
||||
if (!sv.strings.model_precache[i])
|
||||
{
|
||||
|
@ -3860,6 +3864,7 @@ static void QCBUILTIN PF_precache_model (pubprogfuncs_t *prinst, struct globalva
|
|||
PF_precache_model_Internal(prinst, s, false);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
static void QCBUILTIN PF_h2precache_puzzle_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //qc/hc lacks string manipulation.
|
||||
const char *shortname;
|
||||
|
@ -3869,6 +3874,7 @@ static void QCBUILTIN PF_h2precache_puzzle_model (pubprogfuncs_t *prinst, struct
|
|||
|
||||
PF_precache_model_Internal(prinst, fullname, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void QCBUILTIN PF_getmodelindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -4085,6 +4091,7 @@ static void QCBUILTIN PF_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
PF_applylightstyle(style, val, rgb);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
static void QCBUILTIN PF_lightstylevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int style;
|
||||
|
@ -4101,32 +4108,21 @@ static void QCBUILTIN PF_lightstylestatic (pubprogfuncs_t *prinst, struct global
|
|||
{
|
||||
int style;
|
||||
int num;
|
||||
char *val;
|
||||
|
||||
static char *styleDefs[] =
|
||||
{
|
||||
"a", "b", "c", "d", "e", "f", "g",
|
||||
"h", "i", "j", "k", "l", "m", "n",
|
||||
"o", "p", "q", "r", "s", "t", "u",
|
||||
"v", "w", "x", "y", "z"
|
||||
};
|
||||
char val[2];
|
||||
vec3_t rgb = {1,1,1};
|
||||
|
||||
style = G_FLOAT(OFS_PARM0);
|
||||
num = G_FLOAT(OFS_PARM1);
|
||||
#ifdef PEXT_LIGHTSTYLECOL
|
||||
if (svprogfuncs->callargc >= 3)
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), rgb);
|
||||
#endif
|
||||
|
||||
style = G_FLOAT(OFS_PARM0);
|
||||
num = G_FLOAT(OFS_PARM1);
|
||||
if (num < 0)
|
||||
num = 0;
|
||||
else if (num >= 'z'-'a')
|
||||
num = 'z'-'a'-1;
|
||||
val = styleDefs[num];
|
||||
|
||||
val[0] = 'a' + bound(0, num, ('z'-'a')-1);
|
||||
val[1] = 0;
|
||||
PF_applylightstyle(style, val, rgb);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=============
|
||||
|
@ -4782,6 +4778,8 @@ static void QCBUILTIN PF_WriteString2 (pubprogfuncs_t *prinst, struct globalvars
|
|||
G_FLOAT(OFS_PARM1) = old;
|
||||
}
|
||||
|
||||
#ifndef QUAKETC
|
||||
//qtest-only builtins.
|
||||
static void QCBUILTIN PF_qtSingle_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
NPP_NQWriteByte(MSG_PRERELONE, (qbyte)G_FLOAT(OFS_PARM1));
|
||||
|
@ -4847,6 +4845,7 @@ static void QCBUILTIN PF_qtBroadcast_WriteEntity (pubprogfuncs_t *prinst, struct
|
|||
{
|
||||
NPP_NQWriteEntity(MSG_BROADCAST, (short)G_EDICTNUM(prinst, OFS_PARM0));
|
||||
}
|
||||
#endif
|
||||
|
||||
//======================================================
|
||||
|
||||
|
@ -5354,7 +5353,7 @@ static void QCBUILTIN PF_Ignore(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
G_INT(OFS_RETURN) = 0;
|
||||
}
|
||||
|
||||
#define PRSTR 0xa6ffb3d7
|
||||
#ifndef QUAKETC
|
||||
static void QCBUILTIN PF_newstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //mvdsv
|
||||
{
|
||||
char *s;
|
||||
|
@ -5370,6 +5369,7 @@ static void QCBUILTIN PF_newstring(pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
G_INT(OFS_RETURN) = (char*)s - prinst->stringtable;
|
||||
strcpy(s, in);
|
||||
}
|
||||
#endif
|
||||
|
||||
// warning: ‘PF_strcatp’ defined but not used
|
||||
/*
|
||||
|
@ -5927,6 +5927,7 @@ void QCBUILTIN PF_ExecuteCommand (pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
pr_global_struct->other = old_other;
|
||||
}
|
||||
|
||||
#ifndef QUAKETC
|
||||
/*
|
||||
=================
|
||||
PF_teamfield
|
||||
|
@ -6241,7 +6242,7 @@ static void QCBUILTIN PF_log(pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
if (G_FLOAT(OFS_PARM1))
|
||||
Con_Printf("%s", text);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void QCBUILTIN PF_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -6467,6 +6468,126 @@ static void QCBUILTIN PF_clientcommand (pubprogfuncs_t *prinst, struct globalvar
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char *SV_CheckRejectConnection(netadr_t *adr, const char *uinfo, unsigned int protocol, unsigned int pext1, unsigned int pext2, char *guid)
|
||||
{
|
||||
char addrstr[256];
|
||||
char clfeatures[4096], *bp;
|
||||
const char *ret = NULL;
|
||||
if (gfuncs.CheckRejectConnection)
|
||||
{
|
||||
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
||||
|
||||
NET_AdrToString(addrstr, sizeof(addrstr), adr);
|
||||
|
||||
*clfeatures = 0;
|
||||
switch(protocol)
|
||||
{
|
||||
default: bp = "unknown"; break;
|
||||
case SCP_QUAKEWORLD: bp = "qw"; break;
|
||||
case SCP_QUAKE2: bp = "q2"; break;
|
||||
case SCP_QUAKE3: bp = "q3"; break;
|
||||
case SCP_NETQUAKE: bp = "nq"; break;
|
||||
case SCP_PROQUAKE: bp = "nq"; break; //not nuff difference for it to be meaningful
|
||||
case SCP_FITZ666: bp = "fitz666"; break;
|
||||
case SCP_DARKPLACES6: bp = "dp6"; break;
|
||||
case SCP_DARKPLACES7: bp = "dp7"; break;
|
||||
}
|
||||
Info_SetValueForKey(clfeatures, "basicprotocol", bp, sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "guid", guid, sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "maxsounds", "256", sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "maxmodels", "256", sizeof(clfeatures));
|
||||
|
||||
//this is not the limits of the client itself, but the limits that the server is able and willing to send to them.
|
||||
|
||||
if ((pext1 & PEXT_SOUNDDBL) || (protocol == SCP_FITZ666 || protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "maxsounds", va("%i", MAX_PRECACHE_SOUNDS), sizeof(clfeatures));
|
||||
else
|
||||
Info_SetValueForKey(clfeatures, "maxsounds", "256", sizeof(clfeatures));
|
||||
|
||||
if ((pext1 & PEXT_MODELDBL) || (protocol == SCP_FITZ666 || protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "maxmodels", va("%i", MAX_PRECACHE_MODELS), sizeof(clfeatures));
|
||||
else
|
||||
Info_SetValueForKey(clfeatures, "maxmodels", "256", sizeof(clfeatures));
|
||||
|
||||
if (pext2 & PEXT2_REPLACEMENTDELTAS)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", va("%i", MAX_EDICTS), sizeof(clfeatures));
|
||||
else if (protocol == SCP_FITZ666)
|
||||
// Info_SetValueForKey(clfeatures, "maxentities", "65535", sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "32767", sizeof(clfeatures));
|
||||
else if (protocol == SCP_DARKPLACES6 || protocol == SCP_DARKPLACES7)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "32767", sizeof(clfeatures));
|
||||
else if (pext1 & PEXT_ENTITYDBL2)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "2048", sizeof(clfeatures));
|
||||
else if (pext1 & PEXT_ENTITYDBL)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "1024", sizeof(clfeatures));
|
||||
else if (protocol == SCP_NETQUAKE)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "600", sizeof(clfeatures));
|
||||
else //if (protocol == SCP_QUAKEWORLD)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "512", sizeof(clfeatures));
|
||||
|
||||
if (pext2 & PEXT2_REPLACEMENTDELTAS) //limited by packetlog/size, but server can track the whole lot, assuming they're not all sent in a single packet.
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", va("%i", MAX_EDICTS), sizeof(clfeatures));
|
||||
else if (protocol == SCP_DARKPLACES6 || protocol == SCP_DARKPLACES7) //deltaing protocol allows all ents to be visible at once
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", "32767", sizeof(clfeatures));
|
||||
else if (pext1 & PEXT_256PACKETENTITIES)
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", "256", sizeof(clfeatures));
|
||||
else if (protocol == SCP_QUAKEWORLD)
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", "64", sizeof(clfeatures));
|
||||
//others are limited by packet sizes, so the count can vary...
|
||||
|
||||
//features
|
||||
if (pext1 & PEXT_VIEW2)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_VIEW2", "1", sizeof(clfeatures));
|
||||
if (pext1 & PEXT_LIGHTSTYLECOL)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_LIGHTSTYLECOL", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_CSQC) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_CSQC", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_FLOATCOORDS) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_FLOATCOORDS", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_ENTITYDBL) || (pext2 & PEXT2_REPLACEMENTDELTAS) || (protocol == SCP_FITZ666 || protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_ENTITYDBL", "1", sizeof(clfeatures));
|
||||
if (pext1 & PEXT_HEXEN2)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_HEXEN2", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_SETATTACHMENT) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_SETATTACHMENT", "1", sizeof(clfeatures));
|
||||
if (pext1 & PEXT_CUSTOMTEMPEFFECTS)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_CUSTOMTEMPEFFECTS", "1", sizeof(clfeatures));
|
||||
if ((pext2 & PEXT2_PRYDONCURSOR) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT2_PRYDONCURSOR", "1", sizeof(clfeatures));
|
||||
if (pext2 & PEXT2_VOICECHAT)
|
||||
Info_SetValueForKey(clfeatures, "PEXT2_VOICECHAT", "1", sizeof(clfeatures));
|
||||
if (pext2 & PEXT2_REPLACEMENTDELTAS)
|
||||
Info_SetValueForKey(clfeatures, "PEXT2_REPLACEMENTDELTAS", "1", sizeof(clfeatures));
|
||||
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts);
|
||||
G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, addrstr);
|
||||
G_INT(OFS_PARM1) = (int)PR_TempString(svprogfuncs, uinfo);
|
||||
G_INT(OFS_PARM2) = (int)PR_TempString(svprogfuncs, clfeatures);
|
||||
PR_ExecuteProgram (svprogfuncs, gfuncs.CheckRejectConnection);
|
||||
ret = PR_GetStringOfs(svprogfuncs, OFS_RETURN);
|
||||
if (!*ret)
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void SV_AddDebugPolygons(void)
|
||||
{
|
||||
int i;
|
||||
if (gfuncs.AddDebugPolygons)
|
||||
{
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts);
|
||||
for (i = 0; i < sv.allocated_client_slots; i++)
|
||||
if (svs.clients[i].netchan.remote_address.type == NA_LOOPBACK)
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
|
||||
PR_ExecuteProgram (svprogfuncs, gfuncs.AddDebugPolygons);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
static void QCBUILTIN PF_h2AdvanceFrame(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
edict_t *Ent;
|
||||
|
@ -6583,121 +6704,6 @@ static void QCBUILTIN PF_h2advanceweaponframe (pubprogfuncs_t *prinst, struct gl
|
|||
G_FLOAT(OFS_RETURN) = state;
|
||||
}
|
||||
|
||||
const char *SV_CheckRejectConnection(netadr_t *adr, const char *uinfo, unsigned int protocol, unsigned int pext1, unsigned int pext2, char *guid)
|
||||
{
|
||||
char addrstr[256];
|
||||
char clfeatures[4096], *bp;
|
||||
const char *ret = NULL;
|
||||
if (gfuncs.CheckRejectConnection)
|
||||
{
|
||||
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
||||
|
||||
NET_AdrToString(addrstr, sizeof(addrstr), adr);
|
||||
|
||||
*clfeatures = 0;
|
||||
switch(protocol)
|
||||
{
|
||||
default: bp = "unknown"; break;
|
||||
case SCP_QUAKEWORLD: bp = "qw"; break;
|
||||
case SCP_QUAKE2: bp = "q2"; break;
|
||||
case SCP_QUAKE3: bp = "q3"; break;
|
||||
case SCP_NETQUAKE: bp = "nq"; break;
|
||||
case SCP_PROQUAKE: bp = "nq"; break; //not nuff difference for it to be meaningful
|
||||
case SCP_FITZ666: bp = "fitz666"; break;
|
||||
case SCP_DARKPLACES6: bp = "dp6"; break;
|
||||
case SCP_DARKPLACES7: bp = "dp7"; break;
|
||||
}
|
||||
Info_SetValueForKey(clfeatures, "basicprotocol", bp, sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "guid", guid, sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "maxsounds", "256", sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "maxmodels", "256", sizeof(clfeatures));
|
||||
|
||||
//this is not the limits of the client itself, but the limits that the server is able and willing to send to them.
|
||||
|
||||
if ((pext1 & PEXT_SOUNDDBL) || (protocol == SCP_FITZ666 || protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "maxsounds", va("%i", MAX_SOUNDS), sizeof(clfeatures));
|
||||
else
|
||||
Info_SetValueForKey(clfeatures, "maxsounds", "256", sizeof(clfeatures));
|
||||
|
||||
if ((pext1 & PEXT_MODELDBL) || (protocol == SCP_FITZ666 || protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "maxmodels", va("%i", MAX_MODELS), sizeof(clfeatures));
|
||||
else
|
||||
Info_SetValueForKey(clfeatures, "maxmodels", "256", sizeof(clfeatures));
|
||||
|
||||
if (pext2 & PEXT2_REPLACEMENTDELTAS)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", va("%i", MAX_EDICTS), sizeof(clfeatures));
|
||||
else if (protocol == SCP_FITZ666)
|
||||
// Info_SetValueForKey(clfeatures, "maxentities", "65535", sizeof(clfeatures));
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "32767", sizeof(clfeatures));
|
||||
else if (protocol == SCP_DARKPLACES6 || protocol == SCP_DARKPLACES7)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "32767", sizeof(clfeatures));
|
||||
else if (pext1 & PEXT_ENTITYDBL2)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "2048", sizeof(clfeatures));
|
||||
else if (pext1 & PEXT_ENTITYDBL)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "1024", sizeof(clfeatures));
|
||||
else if (protocol == SCP_NETQUAKE)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "600", sizeof(clfeatures));
|
||||
else //if (protocol == SCP_QUAKEWORLD)
|
||||
Info_SetValueForKey(clfeatures, "maxentities", "512", sizeof(clfeatures));
|
||||
|
||||
if (pext2 & PEXT2_REPLACEMENTDELTAS) //limited by packetlog/size, but server can track the whole lot, assuming they're not all sent in a single packet.
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", va("%i", MAX_EDICTS), sizeof(clfeatures));
|
||||
else if (protocol == SCP_DARKPLACES6 || protocol == SCP_DARKPLACES7) //deltaing protocol allows all ents to be visible at once
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", "32767", sizeof(clfeatures));
|
||||
else if (pext1 & PEXT_256PACKETENTITIES)
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", "256", sizeof(clfeatures));
|
||||
else if (protocol == SCP_QUAKEWORLD)
|
||||
Info_SetValueForKey(clfeatures, "maxvisentities", "64", sizeof(clfeatures));
|
||||
//others are limited by packet sizes, so the count can vary...
|
||||
|
||||
//features
|
||||
if (pext1 & PEXT_VIEW2)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_VIEW2", "1", sizeof(clfeatures));
|
||||
if (pext1 & PEXT_LIGHTSTYLECOL)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_LIGHTSTYLECOL", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_CSQC) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_CSQC", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_FLOATCOORDS) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_FLOATCOORDS", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_ENTITYDBL) || (pext2 & PEXT2_REPLACEMENTDELTAS) || (protocol == SCP_FITZ666 || protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_ENTITYDBL", "1", sizeof(clfeatures));
|
||||
if (pext1 & PEXT_HEXEN2)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_HEXEN2", "1", sizeof(clfeatures));
|
||||
if ((pext1 & PEXT_SETATTACHMENT) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT_SETATTACHMENT", "1", sizeof(clfeatures));
|
||||
if (pext1 & PEXT_CUSTOMTEMPEFFECTS)
|
||||
Info_SetValueForKey(clfeatures, "PEXT_CUSTOMTEMPEFFECTS", "1", sizeof(clfeatures));
|
||||
if ((pext2 & PEXT2_PRYDONCURSOR) || (protocol == SCP_DARKPLACES6) || (protocol == SCP_DARKPLACES7))
|
||||
Info_SetValueForKey(clfeatures, "PEXT2_PRYDONCURSOR", "1", sizeof(clfeatures));
|
||||
if (pext2 & PEXT2_VOICECHAT)
|
||||
Info_SetValueForKey(clfeatures, "PEXT2_VOICECHAT", "1", sizeof(clfeatures));
|
||||
if (pext2 & PEXT2_REPLACEMENTDELTAS)
|
||||
Info_SetValueForKey(clfeatures, "PEXT2_REPLACEMENTDELTAS", "1", sizeof(clfeatures));
|
||||
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts);
|
||||
G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, addrstr);
|
||||
G_INT(OFS_PARM1) = (int)PR_TempString(svprogfuncs, uinfo);
|
||||
G_INT(OFS_PARM2) = (int)PR_TempString(svprogfuncs, clfeatures);
|
||||
PR_ExecuteProgram (svprogfuncs, gfuncs.CheckRejectConnection);
|
||||
ret = PR_GetStringOfs(svprogfuncs, OFS_RETURN);
|
||||
if (!*ret)
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void SV_AddDebugPolygons(void)
|
||||
{
|
||||
int i;
|
||||
if (gfuncs.AddDebugPolygons)
|
||||
{
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts);
|
||||
for (i = 0; i < sv.allocated_client_slots; i++)
|
||||
if (svs.clients[i].netchan.remote_address.type == NA_LOOPBACK)
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
|
||||
PR_ExecuteProgram (svprogfuncs, gfuncs.AddDebugPolygons);
|
||||
}
|
||||
}
|
||||
|
||||
void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc)
|
||||
{
|
||||
char temp[16];
|
||||
|
@ -7512,6 +7518,7 @@ static void QCBUILTIN PF_h2getstring(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
char *s = T_GetString(G_FLOAT(OFS_PARM0)-1);
|
||||
RETURN_PSTRING(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void QCBUILTIN PF_RegisterTEnt(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -8327,6 +8334,9 @@ int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *v
|
|||
}
|
||||
else if (entnum <= sv.allocated_client_slots)
|
||||
{ //woo. we found a client.
|
||||
char *oldvalue = Info_ValueForKey(svs.clients[entnum-1].userinfo, key);
|
||||
if (strcmp(oldvalue, value))
|
||||
{
|
||||
Info_SetValueForStarKey(svs.clients[entnum-1].userinfo, key, value, sizeof(svs.clients[entnum-1].userinfo));
|
||||
|
||||
SV_ExtractFromUserinfo (&svs.clients[entnum-1], false);
|
||||
|
@ -8346,6 +8356,7 @@ int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *v
|
|||
PF_ForceInfoKey_Internal(entnum, key, "");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -8656,6 +8667,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
|
|||
pmove.groundent = 0;
|
||||
pmove.waterlevel = 0;
|
||||
pmove.watertype = 0;
|
||||
pmove.capsule = (ent->xv->geomtype == GEOMTYPE_CYLINDER);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
|
@ -9035,7 +9047,6 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"setmodel", PF_setmodel, 3, 3, 3, 0, D("void(entity e, string m)","Looks up m in the model precache list, and sets both e.model and e.modelindex to match. BSP models will set e.mins and e.maxs accordingly, other models depend upon the value of sv_gameplayfix_setmodelrealbox - for compatibility you should always call setsize after all pickups or non-bsp models. Also relinks collision state.")},
|
||||
{"setsize", PF_setsize, 4, 4, 4, 0, D("void(entity e, vector min, vector max)", "Sets the e's mins and maxs fields. Also relinks collision state, which sets absmin and absmax too.")},
|
||||
{"qtest_setabssize",PF_setsize, 5, 0, 0, 0, D("void(entity e, vector min, vector max)", "qtest"), true},
|
||||
{"lightstylestatic",PF_lightstylestatic,0, 0, 5, 5, D("void(float style, float val, optional vector rgb)", "Sets the lightstyle to an explicit numerical level. From Hexen2.")},
|
||||
{"breakpoint", PF_break, 6, 6, 6, 0, D("void()", "Trigger a debugging event. FTE will break into the qc debugger. Other engines may crash with a debug execption.")},
|
||||
{"random", PF_random, 7, 7, 7, 0, D("float()", "Returns a random value between 0 and 1. Be warned, this builtin can return 1 in most engines, which can break arrays.")},
|
||||
{"sound", PF_sound, 8, 8, 8, 0, D("void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags)", "Starts a sound centered upon the given entity.\nchan is the entity sound channel to use, channel 0 will allow you to mix many samples at once, others will replace the old sample\n'samp' must have been precached first\nif specified, 'speedpct' should normally be around 100 (or =0), 200 for double speed or 50 for half speed.\nflags&1 means the sound should be sent reliably.")},
|
||||
|
@ -9068,7 +9079,6 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"traceoff", PF_traceoff, 30, 30, 30, 0, D("void()", "Disables tracing again.")},
|
||||
{"eprint", PF_eprint, 31, 31, 31, 0, D("void(entity e)", "Debugging builtin that prints all fields of the given entity to the console.")},// debug print an entire entity
|
||||
{"walkmove", PF_walkmove, 32, 32, 32, 0, D("float(float yaw, float dist, optional float settraceglobals)", "Attempt to walk the entity at a given angle for a given distance.\nif settraceglobals is set, the trace_* globals will be set, showing the results of the movement.\nThis function will trigger touch events.")},
|
||||
{"tracearea", PF_traceboxh2, 0, 0, 33, 0, D("void(vector v1, vector v2, vector mins, vector maxs, float nomonsters, entity ent)", "For hexen2 compat")},
|
||||
// {"qtest_flymove", NULL, 33}, // float(vector dir) flymove = #33;
|
||||
//qbism super8's 'private'sound #33
|
||||
{"droptofloor", PF_droptofloor, 34, 34, 34, 0, D("float()", "Instantly moves the entity downwards until it hits the ground. If the entity would need to drop more than 'pr_droptofloorunits' quake units, its position will be considered invalid and the builtin will abort.")},
|
||||
|
@ -9088,7 +9098,6 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"particle", PF_particle, 48, 0, 48, 48, D("void(vector pos, vector dir, float colour, float count)", "Spawn 'count' particles around 'pos' moving in the direction 'dir', with a palette colour index between 'colour' and 'colour+8'.")}, //48 nq readded. This isn't present in QW protocol (fte added it back).
|
||||
{"changeyaw", PF_changeyaw, 49, 49, 49, 0, D("#define ChangeYaw changeyaw\nvoid()", "Changes the self.angles_y field towards self.ideal_yaw by up to self.yawspeed.")},
|
||||
// {"qtest_precacheitem", NULL, 50}, // defined QTest builtin that is never called
|
||||
{"vhlen", PF_vhlen, 0, 0, 50, 0, D("float(vector)", "Returns the horizontal length of the given vector ignoring z dispalcement - specifically sqrt(x*x+y*y)")},
|
||||
{"vectoangles", PF_vectoangles, 51, 51, 51, 0, D("vector(vector fwd, optional vector up)", "Returns the angles required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning.")},
|
||||
|
||||
{"WriteByte", PF_WriteByte, 52, 52, 52, 0, D("void(float to, float val)", "Writes a single byte into a network message buffer. Typically you will find a more correct alternative to writing arbitary data. 'to' should be one of the MSG_* constants. MSG_ONE must have msg_entity set first.")}, //52
|
||||
|
@ -9100,6 +9109,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"WriteString", PF_WriteString, 58, 58, 58, 0, "void(float to, string val)"}, //58
|
||||
{"WriteEntity", PF_WriteEntity, 59, 59, 59, 0, "void(float to, entity val)"}, //59
|
||||
|
||||
#ifndef QUAKETC
|
||||
{"swritebyte", PF_qtSingle_WriteByte}, //52
|
||||
{"swritechar", PF_qtSingle_WriteChar}, //53
|
||||
{"swriteshort", PF_qtSingle_WriteShort}, //54
|
||||
|
@ -9117,23 +9127,12 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"bwriteangle", PF_qtBroadcast_WriteAngle}, //64
|
||||
{"bwritestring", PF_qtBroadcast_WriteString}, //65
|
||||
{"bwriteentity", PF_qtBroadcast_WriteEntity}, //66
|
||||
|
||||
|
||||
{"printfloat", PF_h2dprintf, 0, 0, 60}, //60
|
||||
#endif
|
||||
|
||||
{"sin", PF_Sin, 0, 0, 62, 60, "float(float angle)"}, //60
|
||||
{"cos", PF_Cos, 0, 0, 61, 61, "float(float angle)"}, //61
|
||||
{"sqrt", PF_Sqrt, 0, 0, 84, 62, "float(float value)"}, //62
|
||||
|
||||
{"AdvanceFrame", PF_h2AdvanceFrame, 0, 0, 63, 0},
|
||||
{"printvec", PF_h2dprintv, 0, 0, 64, 0}, //64
|
||||
{"RewindFrame", PF_h2RewindFrame, 0, 0, 65, 0},
|
||||
{"particleexplosion",PF_h2particleexplosion,0, 0, 81, 0},
|
||||
{"movestep", PF_h2movestep, 0, 0, 82, 0},
|
||||
{"advanceweaponframe",PF_h2advanceweaponframe,0,0, 83, 0},
|
||||
|
||||
{"setclass", PF_h2setclass, 0, 0, 66, 0},
|
||||
|
||||
{"changepitch", PF_changepitch, 0, 0, 0, 63, "void(entity ent)"},
|
||||
{"tracetoss", PF_TraceToss, 0, 0, 0, 64, "void(entity ent, entity ignore)"},
|
||||
{"etos", PF_etos, 0, 0, 0, 65, "string(entity ent)"},
|
||||
|
@ -9143,7 +9142,6 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"makestatic", PF_makestatic, 69, 69, 69, 0, D("void(entity e)", "Sends a copy of the entity's renderable fields to all clients, and REMOVES the entity, preventing further changes. This means it will be unmutable and non-solid.")}, //69
|
||||
|
||||
{"changelevel", PF_changelevel, 70, 70, 70, 0, D("void(string mapname, optional string newmapstartspot)", "Attempts to change the map to the named map. If 'newmapstartspot' is specified, the state of the current map will be preserved, and the argument will be passed to the next map in the 'startspot' global, and the next map will be loaded from archived state if it was previously visited. If not specified, all archived map states will be purged.")}, //70
|
||||
{"lightstylevalue", PF_lightstylevalue, 0, 0, 71, 0, D("float(float lstyle)", "Returns the last value passed into the lightstylestatic builtin, or the first value specified by the style string passed to the lightstyle builtin")}, //70
|
||||
|
||||
{"cvar_set", PF_cvar_set, 72, 72, 72, 0, D("void(string cvarname, string valuetoset)", "Instantly sets a cvar to the given string value.")}, //72
|
||||
{"centerprint", PF_centerprint, 73, 73, 73, 0, "void(entity ent, string text, optional string text2, optional string text3, optional string text4, optional string text5, optional string text6, optional string text7)"}, //73
|
||||
|
@ -9155,7 +9153,6 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"precache_file2", PF_precache_file, 77, 77, 0, 0, "string(string str)"}, //77
|
||||
|
||||
{"setspawnparms", PF_setspawnparms, 78, 78, 78, 0, "void(entity player)"}, //78
|
||||
{"plaque_draw", PF_h2plaque_draw, 0, 0, 79, 0, "void(entity targ, float stringno)"}, //79
|
||||
{"logfrag", PF_logfrag, 0, 79, 0, 79, "void(entity killer, entity killee)"}, //79
|
||||
|
||||
// Tomaz - QuakeC String Manipulation Begin
|
||||
|
@ -9175,15 +9172,13 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"tq_fputs", PF_fputs, 0, 0, 0, 89, D("void(filestream fhandle, string s)",NULL), true},// (QSG_FILE)
|
||||
// Tomaz - QuakeC File System End
|
||||
|
||||
{"rain_go", PF_h2rain_go, 0, 0, 80, 0}, //80
|
||||
|
||||
{"infokey", PF_infokey, 0, 80, 0, 80, D("string(entity e, string key)", "If e is world, returns the field 'key' from either the serverinfo or the localinfo. If e is a player, returns the value of 'key' from the player's userinfo string. There are a few special exceptions, like 'ip' which is not technically part of the userinfo.")}, //80
|
||||
{"stof", PF_stof, 0, 81, 0, 81, "float(string)"}, //81
|
||||
{"multicast", PF_multicast, 0, 82, 0, 82, D("#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0)\n"
|
||||
"void(vector where, float set)", "Once the MSG_MULTICAST network message buffer has been filled with data, this builtin is used to dispatch it to the given target, filtering by pvs for reduced network bandwidth.")}, //82
|
||||
|
||||
|
||||
|
||||
#ifndef QUAKETC
|
||||
//mvdsv (don't require ebfs usage in qw)
|
||||
{"executecommand", PF_ExecuteCommand, 0, 0, 0, 83, D("void()",NULL), true},
|
||||
{"mvdtokenize", PF_Tokenize, 0, 0, 0, 84, D("void(string str)",NULL), true},
|
||||
|
@ -9212,7 +9207,25 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"mvdcalltimeofday",PF_calltimeofday, 0, 0, 0, 102, D("void()",NULL), true},
|
||||
{"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103, D("void(float now)",NULL), true},
|
||||
//end of mvdsv
|
||||
#endif
|
||||
|
||||
#ifdef HEXEN2
|
||||
{"lightstylestatic",PF_lightstylestatic,0, 0, 5, 5, D("void(float style, float val, optional vector rgb)", "Sets the lightstyle to an explicit numerical level. From Hexen2.")},
|
||||
{"tracearea", PF_traceboxh2, 0, 0, 33, 0, D("void(vector v1, vector v2, vector mins, vector maxs, float nomonsters, entity ent)", "For hexen2 compat")},
|
||||
{"vhlen", PF_vhlen, 0, 0, 50, 0, D("float(vector)", "Returns the horizontal length of the given vector ignoring z dispalcement - specifically sqrt(x*x+y*y)")},
|
||||
{"printfloat", PF_h2dprintf, 0, 0, 60, 0}, //60
|
||||
{"AdvanceFrame", PF_h2AdvanceFrame, 0, 0, 63, 0},
|
||||
{"printvec", PF_h2dprintv, 0, 0, 64, 0}, //64
|
||||
{"RewindFrame", PF_h2RewindFrame, 0, 0, 65, 0},
|
||||
{"particleexplosion",PF_h2particleexplosion,0, 0, 81, 0},
|
||||
{"movestep", PF_h2movestep, 0, 0, 82, 0},
|
||||
{"advanceweaponframe",PF_h2advanceweaponframe,0,0, 83, 0},
|
||||
|
||||
{"setclass", PF_h2setclass, 0, 0, 66, 0},
|
||||
{"lightstylevalue", PF_lightstylevalue, 0, 0, 71, 0, D("float(float lstyle)", "Returns the last value passed into the lightstylestatic builtin, or the first value specified by the style string passed to the lightstyle builtin")}, //70
|
||||
|
||||
{"plaque_draw", PF_h2plaque_draw, 0, 0, 79, 0, "void(entity targ, float stringno)"}, //79
|
||||
{"rain_go", PF_h2rain_go, 0, 0, 80, 0}, //80
|
||||
{"setpuzzlemodel", PF_h2set_puzzle_model,0, 0, 87, 0},
|
||||
{"starteffect", PF_h2starteffect, 0, 0, 88, 0}, //FIXME
|
||||
{"endeffect", PF_h2endeffect, 0, 0, 89, 0}, //FIXME
|
||||
|
@ -9237,6 +9250,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
|
||||
{"precache_model4", PF_precache_model, 0, 0, 116, 0},//please don't use...
|
||||
{"precache_sound4", PF_precache_sound, 0, 0, 117, 0},
|
||||
#endif
|
||||
|
||||
{"tracebox", PF_traceboxdp, 0, 0, 0, 90, D("void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent)", "Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values.")},
|
||||
|
||||
|
@ -9293,9 +9307,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"externset", PF_externset, 0, 0, 0, 204, D("void(float prnum, __variant newval, string varname)", "Sets a global in the named progs by name.\nprnum=0 is the 'default' or 'main' progs.\nprnum=-1 means current progs.\nprnum=-2 will scan through the active progs and will use the first it finds.")},
|
||||
{"externrefcall", PF_externrefcall, 0, 0, 0, 205, D("__variant(float prnum, void() func, ...)","Calls a function between progs by its reference. No longer needed as direct function calls now switch progs context automatically, and have done for a long time. There is no remaining merit for this function."), true},
|
||||
{"instr", PF_instr, 0, 0, 0, 206, D("float(string input, string token)", "Returns substring(input, strstrpos(input, token), -1), or the null string if token was not found in input. You're probably better off using strstrpos.")},
|
||||
#if defined(Q2BSPS) || defined(Q3BSPS)
|
||||
{"openportal", PF_OpenPortal, 0, 0, 0, 207, D("void(entity portal, float state)", "Opens or closes the portals associated with a door or some such on q2 or q3 maps. On Q2BSPs, the entity should be the 'func_areaportal' entity - its style field will say which portal to open. On Q3BSPs, the entity is the door itself, the portal will be determined by the two areas found from a preceding setorigin call.")},
|
||||
#endif
|
||||
|
||||
{"RegisterTempEnt", PF_RegisterTEnt, 0, 0, 0, 208, "float(float attributes, string effectname, ...)"},
|
||||
{"CustomTempEnt", PF_CustomTEnt, 0, 0, 0, 209, "void(float type, vector pos, ...)"},
|
||||
|
@ -9306,10 +9318,12 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
#ifdef SVCHAT
|
||||
{"chat", PF_chat, 0, 0, 0, 214, "void(string filename, float starttag, entity edict)"}, //(FTE_NPCCHAT)
|
||||
#endif
|
||||
//FTE_PEXT_HEXEN2
|
||||
|
||||
#ifdef HEXEN2
|
||||
{"particle2", PF_particle2, 0, 0, 42, 215, "void(vector org, vector dmin, vector dmax, float colour, float effect, float count)"},
|
||||
{"particle3", PF_particle3, 0, 0, 85, 216, "void(vector org, vector box, float colour, float effect, float count)"},
|
||||
{"particle4", PF_particle4, 0, 0, 86, 217, "void(vector org, float radius, float colour, float effect, float count)"},
|
||||
#endif
|
||||
|
||||
//EXT_DIMENSION_PLANES
|
||||
{"bitshift", PF_bitshift, 0, 0, 0, 218, "float(float number, float quantity)"},
|
||||
|
@ -9789,7 +9803,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
|
||||
//end dp extras
|
||||
|
||||
{"getrmqeffectsversion", PF_Ignore, 0, 0, 0, 666, "float()" STUB},
|
||||
{"getrmqeffectsversion",PF_Ignore, 0, 0, 0, 666, "float()" STUB},
|
||||
//don't exceed sizeof(pr_builtin)/sizeof(pr_builtin[0]) (currently 1024) without modifing the size of pr_builtin
|
||||
|
||||
{NULL}
|
||||
|
@ -9852,6 +9866,7 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any
|
|||
builtincount[i]=100;
|
||||
}
|
||||
|
||||
#ifndef QUAKETC
|
||||
if (type == PROG_PREREL)
|
||||
{
|
||||
pr_builtin[52] = PF_qtSingle_WriteByte;
|
||||
|
@ -9872,6 +9887,7 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any
|
|||
pr_builtin[65] = PF_qtBroadcast_WriteString;
|
||||
pr_builtin[66] = PF_qtBroadcast_WriteEntity;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!pr_compatabilitytest.value)
|
||||
{
|
||||
|
@ -10109,7 +10125,11 @@ svextqcfields
|
|||
#define H2 16
|
||||
//mere flags
|
||||
#define FTE 32
|
||||
#ifdef HEXEN2
|
||||
#define ALL (QW|NQ|H2|CS|MENU)
|
||||
#else
|
||||
#define ALL (QW|NQ|CS|MENU)
|
||||
#endif
|
||||
#define CORE
|
||||
typedef struct
|
||||
{
|
||||
|
@ -10558,7 +10578,7 @@ void PR_DumpPlatform_f(void)
|
|||
{"MOVE_EVERYTHING", "const float", QW|NQ|CS, "This type of trace will hit solids and triggers alike. Even non-solid entities.", MOVE_EVERYTHING},
|
||||
{"MOVE_LAGGED", "const float", QW|NQ, "Will use antilag based upon the player's latency. Traces will be performed against old positions for entities instead of their current origin.", MOVE_LAGGED},
|
||||
{"MOVE_ENTCHAIN", "const float", QW|NQ|CS, "Returns a list of entities impacted via the trace_ent.chain field", MOVE_ENTCHAIN},
|
||||
{"MOVE_ONLYENT", "const float", QW|NQ|CS, "Traces that use this trace type will collide against *only* the entity specified, and will ignore all owner/solid/dimension etc fields, they will still adhere to contents though.", MOVE_ONLYENT},
|
||||
// {"MOVE_ONLYENT", "const float", QW|NQ|CS, "Traces that use this trace type will collide against *only* the entity specified, and will ignore all owner/solid/dimension etc fields, they will still adhere to contents though.", MOVE_ONLYENT},
|
||||
|
||||
{"EF_BRIGHTFIELD", "const float", QW|NQ|CS, NULL, EF_BRIGHTFIELD},
|
||||
{"EF_MUZZLEFLASH", "const float", NQ|CS, NULL, EF_MUZZLEFLASH},
|
||||
|
|
|
@ -1940,7 +1940,6 @@ static qboolean Lua_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldw
|
|||
return false; //always do legacy behaviour
|
||||
}
|
||||
|
||||
void PR_SV_FillWorldGlobals(world_t *w);
|
||||
static void Lua_SetupGlobals(world_t *world)
|
||||
{
|
||||
int flds;
|
||||
|
|
|
@ -47,8 +47,6 @@ oh, wait, ktx no longer supports those properly.
|
|||
#define MAX_Q1QVM_EDICTS 768 //according to ktx at api version 12 (fte's protocols go to 2048)
|
||||
#define MAPNAME_LEN 64
|
||||
|
||||
#define VMFSID_Q1QVM 57235 //a cookie
|
||||
|
||||
void PR_SV_FillWorldGlobals(world_t *w);
|
||||
|
||||
#if GAME_API_VERSION >= 13
|
||||
|
@ -561,7 +559,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
|
||||
case G_GetEntityToken:
|
||||
{
|
||||
if (VM_OOB(arg[0], arg[1]))
|
||||
if (VM_OOB(arg[0], arg[1]) || !arg[1])
|
||||
return false;
|
||||
if (q1qvmentstring)
|
||||
{
|
||||
|
@ -573,7 +571,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
else
|
||||
{
|
||||
char *ret = VM_POINTER(arg[0]);
|
||||
strcpy(ret, "");
|
||||
*ret = '\0';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ void PF_InitTempStrings(pubprogfuncs_t *prinst);
|
|||
qboolean PR_LoadLua(void);
|
||||
#endif
|
||||
#ifdef VM_Q1
|
||||
#define VMFSID_Q1QVM 57235 //the q1qvm zone tag that is freed when the module is purged.
|
||||
struct client_s;
|
||||
void Q1QVM_Shutdown(void);
|
||||
qboolean PR_LoadQ1QVM(void);
|
||||
|
|
|
@ -77,7 +77,7 @@ void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
|||
int filelen, filepos;
|
||||
char *file;
|
||||
|
||||
char *modelnames[MAX_MODELS];
|
||||
char *modelnames[MAX_PRECACHE_MODELS];
|
||||
|
||||
if (version != 667 && version != 5 && version != 6) //5 for NQ, 6 for ZQ/FQ
|
||||
{
|
||||
|
@ -241,7 +241,7 @@ void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
|||
}
|
||||
|
||||
//model names are pointers to vm-accessible memory. as that memory is going away, we need to destroy and recreate, which requires preserving them.
|
||||
for (i = 1; i < MAX_MODELS; i++)
|
||||
for (i = 1; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
if (!sv.strings.model_precache[i])
|
||||
{
|
||||
|
@ -268,7 +268,7 @@ void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
|||
}
|
||||
|
||||
//reload model names.
|
||||
for (i = 1; i < MAX_MODELS; i++)
|
||||
for (i = 1; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
if (!modelnames[i])
|
||||
break;
|
||||
|
@ -480,7 +480,7 @@ void LoadModelsAndSounds(vfsfile_t *f)
|
|||
int i;
|
||||
|
||||
sv.strings.model_precache[0] = PR_AddString(svprogfuncs, "", 0, false);
|
||||
for (i=1; i < MAX_MODELS; i++)
|
||||
for (i=1; i < MAX_PRECACHE_MODELS; i++)
|
||||
{
|
||||
VFS_GETS(f, str, sizeof(str));
|
||||
if (!*str)
|
||||
|
@ -488,17 +488,17 @@ void LoadModelsAndSounds(vfsfile_t *f)
|
|||
|
||||
sv.strings.model_precache[i] = PR_AddString(svprogfuncs, str, 0, false);
|
||||
}
|
||||
if (i == MAX_MODELS)
|
||||
if (i == MAX_PRECACHE_MODELS)
|
||||
{
|
||||
VFS_GETS(f, str, sizeof(str));
|
||||
if (*str)
|
||||
SV_Error("Too many model precaches in loadgame cache");
|
||||
}
|
||||
for (; i < MAX_MODELS; i++)
|
||||
for (; i < MAX_PRECACHE_MODELS; i++)
|
||||
sv.strings.model_precache[i] = NULL;
|
||||
|
||||
// sv.sound_precache[0] = PR_AddString(svprogfuncs, "", 0);
|
||||
for (i=1; i < MAX_SOUNDS; i++)
|
||||
for (i=1; i < MAX_PRECACHE_SOUNDS; i++)
|
||||
{
|
||||
VFS_GETS(f, str, sizeof(str));
|
||||
if (!*str)
|
||||
|
@ -506,13 +506,13 @@ void LoadModelsAndSounds(vfsfile_t *f)
|
|||
|
||||
// sv.sound_precache[i] = PR_AddString(svprogfuncs, str, 0);
|
||||
}
|
||||
if (i == MAX_SOUNDS)
|
||||
if (i == MAX_PRECACHE_SOUNDS)
|
||||
{
|
||||
VFS_GETS(f, str, sizeof(str));
|
||||
if (*str)
|
||||
SV_Error("Too many sound precaches in loadgame cache");
|
||||
}
|
||||
for (; i < MAX_SOUNDS; i++)
|
||||
for (; i < MAX_PRECACHE_SOUNDS; i++)
|
||||
*sv.strings.sound_precache[i] = 0;
|
||||
}
|
||||
|
||||
|
@ -944,7 +944,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
|
|||
VFS_PRINTF (f, "%s\n", sv.strings.lightstyles[i]?sv.strings.lightstyles[i]:"");
|
||||
}
|
||||
|
||||
for (i=1 ; i<MAX_MODELS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_MODELS ; i++)
|
||||
{
|
||||
if (sv.strings.model_precache[i] && *sv.strings.model_precache[i])
|
||||
VFS_PRINTF (f, "%s\n", sv.strings.model_precache[i]);
|
||||
|
@ -952,7 +952,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
|
|||
break;
|
||||
}
|
||||
VFS_PRINTF (f,"\n");
|
||||
for (i=1 ; i<MAX_SOUNDS ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_SOUNDS ; i++)
|
||||
{
|
||||
if (*sv.strings.sound_precache[i])
|
||||
VFS_PRINTF (f, "%s\n", sv.strings.sound_precache[i]);
|
||||
|
|
|
@ -134,9 +134,9 @@ typedef struct
|
|||
#endif
|
||||
struct {
|
||||
const char *vw_model_precache[32];
|
||||
const char *model_precache[MAX_MODELS]; // NULL terminated
|
||||
const char *model_precache[MAX_PRECACHE_MODELS]; // NULL terminated
|
||||
char particle_precache[MAX_SSPARTICLESPRE][MAX_QPATH]; // NULL terminated
|
||||
char sound_precache[MAX_SOUNDS][MAX_QPATH]; // NULL terminated
|
||||
char sound_precache[MAX_PRECACHE_SOUNDS][MAX_QPATH]; // NULL terminated
|
||||
const char *lightstyles[MAX_LIGHTSTYLES];
|
||||
vec3_t lightstylecolours[MAX_LIGHTSTYLES];
|
||||
};
|
||||
|
@ -148,7 +148,7 @@ typedef struct
|
|||
int spawned_client_slots; //number of PLAYER slots which are active (ie: putclientinserver was called)
|
||||
int spawned_observer_slots;
|
||||
|
||||
model_t *models[MAX_MODELS];
|
||||
model_t *models[MAX_PRECACHE_MODELS];
|
||||
qbyte *pvs, *phs; // fully expanded and decompressed
|
||||
|
||||
struct client_s *skipbprintclient; //SV_BroadcastPrint skips this client
|
||||
|
@ -949,7 +949,7 @@ extern client_t *host_client;
|
|||
|
||||
extern edict_t *sv_player;
|
||||
|
||||
extern char localmodels[MAX_MODELS][5]; // inline model names for precache
|
||||
//extern char localmodels[MAX_MODELS][5]; // inline model names for precache
|
||||
|
||||
extern char localinfo[MAX_LOCALINFO_STRING+1];
|
||||
|
||||
|
@ -1094,7 +1094,6 @@ trace_t WPhys_Trace_Toss (world_t *w, wedict_t *ent, wedict_t *ignore);
|
|||
void SV_ProgStartFrame (void);
|
||||
void WPhys_RunEntity (world_t *w, wedict_t *ent);
|
||||
qboolean WPhys_RunThink (world_t *w, wedict_t *ent);
|
||||
void WPhys_MoveChain(world_t *w, wedict_t *ent, wedict_t *movechain, float *initial_origin, float *initial_angle); /*here for player movement to do movechains too*/
|
||||
|
||||
//
|
||||
// sv_send.c
|
||||
|
@ -1399,8 +1398,6 @@ void SV_FlushLevelCache(void);
|
|||
|
||||
int SV_RateForClient(client_t *cl);
|
||||
|
||||
qboolean TransformedNativeTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace, vec3_t origin, vec3_t angles);
|
||||
|
||||
void SVVC_Frame (qboolean enabled);
|
||||
void SV_CalcPHS (void);
|
||||
|
||||
|
|
|
@ -392,10 +392,10 @@ static void SV_MapList_f(void)
|
|||
COM_EnumerateFiles("maps/*.hmp", ShowMapList, NULL);
|
||||
}
|
||||
|
||||
static void gtcallback(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
Con_Printf("g_gametype changed\n");
|
||||
}
|
||||
//static void gtcallback(struct cvar_s *var, char *oldvalue)
|
||||
//{
|
||||
// Con_Printf("g_gametype changed\n");
|
||||
//}
|
||||
|
||||
/*
|
||||
======================
|
||||
|
@ -624,7 +624,7 @@ void SV_Map_f (void)
|
|||
Cvar_ForceSet(gametype, level);
|
||||
|
||||
gametype = Cvar_Get("g_gametype", "", CVAR_LATCH|CVAR_SERVERINFO, "Q3 compatability");
|
||||
gametype->callback = gtcallback;
|
||||
// gametype->callback = gtcallback;
|
||||
if (q3singleplayer)
|
||||
Cvar_ForceSet(gametype, "2");//singleplayer
|
||||
else if (gametype->value == 2)
|
||||
|
@ -1731,14 +1731,14 @@ static void SV_Status_f (void)
|
|||
{
|
||||
int count = 0;
|
||||
Con_Printf("entities : %i/%i (mem: %i/%i)\n", sv.world.num_edicts, sv.world.max_edicts, sv.world.progs->stringtablesize, sv.world.progs->stringtablemaxsize);
|
||||
for (count = 1; count < MAX_MODELS; count++)
|
||||
for (count = 1; count < MAX_PRECACHE_MODELS; count++)
|
||||
if (!sv.strings.model_precache[count])
|
||||
break;
|
||||
Con_Printf("models : %i/%i\n", count, MAX_MODELS);
|
||||
for (count = 1; count < MAX_SOUNDS; count++)
|
||||
Con_Printf("models : %i/%i\n", count, MAX_PRECACHE_MODELS);
|
||||
for (count = 1; count < MAX_PRECACHE_SOUNDS; count++)
|
||||
if (!*sv.strings.sound_precache[count])
|
||||
break;
|
||||
Con_Printf("sounds : %i/%i\n", count, MAX_SOUNDS);
|
||||
Con_Printf("sounds : %i/%i\n", count, MAX_PRECACHE_SOUNDS);
|
||||
}
|
||||
Con_Printf("gamedir : %s\n", FS_GetGamedir(true));
|
||||
if (sv.csqcdebug)
|
||||
|
|
|
@ -1238,7 +1238,13 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
|
|||
// Con_Printf("Gen sequence %i\n", sequence);
|
||||
MSG_WriteFloat(msg, sv.world.physicstime);
|
||||
|
||||
for(j = 0; j < client->sentents.num_entities; j++)
|
||||
if (client->pendingentbits[0] & UF_REMOVE)
|
||||
{
|
||||
SV_EmitDeltaEntIndex(msg, 0, true, true);
|
||||
resendbits[outno] = UF_REMOVE;
|
||||
resendnum[outno++] = 0;
|
||||
}
|
||||
for(j = 1; j < client->sentents.num_entities; j++)
|
||||
{
|
||||
bits = client->pendingentbits[j];
|
||||
if (!(bits & ~UF_RESET2)) //skip while there's nothing to send (skip reset2 if there's no other changes, its only to reduce chances of the client getting 'new' entities containing just an origin)*/
|
||||
|
@ -2019,7 +2025,7 @@ qboolean Cull_Traceline(pvscamera_t *cameras, edict_t *seen)
|
|||
for (c = 0; c < cameras->numents; c++)
|
||||
{
|
||||
tr.fraction = 1;
|
||||
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], seen->v->origin, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
|
||||
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], seen->v->origin, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &tr))
|
||||
return false; //wasn't blocked
|
||||
}
|
||||
|
||||
|
@ -2033,7 +2039,7 @@ qboolean Cull_Traceline(pvscamera_t *cameras, edict_t *seen)
|
|||
end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]);
|
||||
|
||||
tr.fraction = 1;
|
||||
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], end, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
|
||||
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], end, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &tr))
|
||||
return false; //this trace went through, so don't cull
|
||||
}
|
||||
}
|
||||
|
@ -2898,7 +2904,7 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
|
|||
else if (ent->v->solid == SOLID_BBOX || ent->v->solid == SOLID_SLIDEBOX || ent->v->skin < 0)
|
||||
{
|
||||
unsigned int mdl = ent->v->modelindex;
|
||||
if (mdl < MAX_MODELS && sv.models[mdl] && sv.models[mdl]->type == mod_brush)
|
||||
if (mdl < MAX_PRECACHE_MODELS && sv.models[mdl] && sv.models[mdl]->type == mod_brush)
|
||||
state->solid = ES_SOLID_BSP;
|
||||
else
|
||||
{
|
||||
|
|
|
@ -31,8 +31,6 @@ server_t sv; // local server
|
|||
entity_state_t *sv_staticentities;
|
||||
int sv_max_staticentities;
|
||||
|
||||
char localmodels[MAX_MODELS][5]; // inline model names for precache
|
||||
|
||||
char localinfo[MAX_LOCALINFO_STRING+1]; // local game info
|
||||
|
||||
extern cvar_t skill, sv_loadentfiles;
|
||||
|
@ -57,12 +55,12 @@ int SV_ModelIndex (const char *name)
|
|||
if (!name || !name[0])
|
||||
return 0;
|
||||
|
||||
for (i=1 ; i<MAX_MODELS && sv.strings.model_precache[i] ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_MODELS && sv.strings.model_precache[i] ; i++)
|
||||
if (!strcmp(sv.strings.model_precache[i], name))
|
||||
return i;
|
||||
if (i==MAX_MODELS || !sv.strings.model_precache[i])
|
||||
if (i==MAX_PRECACHE_MODELS || !sv.strings.model_precache[i])
|
||||
{
|
||||
if (i!=MAX_MODELS)
|
||||
if (i!=MAX_PRECACHE_MODELS)
|
||||
{
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
|
@ -98,10 +96,10 @@ int SV_SafeModelIndex (char *name)
|
|||
if (!name || !name[0])
|
||||
return 0;
|
||||
|
||||
for (i=1 ; i<MAX_MODELS && sv.strings.model_precache[i] ; i++)
|
||||
for (i=1 ; i<MAX_PRECACHE_MODELS && sv.strings.model_precache[i] ; i++)
|
||||
if (!strcmp(sv.strings.model_precache[i], name))
|
||||
return i;
|
||||
if (i==MAX_MODELS || !sv.strings.model_precache[i])
|
||||
if (i==MAX_PRECACHE_MODELS || !sv.strings.model_precache[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -817,7 +815,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
Z_Free(svs.clients[i].spawninfo);
|
||||
svs.clients[i].spawninfo = NULL;
|
||||
}
|
||||
#ifdef HEXEN2
|
||||
T_FreeStrings();
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < svs.allocated_client_slots; i++)
|
||||
|
@ -1093,14 +1093,25 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
{
|
||||
int subs;
|
||||
strcpy(sv.strings.sound_precache[0], "");
|
||||
sv.strings.model_precache[0] = "";
|
||||
|
||||
sv.strings.model_precache[1] = sv.modelname; //the qvm doesn't have access to this array
|
||||
for (i=1 ; i<sv.world.worldmodel->numsubmodels ; i++)
|
||||
subs = sv.world.worldmodel->numsubmodels;
|
||||
if (subs > MAX_PRECACHE_MODELS-2)
|
||||
{
|
||||
sv.strings.model_precache[1+i] = localmodels[i];
|
||||
sv.models[i+1] = Mod_ForName (localmodels[i], MLV_WARN);
|
||||
Con_Printf("Warning: worldmodel has too many submodels\n");
|
||||
subs = MAX_PRECACHE_MODELS-2;
|
||||
}
|
||||
|
||||
sv.strings.model_precache[1] = sv.modelname; //the qvm doesn't have access to this array
|
||||
for (i=1 ; i<subs ; i++)
|
||||
{
|
||||
char *z, *s = va("*%u", i);
|
||||
z = Z_TagMalloc(strlen(s)+1, VMFSID_Q1QVM);
|
||||
strcpy(z, s);
|
||||
sv.strings.model_precache[1+i] = z;
|
||||
sv.models[i+1] = Mod_ForName (z, MLV_WARN);
|
||||
}
|
||||
|
||||
//check player/eyes models for hacks
|
||||
|
@ -1115,14 +1126,22 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
#endif
|
||||
)
|
||||
{
|
||||
int subs;
|
||||
strcpy(sv.strings.sound_precache[0], "");
|
||||
sv.strings.model_precache[0] = "";
|
||||
|
||||
sv.strings.model_precache[1] = PR_AddString(svprogfuncs, sv.modelname, 0, false);
|
||||
for (i=1 ; i<sv.world.worldmodel->numsubmodels ; i++)
|
||||
|
||||
subs = sv.world.worldmodel->numsubmodels;
|
||||
if (subs > MAX_PRECACHE_MODELS-2)
|
||||
{
|
||||
sv.strings.model_precache[1+i] = PR_AddString(svprogfuncs, localmodels[i], 0, false);
|
||||
sv.models[i+1] = Mod_ForName (localmodels[i], MLV_WARN);
|
||||
Con_Printf("Warning: worldmodel has too many submodels\n");
|
||||
subs = MAX_PRECACHE_MODELS-2;
|
||||
}
|
||||
for (i=1 ; i<subs ; i++)
|
||||
{
|
||||
sv.strings.model_precache[1+i] = PR_AddString(svprogfuncs, va("*%u", i), 0, false);
|
||||
sv.models[i+1] = Mod_ForName (sv.strings.model_precache[1+i], MLV_WARN);
|
||||
}
|
||||
|
||||
//check player/eyes models for hacks
|
||||
|
@ -1132,6 +1151,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
#ifdef Q2SERVER
|
||||
else if (svs.gametype == GT_QUAKE2)
|
||||
{
|
||||
int subs;
|
||||
extern int map_checksum;
|
||||
extern cvar_t sv_airaccelerate;
|
||||
|
||||
|
@ -1148,11 +1168,18 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
else
|
||||
strcpy(sv.strings.configstring[Q2CS_MAPCHECKSUM], "0");
|
||||
|
||||
subs = sv.world.worldmodel->numsubmodels;
|
||||
if (subs > Q2MAX_MODELS-2)
|
||||
{
|
||||
Con_Printf("Warning: worldmodel has too many submodels\n");
|
||||
subs = Q2MAX_MODELS-2;
|
||||
}
|
||||
|
||||
strcpy(sv.strings.configstring[Q2CS_MODELS+1], sv.modelname);
|
||||
for (i=1; i<sv.world.worldmodel->numsubmodels; i++)
|
||||
{
|
||||
strcpy(sv.strings.configstring[Q2CS_MODELS+1+i], localmodels[i]);
|
||||
sv.models[i+1] = Mod_ForName (localmodels[i], MLV_WARN);
|
||||
Q_snprintfz(sv.strings.configstring[Q2CS_MODELS+1+i], sizeof(sv.strings.configstring[Q2CS_MODELS+1+i]), "*%u", i);
|
||||
sv.models[i+1] = Mod_ForName (sv.strings.configstring[Q2CS_MODELS+1+i], MLV_WARN);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1480,9 +1507,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
val = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "message", NULL);
|
||||
if (val)
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
if (progstype == PROG_H2)
|
||||
snprintf(sv.mapname, sizeof(sv.mapname), "%s", T_GetString(val->_float-1));
|
||||
else
|
||||
#endif
|
||||
snprintf(sv.mapname, sizeof(sv.mapname), "%s", PR_GetString(svprogfuncs, val->string));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -275,7 +275,9 @@ void SV_Shutdown (void)
|
|||
Z_Free(lp);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
T_FreeStrings();
|
||||
#endif
|
||||
|
||||
SV_GibFilterPurge();
|
||||
|
||||
|
@ -1745,7 +1747,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
|
||||
//you need to reconnect for this to update, of course. so make sure its not *too* low...
|
||||
client->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS);
|
||||
client->maxmodels = MAX_MODELS; //protocol limited to 14 bits.
|
||||
client->maxmodels = MAX_PRECACHE_MODELS; //protocol limited to 14 bits.
|
||||
}
|
||||
else if (ISQWCLIENT(client)) //readd?
|
||||
{
|
||||
|
@ -1757,7 +1759,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
client->max_net_ents += 1024;
|
||||
|
||||
if (client->fteprotocolextensions & PEXT_MODELDBL)
|
||||
client->maxmodels = MAX_MODELS;
|
||||
client->maxmodels = MAX_PRECACHE_MODELS;
|
||||
}
|
||||
else if (ISDPCLIENT(client))
|
||||
{
|
||||
|
@ -4546,9 +4548,6 @@ void SV_InitLocal (void)
|
|||
|
||||
SV_MVDInit();
|
||||
|
||||
for (i=0 ; i<MAX_MODELS ; i++)
|
||||
sprintf (localmodels[i], "*%i", i);
|
||||
|
||||
Info_SetValueForStarKey (svs.info, "*version", version_string(), MAX_SERVERINFO_STRING);
|
||||
|
||||
Info_SetValueForStarKey (svs.info, "*z_ext", va("%i", SUPPORTED_Z_EXTENSIONS), MAX_SERVERINFO_STRING);
|
||||
|
@ -5034,11 +5033,13 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose)
|
|||
else
|
||||
cl->drate = cl->rate; //0 disables the downloading check
|
||||
|
||||
#ifdef HEXEN2
|
||||
val = Info_ValueForKey (cl->userinfo, "cl_playerclass");
|
||||
if (val)
|
||||
{
|
||||
PRH2_SetPlayerClass(cl, atoi(val), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
// msg command
|
||||
val = Info_ValueForKey (cl->userinfo, "msg");
|
||||
|
|
|
@ -1331,7 +1331,7 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
|
|||
if (trace.allsolid)
|
||||
{
|
||||
if (progstype != PROG_H2)
|
||||
trace.fraction = 0;
|
||||
trace.fraction = 0; //traces that start in solid report a fraction of 0. this is to prevent things from dropping out of the world completely. at least this way they ought to still be shootable etc
|
||||
|
||||
#pragma warningmsg("The following line might help boost framerates a lot in rmq, not sure if they violate expected behaviour in other mods though - check that they're safe.")
|
||||
VectorNegate(gravitydir, trace.plane.normal);
|
||||
|
@ -1976,6 +1976,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HEXEN2
|
||||
void WPhys_MoveChain(world_t *w, wedict_t *ent, wedict_t *movechain, float *initial_origin, float *initial_angle)
|
||||
{
|
||||
qboolean callfunc;
|
||||
|
@ -2006,6 +2007,7 @@ void WPhys_MoveChain(world_t *w, wedict_t *ent, wedict_t *movechain, float *init
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -2015,8 +2017,10 @@ SV_RunEntity
|
|||
*/
|
||||
void WPhys_RunEntity (world_t *w, wedict_t *ent)
|
||||
{
|
||||
#ifdef HEXEN2
|
||||
wedict_t *movechain;
|
||||
vec3_t initial_origin = {0},initial_angle = {0}; // warning: ‘initial_?[?]’ may be used uninitialized in this function
|
||||
#endif
|
||||
const float *gravitydir;
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
|
@ -2071,13 +2075,14 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HEXEN2
|
||||
movechain = PROG_TO_WEDICT(w->progs, ent->xv->movechain);
|
||||
if (movechain != w->edicts)
|
||||
{
|
||||
VectorCopy(ent->v->origin,initial_origin);
|
||||
VectorCopy(ent->v->angles,initial_angle);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch ( (int)ent->v->movetype)
|
||||
{
|
||||
|
@ -2140,10 +2145,10 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
if (movechain != w->edicts)
|
||||
{
|
||||
WPhys_MoveChain(w, ent, movechain, initial_origin, initial_angle);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
if (svent)
|
||||
|
|
|
@ -995,15 +995,15 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, const cha
|
|||
return;
|
||||
else
|
||||
{
|
||||
for (sound_num=1 ; sound_num<MAX_SOUNDS
|
||||
for (sound_num=1 ; sound_num<MAX_PRECACHE_SOUNDS
|
||||
&& *sv.strings.sound_precache[sound_num] ; sound_num++)
|
||||
if (!strcmp(sample, sv.strings.sound_precache[sound_num]))
|
||||
break;
|
||||
}
|
||||
|
||||
if ( sound_num == MAX_SOUNDS || !*sv.strings.sound_precache[sound_num] )
|
||||
if ( sound_num == MAX_PRECACHE_SOUNDS || !*sv.strings.sound_precache[sound_num] )
|
||||
{
|
||||
if (sound_num < MAX_SOUNDS)
|
||||
if (sound_num < MAX_PRECACHE_SOUNDS)
|
||||
{
|
||||
Con_Printf("WARNING: SV_StartSound: sound %s not precached\n", sample);
|
||||
//late precache it. use multicast to ensure that its sent NOW (and to all). normal reliables would mean it would arrive after the svc_sound
|
||||
|
@ -1187,7 +1187,7 @@ void SV_FindModelNumbers (void)
|
|||
sv_supernailmodel = -1;
|
||||
sv_playermodel = -1;
|
||||
|
||||
for (i=0 ; i<MAX_MODELS ; i++)
|
||||
for (i=0 ; i<MAX_PRECACHE_MODELS ; i++)
|
||||
{
|
||||
if (!sv.strings.model_precache[i])
|
||||
break;
|
||||
|
@ -1750,7 +1750,7 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf
|
|||
statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
|
||||
if (client->fteprotocolextensions & PEXT_MODELDBL)
|
||||
{
|
||||
if ((unsigned)statsi[STAT_WEAPON] >= MAX_MODELS)
|
||||
if ((unsigned)statsi[STAT_WEAPON] >= MAX_PRECACHE_MODELS)
|
||||
statsi[STAT_WEAPON] = 0;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -983,7 +983,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
|||
int maxclientsupportedsounds = 256;
|
||||
#ifdef PEXT_SOUNDDBL
|
||||
if (client->fteprotocolextensions & PEXT_SOUNDDBL)
|
||||
maxclientsupportedsounds = MAX_SOUNDS;
|
||||
maxclientsupportedsounds = MAX_PRECACHE_SOUNDS;
|
||||
#endif
|
||||
started = false;
|
||||
|
||||
|
@ -5932,6 +5932,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
|||
pmove.physents[0].model = sv.world.worldmodel;
|
||||
pmove.cmd = *ucmd;
|
||||
pmove.hullnum = SV_HullNumForPlayer(0, player_mins, player_maxs);
|
||||
pmove.capsule = (sv_player->xv->geomtype == GEOMTYPE_CAPSULE);
|
||||
|
||||
movevars.entgravity = 0;
|
||||
movevars.maxspeed = 0;
|
||||
|
@ -6125,6 +6126,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
|||
pmove.physents[0].model = sv.world.worldmodel;
|
||||
pmove.cmd = *ucmd;
|
||||
pmove.skipent = -1;
|
||||
pmove.capsule = (sv_player->xv->geomtype == GEOMTYPE_CAPSULE);
|
||||
|
||||
movevars.entgravity = host_client->entgravity/movevars.gravity;
|
||||
movevars.maxspeed = host_client->maxspeed;
|
||||
|
|
|
@ -1655,6 +1655,7 @@ extern cvar_t temp1;
|
|||
pmove.physents[0].info = 0;
|
||||
pmove.skipent = -1;
|
||||
pmove.onladder = false;
|
||||
pmove.capsule = false;
|
||||
|
||||
if (ed->v.flags & (1<<24))
|
||||
{
|
||||
|
|
|
@ -707,7 +707,7 @@ static int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list, in
|
|||
|
||||
static model_t *SVQ2_GetCModel(world_t *w, int modelindex)
|
||||
{
|
||||
if ((unsigned int)modelindex < MAX_MODELS)
|
||||
if ((unsigned int)modelindex < MAX_PRECACHE_MODELS)
|
||||
return sv.models[modelindex];
|
||||
else
|
||||
return NULL;
|
||||
|
|
|
@ -156,7 +156,7 @@ static void Q3G_UnlinkEntity(q3sharedEntity_t *ent)
|
|||
|
||||
static model_t *Q3G_GetCModel(unsigned int modelindex)
|
||||
{
|
||||
if ((unsigned int)modelindex < MAX_MODELS)
|
||||
if ((unsigned int)modelindex < MAX_PRECACHE_MODELS)
|
||||
{
|
||||
if (!sv.models[modelindex])
|
||||
{
|
||||
|
@ -416,7 +416,7 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs
|
|||
if (!maxs)
|
||||
maxs = vec3_origin;
|
||||
|
||||
sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, NULL, start, end, mins, maxs, contentmask, &tr);
|
||||
sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, NULL, start, end, mins, maxs, capsule, contentmask, &tr);
|
||||
result->allsolid = tr.allsolid;
|
||||
result->contents = tr.contents;
|
||||
VectorCopy(tr.endpos, result->endpos);
|
||||
|
@ -476,7 +476,6 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs
|
|||
|
||||
if (es->r.bmodel)
|
||||
{
|
||||
//FIXME, this is inefficient.
|
||||
mod = Q3G_GetCModel(es->s.modelindex);
|
||||
if (!mod)
|
||||
continue;
|
||||
|
@ -484,9 +483,11 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs
|
|||
}
|
||||
else
|
||||
{
|
||||
if (es->r.svFlags & SVF_CAPSULE)
|
||||
mod = CM_TempBoxModel(es->r.mins, es->r.maxs);
|
||||
else
|
||||
mod = CM_TempBoxModel(es->r.mins, es->r.maxs);
|
||||
tr = CM_TransformedBoxTrace(mod, start, end, mins, maxs, contentmask, es->r.currentOrigin, es->r.currentAngles);
|
||||
// mod->funcs.Trace(mod, 0, 0, start, end, mins, maxs, &tr);
|
||||
}
|
||||
if (tr.fraction < result->fraction)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef struct
|
|||
q2edict_t *q2passedict;
|
||||
#endif
|
||||
int hullnum;
|
||||
qboolean capsule;
|
||||
} moveclip_t;
|
||||
|
||||
/*
|
||||
|
@ -119,6 +120,26 @@ hull_t *World_HullForBox (vec3_t mins, vec3_t maxs)
|
|||
return &box_hull;
|
||||
}
|
||||
|
||||
model_t mod_capsule;
|
||||
qboolean World_BoxTrace(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace)
|
||||
{
|
||||
//bbox vs bbox (NYI)
|
||||
//capsule vs bbox (NYI)
|
||||
return false;
|
||||
}
|
||||
qboolean World_CapsuleTrace(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
|
||||
{
|
||||
//bbox vs capsule (NYI)
|
||||
//capsule vs capsule (NYI)
|
||||
return false;
|
||||
}
|
||||
model_t *World_CapsuleForBox(vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
VectorCopy(mins, mod_capsule.mins);
|
||||
VectorCopy(maxs, mod_capsule.maxs);
|
||||
mod_capsule.funcs.NativeTrace = World_CapsuleTrace;
|
||||
return &mod_capsule;
|
||||
}
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -910,7 +931,7 @@ qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
|||
|
||||
//wrapper function. Rotates the start and end positions around the angles if needed.
|
||||
//qboolean TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *trace, vec3_t angles)
|
||||
qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace, vec3_t origin, vec3_t angles, unsigned int hitcontentsmask)
|
||||
qboolean World_TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, struct trace_s *trace, vec3_t origin, vec3_t angles, unsigned int hitcontentsmask)
|
||||
{
|
||||
vec3_t start_l, end_l;
|
||||
vec3_t axis[3];
|
||||
|
@ -929,71 +950,23 @@ qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, v
|
|||
return false;
|
||||
}
|
||||
|
||||
// don't rotate non bsp ents. Too small to bother.
|
||||
if (model && !model->needload)
|
||||
{
|
||||
VectorSubtract (start, origin, start_l);
|
||||
VectorSubtract (end, origin, end_l);
|
||||
|
||||
if (angles[0] || angles[1] || angles[2])
|
||||
{
|
||||
AngleVectors (angles, axis[0], axis[1], axis[2]);
|
||||
VectorNegate(axis[1], axis[1]);
|
||||
result = model->funcs.NativeTrace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, hitcontentsmask, trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = model->funcs.NativeTrace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, hitcontentsmask, trace);
|
||||
}
|
||||
|
||||
VectorAdd (trace->endpos, origin, trace->endpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
hull_t *hull = &box_hull;
|
||||
|
||||
memset (trace, 0, sizeof(trace_t));
|
||||
trace->fraction = 1;
|
||||
trace->allsolid = true;
|
||||
|
||||
VectorSubtract (start, origin, start_l);
|
||||
VectorSubtract (end, origin, end_l);
|
||||
VectorCopy (end_l, trace->endpos);
|
||||
result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
|
||||
VectorAdd (trace->endpos, origin, trace->endpos);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
qboolean TransformedNativeTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace, vec3_t origin, vec3_t angles)
|
||||
{
|
||||
vec3_t start_l, end_l;
|
||||
vec3_t axis[3];
|
||||
qboolean result;
|
||||
|
||||
memset (trace, 0, sizeof(trace_t));
|
||||
trace->fraction = 1;
|
||||
trace->allsolid = false;
|
||||
trace->startsolid = false;
|
||||
trace->inopen = true; //probably wrong...
|
||||
VectorCopy (end, trace->endpos);
|
||||
|
||||
// don't rotate non bsp ents. Too small to bother.
|
||||
if (model)
|
||||
{
|
||||
VectorSubtract (start, origin, start_l);
|
||||
VectorSubtract (end, origin, end_l);
|
||||
|
||||
if (angles[0] || angles[1] || angles[2])
|
||||
{
|
||||
AngleVectors (angles, axis[0], axis[1], axis[2]);
|
||||
VectorNegate(axis[1], axis[1]);
|
||||
result = model->funcs.NativeTrace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, against, trace);
|
||||
result = model->funcs.NativeTrace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, capsule, hitcontentsmask, trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = model->funcs.NativeTrace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, against, trace);
|
||||
result = model->funcs.NativeTrace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, capsule, hitcontentsmask, trace);
|
||||
}
|
||||
|
||||
VectorAdd (trace->endpos, origin, trace->endpos);
|
||||
}
|
||||
else
|
||||
|
@ -1022,7 +995,7 @@ Handles selection or creation of a clipping hull, and offseting (and
|
|||
eventually rotation) of the end points
|
||||
==================
|
||||
*/
|
||||
static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel, unsigned int hitcontentsmask) //hullnum overrides min/max for q1 style bsps
|
||||
static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel, qboolean capsule, unsigned int hitcontentsmask) //hullnum overrides min/max for q1 style bsps
|
||||
{
|
||||
trace_t trace;
|
||||
model_t *model;
|
||||
|
@ -1041,11 +1014,15 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
|
|||
else
|
||||
model = NULL;
|
||||
|
||||
if (!model)
|
||||
if (!model || model->needload)
|
||||
{
|
||||
vec3_t boxmins, boxmaxs;
|
||||
model = NULL;
|
||||
VectorSubtract (ent->v->mins, maxs, boxmins);
|
||||
VectorSubtract (ent->v->maxs, mins, boxmaxs);
|
||||
if (ent->xv->geomtype == GEOMTYPE_CAPSULE && !hitmodel)
|
||||
model = World_CapsuleForBox(boxmins, boxmaxs);
|
||||
else
|
||||
World_HullForBox(boxmins, boxmaxs);
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1030,7 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
|
|||
if (ent->v->solid == SOLID_PORTAL)
|
||||
{
|
||||
//solid_portal cares only about origins and as such has no mins/max
|
||||
TransformedTrace(model, 0, ent->v->frame, start, end, vec3_origin, vec3_origin, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
World_TransformedTrace(model, 0, ent->v->frame, start, end, vec3_origin, vec3_origin, capsule, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
if (trace.startsolid) //portals should not block traces. this prevents infinite looping
|
||||
trace.startsolid = false;
|
||||
hitmodel = false;
|
||||
|
@ -1061,24 +1038,24 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
|
|||
else if (ent->v->solid != SOLID_BSP)
|
||||
{
|
||||
ent->v->angles[0]*=-1; //carmack made bsp models rotate wrongly.
|
||||
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
World_TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, capsule, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
ent->v->angles[0]*=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
World_TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, capsule, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
}
|
||||
|
||||
// if using hitmodel, we know it hit the bounding box, so try a proper trace now.
|
||||
if (hitmodel && trace.fraction != 1 && ent->v->solid != SOLID_BSP && mdlidx != 0)
|
||||
if (hitmodel && trace.fraction != 1 && !model)
|
||||
{
|
||||
//okay, we hit the bbox
|
||||
model = w->Get_CModel(w, mdlidx);
|
||||
|
||||
if (model && model->funcs.NativeTrace)
|
||||
if (model && model->funcs.NativeTrace && !model->needload)
|
||||
{
|
||||
//do the second trace
|
||||
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
//do the second trace, using the actual mesh.
|
||||
World_TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, capsule, &trace, eorg, ent->v->angles, hitcontentsmask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1092,16 +1069,13 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
|
|||
static trace_t WorldQ2_ClipMoveToEntity (world_t *w, q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, unsigned int hitcontentsmask)
|
||||
{
|
||||
trace_t trace;
|
||||
model_t *model;
|
||||
model_t *model = NULL;
|
||||
|
||||
// get the clipping hull
|
||||
if (ent->s.solid == Q2SOLID_BSP)
|
||||
{
|
||||
model = w->Get_CModel(w, ent->s.modelindex);
|
||||
if (!model || model->type != mod_brush)
|
||||
SV_Error("SOLID_BSP with non bsp model");
|
||||
}
|
||||
else
|
||||
|
||||
if (!model || model->type != mod_brush || model->needload)
|
||||
{
|
||||
vec3_t boxmins, boxmaxs;
|
||||
VectorSubtract (ent->mins, maxs, boxmins);
|
||||
|
@ -1111,7 +1085,7 @@ static trace_t WorldQ2_ClipMoveToEntity (world_t *w, q2edict_t *ent, vec3_t star
|
|||
}
|
||||
|
||||
// trace a line through the apropriate clipping hull
|
||||
TransformedTrace(model, 0, 0, start, end, mins, maxs, &trace, ent->s.origin, ent->s.angles, hitcontentsmask);
|
||||
World_TransformedTrace(model, 0, 0, start, end, mins, maxs, false, &trace, ent->s.origin, ent->s.angles, hitcontentsmask);
|
||||
|
||||
// did we clip the move?
|
||||
if (trace.fraction < 1 || trace.startsolid )
|
||||
|
@ -1541,9 +1515,9 @@ static void World_ClipToEverything (world_t *w, moveclip_t *clip)
|
|||
}
|
||||
|
||||
if ((int)touch->v->flags & FL_MONSTER)
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->capsule, clip->hitcontentsmask);
|
||||
else
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->capsule, clip->hitcontentsmask);
|
||||
if (trace.allsolid || trace.startsolid ||
|
||||
trace.fraction < clip->trace.fraction)
|
||||
{
|
||||
|
@ -1648,9 +1622,9 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip)
|
|||
}
|
||||
|
||||
if ((int)touch->v->flags & FL_MONSTER)
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->capsule, clip->hitcontentsmask);
|
||||
else
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
|
||||
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->capsule, clip->hitcontentsmask);
|
||||
|
||||
if (trace.fraction < clip->trace.fraction)
|
||||
{
|
||||
|
@ -1841,16 +1815,17 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
|
|||
clip.hitcontentsmask = MASK_BOXSOLID; /*impacts playerclip*/
|
||||
else
|
||||
clip.hitcontentsmask = MASK_POINTSOLID; /*ignores playerclip but hits everything else*/
|
||||
clip.capsule = (passedict->xv->geomtype == GEOMTYPE_CAPSULE);
|
||||
|
||||
if (type & MOVE_ONLYENT)
|
||||
{
|
||||
if (!passedict)
|
||||
passedict = w->edicts;
|
||||
return World_ClipMoveToEntity (w, passedict, passedict->v->origin, start, mins, maxs, end, hullnum, clip.type & MOVE_HITMODEL, clip.hitcontentsmask);
|
||||
return World_ClipMoveToEntity (w, passedict, passedict->v->origin, start, mins, maxs, end, hullnum, type & MOVE_HITMODEL, clip.capsule, clip.hitcontentsmask);
|
||||
}
|
||||
|
||||
// clip to world
|
||||
clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false, clip.hitcontentsmask);
|
||||
clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false, clip.capsule, clip.hitcontentsmask);
|
||||
|
||||
clip.start = start;
|
||||
clip.end = end;
|
||||
|
@ -1973,7 +1948,7 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
|
|||
continue; // don't clip against owner
|
||||
}
|
||||
|
||||
trace = World_ClipMoveToEntity (w, touch, lp, clip.start, clip.mins, clip.maxs, clip.end, clip.hullnum, clip.type & MOVE_HITMODEL, clip.hitcontentsmask);
|
||||
trace = World_ClipMoveToEntity (w, touch, lp, clip.start, clip.mins, clip.maxs, clip.end, clip.hullnum, clip.type & MOVE_HITMODEL, clip.capsule, clip.hitcontentsmask);
|
||||
|
||||
if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction)
|
||||
{
|
||||
|
@ -2011,7 +1986,7 @@ trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t
|
|||
memset ( &clip, 0, sizeof ( moveclip_t ) );
|
||||
|
||||
// clip to world
|
||||
w->worldmodel->funcs.NativeTrace(w->worldmodel, 0, 0, NULL, start, end, mins, maxs, hitcontentsmask, &clip.trace);
|
||||
w->worldmodel->funcs.NativeTrace(w->worldmodel, 0, 0, NULL, start, end, mins, maxs, false, hitcontentsmask, &clip.trace);
|
||||
clip.trace.ent = ge->edicts;
|
||||
|
||||
if (clip.trace.fraction == 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue