cmake now builds botlib (as a shared object)
fix q3 looping sounds fix q3sv bug that was kicking clients on map changes attempt to resize q3ui if the window changes size added some more disconnect reasons (for menuqc/q3ui to report). reworked particle count/step arguments for better compat with DP. particles that used count for trails were already broken... drawtextfield builtin will report line numbers shown, so qc can finally tell how much text there actually was added some more items to 'fps_preset dp', stuff needed for the 'quake15' mod. added dpcompat_noretouchground cvar for people wanting to mimic dp's bugs. added 'r_netgraph 2' setting, which will show packet sizes per svc, in part to highlight wasteful mods. added cvar to disable the q1mdl floodfill, which caused problems for yet another person. internal editor now attempts to support debugging asm, if no source is available. fix 64bit icon bug in x11. FINALLY fix high's te_teleport effect. load with no arguments will scan for the most recent a#/s#/quick savedgame instead of using just quick. load command will chose between fte and vanilla savedgame formats based on modification time, if both exist in the same package/dir. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5394 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c87535ecef
commit
cd97d1fff3
49 changed files with 892 additions and 270 deletions
|
@ -648,6 +648,41 @@ SET(FTE_CLIENT_FILES
|
|||
engine/vk/vk_init.c
|
||||
)
|
||||
|
||||
ADD_LIBRARY(fteq3bot MODULE
|
||||
engine/botlib/be_aas_bspq3.c
|
||||
engine/botlib/be_aas_entity.c
|
||||
engine/botlib/be_aas_move.c
|
||||
engine/botlib/be_aas_routealt.c
|
||||
engine/botlib/be_ai_char.c
|
||||
engine/botlib/be_ai_goal.c
|
||||
engine/botlib/be_ai_weight.c
|
||||
engine/botlib/l_crc.c
|
||||
engine/botlib/l_memory.c
|
||||
engine/botlib/l_struct.c
|
||||
engine/botlib/be_aas_cluster.c
|
||||
engine/botlib/be_aas_file.c
|
||||
engine/botlib/be_aas_optimize.c
|
||||
engine/botlib/be_aas_route.c
|
||||
engine/botlib/be_ai_chat.c
|
||||
engine/botlib/be_ai_move.c
|
||||
engine/botlib/be_ea.c
|
||||
engine/botlib/l_libvar.c
|
||||
engine/botlib/l_precomp.c
|
||||
engine/botlib/be_aas_debug.c
|
||||
engine/botlib/be_aas_main.c
|
||||
engine/botlib/be_aas_reach.c
|
||||
engine/botlib/be_aas_sample.c
|
||||
engine/botlib/be_ai_gen.c
|
||||
engine/botlib/be_ai_weap.c
|
||||
engine/botlib/be_interface.c
|
||||
engine/botlib/l_log.c
|
||||
engine/botlib/l_script.c
|
||||
engine/botlib/standalone.c
|
||||
)
|
||||
SET_TARGET_PROPERTIES(fteq3bot PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON};BOTLIB;EXTERNALBOTLIB")
|
||||
TARGET_LINK_LIBRARIES(fteq3bot ${FTE_LIBS} )
|
||||
SET_TARGET_PROPERTIES(fteq3bot PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
|
||||
|
||||
FILE(STRINGS "${FTE_BUILD_CONFIG}" BULLET_INTERNAL REGEX "^#define[\t ]+USE_INTERNAL_BULLET")
|
||||
IF(BULLET_INTERNAL)
|
||||
#Built-in bullet physics plugin...
|
||||
|
|
|
@ -868,6 +868,13 @@ static void Init_AI_Export( ai_export_t *ai ) {
|
|||
GetBotLibAPI
|
||||
============
|
||||
*/
|
||||
#ifdef EXTERNALBOTLIB
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#else
|
||||
__attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif
|
||||
botlib_export_t *QDECL GetBotLibAPI(int apiVersion, botlib_import_t *import) {
|
||||
assert(import);
|
||||
botimport = *import;
|
||||
|
|
|
@ -203,6 +203,8 @@ typedef struct botlib_import_s
|
|||
//
|
||||
int (*DebugPolygonCreate)(int color, int numPoints, vec3_t *points);
|
||||
void (*DebugPolygonDelete)(int id);
|
||||
|
||||
void (*Error)(const char *msg); //for unrecoverable errors only. Will quit out.
|
||||
} botlib_import_t;
|
||||
|
||||
typedef struct aas_export_s
|
||||
|
|
|
@ -277,7 +277,7 @@ token_t *PC_CopyToken(token_t *token)
|
|||
#ifdef BSPC
|
||||
Error("out of token space\n");
|
||||
#else
|
||||
Com_Error(ERR_FATAL, "out of token space");
|
||||
botimport.Error("out of token space");
|
||||
#endif
|
||||
return NULL;
|
||||
} //end if
|
||||
|
@ -561,7 +561,7 @@ void PC_PrintDefineHashTable(define_t **definehash)
|
|||
|
||||
int PC_NameHash(char *name)
|
||||
{
|
||||
int register hash, i;
|
||||
register int hash, i;
|
||||
|
||||
hash = 0;
|
||||
for (i = 0; name[i] != '\0'; i++)
|
||||
|
|
198
engine/botlib/standalone.c
Normal file
198
engine/botlib/standalone.c
Normal file
|
@ -0,0 +1,198 @@
|
|||
//license GPLv2+
|
||||
//this file allows botlib to link as a dynamic lib with no external dependancies
|
||||
|
||||
#include "q_shared.h"
|
||||
#include "botlib.h"
|
||||
|
||||
vec3_t vec3_origin;
|
||||
void QDECL AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
||||
{
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
if (forward)
|
||||
{
|
||||
forward[0] = cp*cy;
|
||||
forward[1] = cp*sy;
|
||||
forward[2] = -sp;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
|
||||
right[1] = (-1*sr*sp*sy+-1*cr*cy);
|
||||
right[2] = -1*sr*cp;
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = (cr*sp*cy+-sr*-sy);
|
||||
up[1] = (cr*sp*sy+-sr*cy);
|
||||
up[2] = cr*cp;
|
||||
}
|
||||
}
|
||||
void QDECL VectorAngles(float *forward, float *up, float *result, qboolean meshpitch)
|
||||
{
|
||||
float yaw, pitch, roll;
|
||||
|
||||
if (forward[1] == 0 && forward[0] == 0)
|
||||
{
|
||||
if (forward[2] > 0)
|
||||
{
|
||||
pitch = -M_PI * 0.5;
|
||||
yaw = up ? atan2(-up[1], -up[0]) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = M_PI * 0.5;
|
||||
yaw = up ? atan2(up[1], up[0]) : 0;
|
||||
}
|
||||
roll = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = atan2(forward[1], forward[0]);
|
||||
pitch = -atan2(forward[2], sqrt (forward[0]*forward[0] + forward[1]*forward[1]));
|
||||
|
||||
if (up)
|
||||
{
|
||||
vec_t cp = cos(pitch), sp = sin(pitch);
|
||||
vec_t cy = cos(yaw), sy = sin(yaw);
|
||||
vec3_t tleft, tup;
|
||||
tleft[0] = -sy;
|
||||
tleft[1] = cy;
|
||||
tleft[2] = 0;
|
||||
tup[0] = sp*cy;
|
||||
tup[1] = sp*sy;
|
||||
tup[2] = cp;
|
||||
roll = -atan2(DotProduct(up, tleft), DotProduct(up, tup));
|
||||
}
|
||||
else
|
||||
roll = 0;
|
||||
}
|
||||
|
||||
pitch *= 180 / M_PI;
|
||||
yaw *= 180 / M_PI;
|
||||
roll *= 180 / M_PI;
|
||||
// if (meshpitch)
|
||||
// pitch *= r_meshpitch.value;
|
||||
if (pitch < 0)
|
||||
pitch += 360;
|
||||
if (yaw < 0)
|
||||
yaw += 360;
|
||||
if (roll < 0)
|
||||
roll += 360;
|
||||
|
||||
result[0] = pitch;
|
||||
result[1] = yaw;
|
||||
result[2] = roll;
|
||||
}
|
||||
|
||||
vec_t QDECL VectorNormalize2 (const vec3_t v, vec3_t out)
|
||||
{
|
||||
float length, ilength;
|
||||
|
||||
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||
length = sqrt (length);
|
||||
if (length)
|
||||
{
|
||||
ilength = 1/length;
|
||||
out[0] = v[0]*ilength;
|
||||
out[1] = v[1]*ilength;
|
||||
out[2] = v[2]*ilength;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorClear (out);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
float QDECL VectorNormalize (vec3_t v)
|
||||
{
|
||||
return VectorNormalize2(v,v);
|
||||
}
|
||||
|
||||
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr, fmt);
|
||||
vsnprintf (dest, size, fmt, argptr);
|
||||
va_end (argptr);
|
||||
}
|
||||
|
||||
int Q_strncasecmp (const char *s1, const char *s2, int n)
|
||||
{
|
||||
int c1, c2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
c1 = *s1++;
|
||||
c2 = *s2++;
|
||||
|
||||
if (!n--)
|
||||
return 0; // strings are equal until end point
|
||||
|
||||
if (c1 != c2)
|
||||
{
|
||||
if (c1 >= 'a' && c1 <= 'z')
|
||||
c1 -= ('a' - 'A');
|
||||
if (c2 >= 'a' && c2 <= 'z')
|
||||
c2 -= ('a' - 'A');
|
||||
if (c1 != c2)
|
||||
{ // strings not equal
|
||||
if (c1 > c2)
|
||||
return 1; // strings not equal
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!c1)
|
||||
return 0; // strings are equal
|
||||
// s1++;
|
||||
// s2++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
int QDECL Q_stricmp (const char *s1, const char *s2)
|
||||
{
|
||||
return Q_strncasecmp (s1, s2, 0x7fffffff);
|
||||
}
|
||||
|
||||
void QDECL Q_strncpyz(char *d, const char *s, int n)
|
||||
{
|
||||
int i;
|
||||
n--;
|
||||
if (n < 0)
|
||||
return; //this could be an error
|
||||
|
||||
for (i=0; *s; i++)
|
||||
{
|
||||
if (i == n)
|
||||
break;
|
||||
*d++ = *s++;
|
||||
}
|
||||
*d='\0';
|
||||
}
|
||||
|
||||
char *QDECL va(char *format, ...)
|
||||
{
|
||||
#define VA_BUFFER_SIZE 1024
|
||||
va_list argptr;
|
||||
static char string[VA_BUFFER_SIZE];
|
||||
|
||||
va_start (argptr, format);
|
||||
vsnprintf (string,sizeof(string)-1, format,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
return string;
|
||||
}
|
|
@ -476,6 +476,99 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti
|
|||
return ctx.numfrags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//called by the sound code.
|
||||
static struct
|
||||
{
|
||||
unsigned int entnum;
|
||||
vec3_t origin;
|
||||
// vec3_t velocity;
|
||||
sfx_t *sfx;
|
||||
qboolean ispersistent;
|
||||
} *loopers;
|
||||
static size_t numloopers;
|
||||
static size_t maxloopers;
|
||||
unsigned int CG_GatherLoopingSounds(vec3_t *positions, unsigned int *entnums, sfx_t **sounds, unsigned int max)
|
||||
{
|
||||
size_t i;
|
||||
if (max > numloopers)
|
||||
max = numloopers;
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
entnums[i] = loopers[i].entnum;
|
||||
VectorCopy(loopers[i].origin, positions[i]);
|
||||
sounds[i] = loopers[i].sfx;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static void CG_StopLoopingSounds(unsigned int entnum)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < numloopers; i++)
|
||||
{
|
||||
if (loopers[i].entnum == entnum)
|
||||
break;
|
||||
}
|
||||
if (i == numloopers)
|
||||
return;
|
||||
loopers[i] = loopers[numloopers-1];
|
||||
numloopers--;
|
||||
}
|
||||
static void CG_StartLoopingSounds(unsigned int entnum, float *origin, float *velocity, const char *soundname, qboolean persistent)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < numloopers; i++)
|
||||
{
|
||||
if (loopers[i].entnum == entnum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == numloopers)
|
||||
{
|
||||
if (numloopers == maxloopers)
|
||||
Z_ReallocElements((void**)&loopers, &maxloopers, maxloopers+1, sizeof(*loopers));
|
||||
numloopers++;
|
||||
}
|
||||
loopers[i].entnum = entnum;
|
||||
VectorCopy(origin, loopers[i].origin);
|
||||
//VectorCopy(velocity, loopers[i].velocity);
|
||||
loopers[i].sfx = S_PrecacheSound(soundname);
|
||||
loopers[i].ispersistent = persistent;
|
||||
}
|
||||
static void CG_MoveLoopingSound(unsigned int entnum, float *origin)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < numloopers; i++)
|
||||
{
|
||||
if (loopers[i].entnum == entnum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == numloopers)
|
||||
return;
|
||||
VectorCopy(origin, loopers[i].origin);
|
||||
}
|
||||
static void CG_ClearLoopingSounds(qboolean clearall)
|
||||
{
|
||||
if (clearall)
|
||||
numloopers = 0;
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < numloopers; )
|
||||
{
|
||||
if (!loopers[i].ispersistent)
|
||||
{
|
||||
loopers[i] = loopers[numloopers-1];
|
||||
numloopers--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname);
|
||||
|
||||
#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to cgame trap %u passes invalid pointer\n", (unsigned int)fn); //out of bounds.
|
||||
|
@ -923,15 +1016,23 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
|
||||
case CG_S_ADDLOOPINGSOUND:
|
||||
//entnum, origin, velocity, sfx
|
||||
// Con_DPrintf("CG_S_ADDLOOPINGSOUND: not implemented\n");
|
||||
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_FROMSTRCACHE(arg[3]), false);
|
||||
break;
|
||||
case CG_S_ADDREALLOOPINGSOUND:
|
||||
//entnum, origin, velocity, sfx
|
||||
// Con_DPrintf("CG_S_ADDREALLOOPINGSOUND: not implemented\n");
|
||||
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_FROMSTRCACHE(arg[3]), true);
|
||||
break;
|
||||
case CG_S_STOPLOOPINGSOUND:
|
||||
//entnum
|
||||
// Con_DPrintf("CG_S_STOPLOOPINGSOUND: not implemented\n");
|
||||
CG_StopLoopingSounds(VM_LONG(arg[0])+1);
|
||||
break;
|
||||
case CG_S_CLEARLOOPINGSOUNDS:
|
||||
//clearall
|
||||
CG_ClearLoopingSounds(VM_LONG(arg[0]));
|
||||
break;
|
||||
case CG_S_UPDATEENTITYPOSITION://void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin );
|
||||
//entnum, org
|
||||
CG_MoveLoopingSound(VM_LONG(arg[0])+1, VM_POINTER(arg[1]));
|
||||
break;
|
||||
|
||||
case CG_S_STARTBACKGROUNDTRACK:
|
||||
|
@ -940,23 +1041,16 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
case CG_S_STOPBACKGROUNDTRACK:
|
||||
Media_NamedTrack(NULL, NULL);
|
||||
return 0;
|
||||
case CG_S_CLEARLOOPINGSOUNDS:
|
||||
//clearall
|
||||
Con_DPrintf("CG_S_CLEARLOOPINGSOUNDS: not implemented\n");
|
||||
break;
|
||||
|
||||
case CG_S_UPDATEENTITYPOSITION://void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin );
|
||||
//entnum, org
|
||||
// Con_DPrintf("CG_S_UPDATEENTITYPOSITION: not implemented\n");
|
||||
break;
|
||||
case CG_S_RESPATIALIZE://void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater );
|
||||
{
|
||||
int entnum = VM_LONG(arg[0])+1;
|
||||
float *org = VM_POINTER(arg[1]);
|
||||
vec3_t *axis = VM_POINTER(arg[2]);
|
||||
int inwater = VM_LONG(arg[3]);
|
||||
|
||||
cl.playerview[0].audio.defaulted = false;
|
||||
cl.playerview[0].audio.entnum = VM_LONG(arg[0])+1;
|
||||
cl.playerview[0].audio.entnum = entnum;
|
||||
VectorCopy(org, cl.playerview[0].audio.origin);
|
||||
VectorCopy(axis[0], cl.playerview[0].audio.forward);
|
||||
VectorCopy(axis[1], cl.playerview[0].audio.right);
|
||||
|
@ -1142,7 +1236,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
case CG_FTE_SPAWNPARTICLEEFFECT:
|
||||
return pe->RunParticleEffectState(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]), VM_LONG(arg[3]), VM_POINTER(arg[4]));
|
||||
case CG_FTE_SPAWNPARTICLETRAIL:
|
||||
return pe->ParticleTrail(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0, NULL, VM_POINTER(arg[3]));
|
||||
return pe->ParticleTrail(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0, 1, NULL, VM_POINTER(arg[3]));
|
||||
case CG_FTE_FREEPARTICLESTATE:
|
||||
pe->DelinkTrailstate(VM_POINTER(arg[0]));
|
||||
break;
|
||||
|
|
|
@ -3894,6 +3894,7 @@ void CL_LinkPacketEntities (void)
|
|||
int trailef, trailidx;
|
||||
int modelflags;
|
||||
struct itemtimer_s *timer, **timerlink;
|
||||
float timestep = host_frametime;
|
||||
|
||||
pack = cl.currentpackentities;
|
||||
if (!pack)
|
||||
|
@ -4023,7 +4024,7 @@ void CL_LinkPacketEntities (void)
|
|||
CL_NewDlight(state->number, ent->origin, radius, 0.1, colour[0], colour[1], colour[2]);
|
||||
}
|
||||
}
|
||||
if (state->lightpflags & (PFLAGS_FULLDYNAMIC|PFLAGS_CORONA))
|
||||
if ((state->lightpflags & (PFLAGS_FULLDYNAMIC|PFLAGS_CORONA)) && ((state->lightpflags&PFLAGS_FULLDYNAMIC)||state->light[3]))
|
||||
{
|
||||
vec3_t colour;
|
||||
if (!state->light[0] && !state->light[1] && !state->light[2])
|
||||
|
@ -4380,9 +4381,9 @@ void CL_LinkPacketEntities (void)
|
|||
//and emit it
|
||||
// if (lasttime != cl.currentpacktime)
|
||||
{
|
||||
if (trailef == P_INVALID || pe->ParticleTrail (old_origin, ent->origin, trailef, ent->keynum, ent->axis, &(le->trailstate)))
|
||||
if (trailef == P_INVALID || pe->ParticleTrail (old_origin, ent->origin, trailef, timestep, ent->keynum, ent->axis, &(le->trailstate)))
|
||||
if (model->traildefaultindex >= 0)
|
||||
pe->ParticleTrailIndex(old_origin, ent->origin, P_INVALID, trailidx, 0, &(le->trailstate));
|
||||
pe->ParticleTrailIndex(old_origin, ent->origin, P_INVALID, timestep, trailidx, 0, &(le->trailstate));
|
||||
|
||||
//dlights are not so customisable.
|
||||
if (r_rocketlight.value && (modelflags & MF_ROCKET) && !(state->lightpflags & (PFLAGS_FULLDYNAMIC|PFLAGS_CORONA)))
|
||||
|
|
|
@ -55,7 +55,7 @@ cvar_t cl_timeout = CVAR("cl_timeout", "60");
|
|||
|
||||
cvar_t cl_shownet = CVARD("cl_shownet","0", "Debugging var. 0 shows nothing. 1 shows incoming packet sizes. 2 shows individual messages. 3 shows entities too."); // can be 0, 1, or 2
|
||||
|
||||
cvar_t cl_disconnectreason = CVARFD("_cl_disconnectreason", "", CVAR_NOSAVE, "This cvar contains the reason for the last disconnection, so that mod menus can know why things failed.");
|
||||
cvar_t cl_disconnectreason = CVARAFD("_cl_disconnectreason", "", "com_errorMessage", CVAR_NOSAVE, "This cvar contains the reason for the last disconnection, so that mod menus can know why things failed.");
|
||||
|
||||
cvar_t cl_pure = CVARD("cl_pure", "0", "0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 is only reliable with total conversions.\nIf sv_pure is set, the client will prefer the highest value set.");
|
||||
cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback);
|
||||
|
@ -1046,6 +1046,7 @@ void CL_CheckForResend (void)
|
|||
|
||||
if (!NET_StringToAdr (host, connectinfo.defaultport, &connectinfo.adr))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("Bad server address \"%s\"", host));
|
||||
Con_TPrintf ("Bad server address \"%s\"\n", host);
|
||||
connectinfo.trying = false;
|
||||
SCR_EndLoadingPlaque();
|
||||
|
@ -1072,6 +1073,7 @@ void CL_CheckForResend (void)
|
|||
}
|
||||
if (!NET_IsClientLegal(&connectinfo.adr))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("Illegal server address"));
|
||||
Con_TPrintf ("Illegal server address\n");
|
||||
SCR_EndLoadingPlaque();
|
||||
connectinfo.trying = false;
|
||||
|
@ -1101,6 +1103,7 @@ void CL_CheckForResend (void)
|
|||
if (connectinfo.tries == 0)
|
||||
if (!NET_EnsureRoute(cls.sockets, "conn", cls.servername, &connectinfo.adr))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("Unable to establish connection to %s\n", cls.servername));
|
||||
Con_Printf ("Unable to establish connection to %s\n", cls.servername);
|
||||
connectinfo.trying = false;
|
||||
SCR_EndLoadingPlaque();
|
||||
|
@ -1171,6 +1174,7 @@ void CL_CheckForResend (void)
|
|||
|
||||
if (!keeptrying)
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("No route to \"%s\", giving up\n", cls.servername));
|
||||
Con_TPrintf ("No route to host, giving up\n");
|
||||
connectinfo.trying = false;
|
||||
SCR_EndLoadingPlaque();
|
||||
|
@ -2960,19 +2964,28 @@ void CL_ConnectionlessPacket (void)
|
|||
char *data = MSG_ReadStringLine();
|
||||
Con_Printf ("reject\n%s\n", data);
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("%s\n", data));
|
||||
connectinfo.trying = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(s, "badname"))
|
||||
{ //rejected purely because of player name
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("bad player name\n"));
|
||||
connectinfo.trying = false;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(s, "badaccount"))
|
||||
{ //rejected because username or password is wrong
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("invalid username or password\n"));
|
||||
connectinfo.trying = false;
|
||||
}
|
||||
}
|
||||
|
||||
Con_Printf ("f%s\n", s);
|
||||
return;
|
||||
|
@ -3206,6 +3219,7 @@ void CL_ConnectionlessPacket (void)
|
|||
}
|
||||
if (connectinfo.dtlsupgrade == DTLS_REQUIRE)
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("Server does not support/allow dtls. not connecting\n"));
|
||||
connectinfo.trying = false;
|
||||
Con_Printf("Server does not support/allow dtls. not connecting.\n");
|
||||
return;
|
||||
|
|
|
@ -43,6 +43,12 @@ static int cl_dp_csqc_progscrc;
|
|||
static int cl_dp_serverextension_download;
|
||||
#endif
|
||||
|
||||
//tracks which svcs are using what data (per second)
|
||||
static size_t packetusage_saved[256];
|
||||
static size_t packetusage_pending[256];
|
||||
static double packetusageflushtime;
|
||||
static const double packetusage_interval=10;
|
||||
|
||||
#ifdef AVAIL_ZLIB
|
||||
#ifndef ZEXPORT
|
||||
#define ZEXPORT VARGS
|
||||
|
@ -51,7 +57,7 @@ static int cl_dp_serverextension_download;
|
|||
#endif
|
||||
|
||||
|
||||
static char *svc_qwstrings[] =
|
||||
static const char *svc_qwstrings[] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
|
@ -182,7 +188,7 @@ static char *svc_qwstrings[] =
|
|||
};
|
||||
|
||||
#ifdef NQPROT
|
||||
static char *svc_nqstrings[] =
|
||||
static const char *svc_nqstrings[] =
|
||||
{
|
||||
"nqsvc_bad",
|
||||
"nqsvc_nop",
|
||||
|
@ -6701,6 +6707,7 @@ void CLQW_ParseServerMessage (void)
|
|||
qboolean csqcpacket = false;
|
||||
inframe_t *inf;
|
||||
extern vec3_t demoangles;
|
||||
unsigned int cmdstart;
|
||||
|
||||
received_framecount = host_framecount;
|
||||
cl.last_servermessage = realtime;
|
||||
|
@ -6751,6 +6758,13 @@ void CLQW_ParseServerMessage (void)
|
|||
}
|
||||
}
|
||||
|
||||
if (realtime > packetusageflushtime)
|
||||
{
|
||||
memcpy(packetusage_saved, packetusage_pending, sizeof(packetusage_saved));
|
||||
memset(packetusage_pending, 0, sizeof(packetusage_pending));
|
||||
packetusageflushtime = realtime + packetusage_interval;
|
||||
}
|
||||
|
||||
//
|
||||
// parse the message
|
||||
//
|
||||
|
@ -6763,6 +6777,7 @@ void CLQW_ParseServerMessage (void)
|
|||
break;
|
||||
}
|
||||
|
||||
cmdstart = msg_readcount;
|
||||
cmd = MSG_ReadByte ();
|
||||
|
||||
if (cmd == svcfte_choosesplitclient)
|
||||
|
@ -7267,6 +7282,8 @@ void CLQW_ParseServerMessage (void)
|
|||
Con_Printf("Unable to parse gamecode packet\n");
|
||||
break;
|
||||
}
|
||||
|
||||
packetusage_pending[cmd] += msg_readcount-cmdstart;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8282,3 +8299,57 @@ void CLNQ_ParseServerMessage (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
struct sortedsvcs_s
|
||||
{
|
||||
const char *name;
|
||||
size_t bytes;
|
||||
};
|
||||
static QDECL int sorttraffic(const void *l, const void *r)
|
||||
{
|
||||
const struct sortedsvcs_s *a=l, *b=r;
|
||||
|
||||
if (a->bytes==b->bytes)
|
||||
return 0;
|
||||
if (a->bytes>b->bytes)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
void CL_ShowTrafficUsage(float x, float y)
|
||||
{
|
||||
const char **svcnames, *n;
|
||||
size_t svccount, i, j=0;
|
||||
size_t total;
|
||||
struct sortedsvcs_s sorted[256];
|
||||
if (cls.protocol == CP_NETQUAKE)
|
||||
{
|
||||
svcnames = svc_nqstrings;
|
||||
svccount = countof(svc_nqstrings);
|
||||
}
|
||||
else
|
||||
{
|
||||
svcnames = svc_qwstrings;
|
||||
svccount = countof(svc_qwstrings);
|
||||
}
|
||||
total = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
total += packetusage_saved[i];
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (!packetusage_saved[i])
|
||||
continue; //don't show if there's no point.
|
||||
if (i < svccount)
|
||||
n = svcnames[i];
|
||||
else
|
||||
n = va("svc %u", (unsigned)i);
|
||||
sorted[j].name = n;
|
||||
sorted[j].bytes = packetusage_saved[i];
|
||||
j++;
|
||||
}
|
||||
qsort(sorted, j, sizeof(*sorted), sorttraffic);
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
Draw_FunString(x, y, va("%22s:%5.1f%% (%.0f/s)", sorted[i].name, (100.0*sorted[i].bytes)/total, (sorted[i].bytes/packetusage_interval)));
|
||||
y+=8;
|
||||
}
|
||||
}
|
|
@ -648,7 +648,7 @@ static char *SCR_CopyCenterPrint(cprint_t *p) //reads the link under the mouse c
|
|||
}
|
||||
|
||||
#define MAX_CPRINT_LINES 512
|
||||
void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
||||
int SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
||||
{
|
||||
int l;
|
||||
int y, x;
|
||||
|
@ -794,6 +794,8 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
|||
}
|
||||
|
||||
Font_EndString(font);
|
||||
|
||||
return linecount;
|
||||
}
|
||||
|
||||
qboolean Key_Centerprint(int key, int unicode, unsigned int devid)
|
||||
|
@ -904,7 +906,7 @@ void SCR_CheckDrawCenterString (void)
|
|||
}
|
||||
}
|
||||
|
||||
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags, struct font_s *font, vec2_t fontscale)
|
||||
int R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags, struct font_s *font, vec2_t fontscale)
|
||||
{
|
||||
cprint_t p;
|
||||
vrect_t r;
|
||||
|
@ -923,7 +925,7 @@ void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int
|
|||
p.time_start = cl.time;
|
||||
*p.titleimage = 0;
|
||||
|
||||
SCR_DrawCenterString(&r, &p, font);
|
||||
return SCR_DrawCenterString(&r, &p, font);
|
||||
}
|
||||
|
||||
qboolean SCR_HardwareCursorIsActive(void)
|
||||
|
|
|
@ -776,8 +776,8 @@ beam_t *CL_AddBeam (enum beamtype_e tent, int ent, vec3_t start, vec3_t end) //f
|
|||
if (ent < 0 && ent >= -512) //a zquake concept. ent between -1 and -maxplayers is to be taken to be a railtrail from a particular player instead of a beam.
|
||||
{
|
||||
// TODO: add support for those finnicky colored railtrails...
|
||||
if (P_ParticleTrail(start, end, rtqw_railtrail, -ent, NULL, NULL))
|
||||
P_ParticleTrailIndex(start, end, P_INVALID, 208, 8, NULL);
|
||||
if (P_ParticleTrail(start, end, rtqw_railtrail, 0.1, -ent, NULL, NULL))
|
||||
P_ParticleTrailIndex(start, end, P_INVALID, 0.1, 208, 8, NULL);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
@ -1607,8 +1607,8 @@ void CL_ParseTEnt (void)
|
|||
pos2[1] = MSG_ReadCoord ();
|
||||
pos2[2] = MSG_ReadCoord ();
|
||||
|
||||
if (P_ParticleTrail(pos, pos2, rtqw_railtrail, 0, NULL, NULL))
|
||||
P_ParticleTrailIndex(pos, pos2, P_INVALID, 208, 8, NULL);
|
||||
if (P_ParticleTrail(pos, pos2, rtqw_railtrail, 1, 0, NULL, NULL))
|
||||
P_ParticleTrailIndex(pos, pos2, P_INVALID, 1, 208, 8, NULL);
|
||||
break;
|
||||
|
||||
case TEH2_STREAM_LIGHTNING_SMALL:
|
||||
|
@ -1751,8 +1751,8 @@ void CL_ParseTEnt (void)
|
|||
MSG_ReadCoord ();
|
||||
MSG_ReadCoord ();
|
||||
|
||||
if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_nexbeam"), 0, NULL, NULL))
|
||||
P_ParticleTrailIndex(pos, pos2, P_INVALID, 15, 0, NULL);
|
||||
if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_nexbeam"), 1, 0, NULL, NULL))
|
||||
P_ParticleTrailIndex(pos, pos2, P_INVALID, 1, 15, 0, NULL);
|
||||
break;
|
||||
|
||||
case TEDP_SMOKE:
|
||||
|
@ -1933,7 +1933,7 @@ void CL_SpawnCustomTEnt(custtentinst_t *info)
|
|||
}
|
||||
}
|
||||
else
|
||||
failed = P_ParticleTrail(info->pos, info->pos2, t->particleeffecttype, 0, NULL, NULL);
|
||||
failed = P_ParticleTrail(info->pos, info->pos2, t->particleeffecttype, 1, 0, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2262,8 +2262,8 @@ void CL_ParseTrailParticles(void)
|
|||
else
|
||||
ts = NULL;
|
||||
|
||||
if (P_ParticleTrail(start, end, effectindex, entityindex, NULL, ts))
|
||||
P_ParticleTrail(start, end, rt_blood, entityindex, NULL, ts);
|
||||
if (P_ParticleTrail(start, end, effectindex, 1, entityindex, NULL, ts))
|
||||
P_ParticleTrail(start, end, rt_blood, 1, entityindex, NULL, ts);
|
||||
}
|
||||
|
||||
void CL_ParsePointParticles(qboolean compact)
|
||||
|
@ -2588,7 +2588,7 @@ void CLQ2_ParseTEnt (void)
|
|||
case Q2TE_BLUEHYPERBLASTER: //TE_BLASTER without model+light
|
||||
MSG_ReadPos (pos);
|
||||
MSG_ReadPos (pos2);
|
||||
P_ParticleTrail(pos, pos2, pt, 0, NULL, NULL);
|
||||
P_ParticleTrail(pos, pos2, pt, 1, 0, NULL, NULL);
|
||||
break;
|
||||
case Q2TE_EXPLOSION1: //column
|
||||
case Q2TE_EXPLOSION2: //splits
|
||||
|
@ -2674,13 +2674,13 @@ void CLQ2_ParseTEnt (void)
|
|||
MSG_ReadPos (pos);
|
||||
MSG_ReadPos (pos2);
|
||||
color = MSG_ReadByte ();
|
||||
P_ParticleTrailIndex(pos, pos2, pt, color, 0, NULL);
|
||||
P_ParticleTrailIndex(pos, pos2, pt, 1, color, 0, NULL);
|
||||
break;
|
||||
|
||||
case Q2TE_FLASHLIGHT: //white 400-radius dlight
|
||||
MSG_ReadPos(pos);
|
||||
ent = MSG_ReadShort();
|
||||
P_ParticleTrail(pos, pos, pt, ent, NULL, NULL);
|
||||
P_ParticleTrail(pos, pos, pt, 1, ent, NULL, NULL);
|
||||
break;
|
||||
case Q2TE_WIDOWBEAMOUT: /*requires state tracking to keep it splurting constantly for 2.1 secs*/
|
||||
ent = MSG_ReadShort();
|
||||
|
@ -2737,7 +2737,7 @@ void CLQ2_ParseTEnt (void)
|
|||
case CRTE_BLASTERBEAM:
|
||||
MSG_ReadPos (pos);
|
||||
MSG_ReadPos (pos2);
|
||||
P_ParticleTrail(pos, pos2, P_FindParticleType("q2part.TR_BLASTERTRAIL2"), 0, NULL, NULL);
|
||||
P_ParticleTrail(pos, pos2, P_FindParticleType("q2part.TR_BLASTERTRAIL2"), 1, 0, NULL, NULL);
|
||||
break;
|
||||
/* case CRTE_STAIN:
|
||||
Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type);
|
||||
|
@ -2969,7 +2969,7 @@ void CL_UpdateBeams (void)
|
|||
}
|
||||
|
||||
if (ruleset_allow_particle_lightning.ival || !type->modelname)
|
||||
if (type->ef_beam >= 0 && !P_ParticleTrail(org, b->end, type->ef_beam, b->entity, NULL, &b->trailstate))
|
||||
if (type->ef_beam >= 0 && !P_ParticleTrail(org, b->end, type->ef_beam, host_frametime, b->entity, NULL, &b->trailstate))
|
||||
continue;
|
||||
if (!type->model)
|
||||
{
|
||||
|
@ -3151,7 +3151,7 @@ void CL_UpdateExplosions (void)
|
|||
#endif
|
||||
|
||||
if (ex->traileffect != P_INVALID)
|
||||
pe->ParticleTrail(ent->oldorigin, ent->origin, ex->traileffect, 0, ent->axis, &(ex->trailstate));
|
||||
pe->ParticleTrail(ent->oldorigin, ent->origin, ex->traileffect, frametime, 0, ent->axis, &(ex->trailstate));
|
||||
if (!(ex->flags & Q2RF_BEAM))
|
||||
VectorCopy(ent->origin, ex->oldorigin); //don't corrupt q2 beams
|
||||
if (ex->flags & Q2RF_BEAM)
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef struct {
|
|||
} script_t;
|
||||
static script_t *scripts;
|
||||
static int maxscripts;
|
||||
static unsigned int ui_width, ui_height; //to track when it needs to be restarted (the api has no video mode changed event)
|
||||
#define Q3SCRIPTPUNCTUATION "(,{})(\':;=!><&|+-\""
|
||||
void StripCSyntax (char *s)
|
||||
{
|
||||
|
@ -1483,6 +1484,12 @@ void UI_DrawMenu(void)
|
|||
{
|
||||
if (uivm)
|
||||
{
|
||||
if (qrenderer != QR_NONE && (ui_width != vid.width || ui_height != vid.height))
|
||||
{
|
||||
ui_width = vid.width;
|
||||
ui_height = vid.height;
|
||||
VM_Call(uivm, UI_INIT);
|
||||
}
|
||||
VM_Call(uivm, UI_REFRESH, (int)(realtime * 1000));
|
||||
}
|
||||
}
|
||||
|
@ -1585,11 +1592,14 @@ qboolean UI_KeyPress(int key, int unicode, qboolean down)
|
|||
// return result;
|
||||
}
|
||||
|
||||
qboolean UI_MousePosition(int xpos, int ypos)
|
||||
qboolean UI_MousePosition(float xpos, float ypos)
|
||||
{
|
||||
if (uivm && (keycatcher&2))
|
||||
{
|
||||
VM_Call(uivm, UI_MOUSE_EVENT, (xpos)*640/(int)vid.width, (ypos)*480/(int)vid.height);
|
||||
int px, py;
|
||||
px = (xpos);//*640/(int)vid.width;
|
||||
py = (ypos);//*480/(int)vid.height;
|
||||
VM_Call(uivm, UI_MOUSE_EVENT, px, py);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1625,6 +1635,8 @@ void UI_Start (void)
|
|||
for (i = 0; i < MAX_PINGREQUESTS; i++)
|
||||
ui_pings[i].type = NA_INVALID;
|
||||
|
||||
ui_width = vid.width;
|
||||
ui_height = vid.height;
|
||||
uivm = VM_Create("vm/ui", com_nogamedirnativecode.ival?NULL:UI_SystemCallsNative, UI_SystemCallsVM);
|
||||
if (uivm)
|
||||
{
|
||||
|
|
|
@ -1282,6 +1282,7 @@ void CLNQ_ParseServerMessage (void);
|
|||
#ifdef Q2CLIENT
|
||||
void CLQ2_ParseServerMessage (void);
|
||||
#endif
|
||||
void CL_ShowTrafficUsage(float x, float y);
|
||||
void CL_NewTranslation (int slot);
|
||||
|
||||
int CL_IsDownloading(const char *localname);
|
||||
|
|
|
@ -1779,6 +1779,8 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
unsigned int effects, renderfx;
|
||||
float back, fwds;
|
||||
|
||||
float timestep = cl.gametime-cl.oldgametime;
|
||||
|
||||
// bonus items rotate at a fixed rate
|
||||
autorotate = anglemod(cl.time*100);
|
||||
|
||||
|
@ -2206,10 +2208,10 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
if (effects & Q2EF_ROCKET)
|
||||
{
|
||||
//FIXME: cubemap orientation
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_ROCKET], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_rocket, ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_ROCKET], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_rocket, timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 0xdc, 4, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 0xdc, 4, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.1, 0.05);
|
||||
}
|
||||
}
|
||||
|
@ -2220,17 +2222,17 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
//PGM
|
||||
if (effects & Q2EF_TRACKER) // lame... problematic?
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_BLASTERTRAIL2], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_BLASTERTRAIL2], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 0xd0, 1, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 0xd0, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 200, 0, 0.2, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_BLASTERTRAIL], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_BLASTERTRAIL], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 0xe0, 1, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 0xe0, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0);
|
||||
}
|
||||
}
|
||||
|
@ -2245,15 +2247,15 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
}
|
||||
else if (effects & Q2EF_GIB)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_GIB], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_blood, ent.keynum, NULL, ¢->trailstate))
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 0xe8, 8, ¢->trailstate);
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_GIB], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_blood, timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 0xe8, 8, ¢->trailstate);
|
||||
}
|
||||
else if (effects & Q2EF_GRENADE)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_GRENADE], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_grenade, ent.keynum, NULL, ¢->trailstate))
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 4, 8, ¢->trailstate);
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_GRENADE], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_grenade, timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 4, 8, ¢->trailstate);
|
||||
}
|
||||
else if (effects & Q2EF_FLIES)
|
||||
{
|
||||
|
@ -2278,21 +2280,21 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
else if (effects & Q2EF_TRAP)
|
||||
{
|
||||
ent.origin[2] += 32;
|
||||
P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_TRAP], ent.keynum, NULL, ¢->trailstate);
|
||||
P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_TRAP], timestep, ent.keynum, NULL, ¢->trailstate);
|
||||
}
|
||||
else if (effects & Q2EF_FLAG1)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_FLAG1], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_FLAG1], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 242, 1, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 242, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.05, 0.05);
|
||||
}
|
||||
}
|
||||
else if (effects & Q2EF_FLAG2)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_FLAG2], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_FLAG2], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 115, 1, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 115, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 225, 0.05, 0.05, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -2300,9 +2302,9 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
//ROGUE
|
||||
else if (effects & Q2EF_TAGTRAIL)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_TAGTRAIL], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_TAGTRAIL], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 220, 1, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 220, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.2, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -2325,9 +2327,9 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
}
|
||||
else if (effects & Q2EF_TRACKER)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_TRACKER], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_TRACKER], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 0, 1, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 0, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 200, -0.2, -0.2, -0.2);
|
||||
}
|
||||
}
|
||||
|
@ -2336,15 +2338,15 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
// RAFAEL
|
||||
else if (effects & Q2EF_GREENGIB)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_GREENGIB], ent.keynum, NULL, ¢->trailstate))
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 219, 8, ¢->trailstate);
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_GREENGIB], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 219, 8, ¢->trailstate);
|
||||
}
|
||||
// RAFAEL
|
||||
else if (effects & Q2EF_IONRIPPER)
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_IONRIPPER], ent.keynum, NULL, ¢->trailstate))
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_IONRIPPER], timestep, ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, 228, 4, ¢->trailstate);
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, P_INVALID, timestep, 228, 4, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 100, 0.2, 0.1, 0.1);
|
||||
}
|
||||
}
|
||||
|
@ -2358,7 +2360,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
{
|
||||
if (effects & Q2EF_ANIM_ALLFAST)
|
||||
{
|
||||
P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_PLASMA], ent.keynum, NULL, ¢->trailstate);
|
||||
P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_PLASMA], timestep, ent.keynum, NULL, ¢->trailstate);
|
||||
}
|
||||
V_AddLight (ent.keynum, ent.origin, 130, 0.2, 0.1, 0.1);
|
||||
}
|
||||
|
|
|
@ -549,7 +549,6 @@ void CLQ3_ParseGameState(void)
|
|||
cl.maxpitch = 90;
|
||||
|
||||
ccs.lastServerCommandNum = MSG_ReadLong();
|
||||
ccs.currentServerCommandNum = ccs.lastServerCommandNum;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
|
|
@ -219,7 +219,6 @@ typedef struct frame_s {
|
|||
typedef struct {
|
||||
int lastClientCommandNum;
|
||||
int lastServerCommandNum;
|
||||
int currentServerCommandNum;
|
||||
int numClientCommands;
|
||||
|
||||
int serverMessageNum;
|
||||
|
|
|
@ -1068,11 +1068,28 @@ void FPS_Preset_f (void)
|
|||
|
||||
if (!stricmp("dp", arg))
|
||||
{
|
||||
if (sv.state)
|
||||
Cbuf_InsertText("echo Be sure to restart your server\n", RESTRICT_LOCAL, false);
|
||||
Cbuf_InsertText(
|
||||
"set sv_listen_dp 1\n"
|
||||
"set sv_bigcoords 1\n"
|
||||
"set r_particledesc \"effectinfo classic\"\n"
|
||||
"echo you may need to restart the map\n"
|
||||
//these are for smc+derived mods
|
||||
"sv_listen_dp 1\n" //awkward, but forces the server to load the effectinfo.txt in advance.
|
||||
"sv_bigcoords 1\n" //for viewmodel lep precision (would be better to use csqc)
|
||||
"r_particledesc \"effectinfo high\"\n" //blurgh.
|
||||
"dpcompat_noretouchground 1\n" //don't call touch functions on entities that already appear onground. this also changes the order that the onground flag is set relative to touch functions.
|
||||
"cl_nopred 1\n" //DP doesn't predict by default, and DP mods have a nasty habit of clearing .solid values during prethinks, which screws up prediction. so play safe.
|
||||
"r_dynamic 0\nr_shadow_realtime_dlight 1\n" //fte has separate cvars for everything. which kinda surprises people and makes stuff twice as bright as it should be.
|
||||
|
||||
//general compat stuff
|
||||
"dpcompat_console 1\n" //
|
||||
"dpcompat_findradiusarealinks 1\n" //faster findradiuses (but that require things are setorigined properly)
|
||||
"dpcompat_makeshitup 2\n" //flatten shaders to a single pass, then add new specular etc passes.
|
||||
//"dpcompat_nopremulpics 1\n" //don't use premultiplied alpha (solving issues with compressed image formats)
|
||||
"dpcompat_psa_ungroup 1\n" //don't use framegroups with psk models at all.
|
||||
"dpcompat_set 1\n" //handle 3-arg sets differently
|
||||
"dpcompat_stats 1\n" //truncate float stats
|
||||
"dpcompat_strcat_limit 16383\n" //xonotic compat. maximum length of strcat strings.
|
||||
|
||||
// "sv_listen_dp 1\nsv_listen_nq 0\nsv_listen_qw 0\ncl_loopbackprotocol dpp7\ndpcompat_nopreparse 1\n"
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ extern void SCR_DrawConsole (qboolean noback);
|
|||
extern void SCR_SetUpToDrawConsole (void);
|
||||
extern void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode);
|
||||
|
||||
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags, struct font_s *font, vec2_t fontscale);
|
||||
int R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags, struct font_s *font, vec2_t fontscale);
|
||||
#define CPRINT_LALIGN (1<<0) //L
|
||||
#define CPRINT_TALIGN (1<<1) //T
|
||||
#define CPRINT_RALIGN (1<<2) //R
|
||||
|
|
|
@ -265,7 +265,7 @@ static void PClassic_RunParticleEffect4 (vec3_t org, float radius, int color, in
|
|||
}
|
||||
|
||||
//this function is used as a fallback in case a trail effect is unknown.
|
||||
static void PClassic_ParticleTrailIndex (vec3_t start, vec3_t end, int type, int color, int crnd, trailstate_t **tsk)
|
||||
static void PClassic_ParticleTrailIndex (vec3_t start, vec3_t end, int type, float timestep, int color, int crnd, trailstate_t **tsk)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1130,7 +1130,7 @@ int PClassic_PointFile(int c, vec3_t point)
|
|||
}
|
||||
|
||||
//builds a trail from here to there. The trail state can be used to remember how far you got last frame.
|
||||
static int PClassic_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlkey, vec3_t dlaxis[3], trailstate_t **tsk)
|
||||
static int PClassic_ParticleTrail (vec3_t startpos, vec3_t end, int type, float timestep, int dlkey, vec3_t dlaxis[3], trailstate_t **tsk)
|
||||
{
|
||||
float leftover;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ static int PNULL_FindParticleType(const char *name)
|
|||
}
|
||||
|
||||
static int PNULL_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *name){return 1;}
|
||||
static int PNULL_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlkey, vec3_t dlaxis[3], trailstate_t **tsk){return 1;}
|
||||
static int PNULL_ParticleTrail (vec3_t startpos, vec3_t end, int type, float timestep, int dlkey, vec3_t dlaxis[3], trailstate_t **tsk){return 1;}
|
||||
static int PNULL_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk){return 1;}
|
||||
static void PNULL_RunParticleWeather(vec3_t minb, vec3_t maxb, vec3_t dir, float count, int colour, char *efname){}
|
||||
static void PNULL_RunParticleCube(int typenum, vec3_t minb, vec3_t maxb, vec3_t dir_min, vec3_t dir_max, float count, int colour, qboolean gravity, float jitter){}
|
||||
|
@ -22,7 +22,7 @@ static void PNULL_RunParticleEffect3 (vec3_t org, vec3_t box, int color, int eff
|
|||
static void PNULL_RunParticleEffect4 (vec3_t org, float radius, int color, int effect, int count){}
|
||||
static void PNULL_RunParticleEffectPalette (const char *nameprefix, vec3_t org, vec3_t dir, int color, int count){}
|
||||
|
||||
static void PNULL_ParticleTrailIndex (vec3_t start, vec3_t end, int type, int color, int crnd, trailstate_t **tsk){}
|
||||
static void PNULL_ParticleTrailIndex (vec3_t start, vec3_t end, int type, float timestep, int color, int crnd, trailstate_t **tsk){}
|
||||
|
||||
static qboolean PNULL_InitParticles (void)
|
||||
{
|
||||
|
|
|
@ -264,6 +264,8 @@ typedef struct part_type_s {
|
|||
int countextra;
|
||||
float count;
|
||||
float countrand;
|
||||
float countspacing; //for trails.
|
||||
float countoverflow; //for badly-designed effects, instead of depending on trail state.
|
||||
float rainfrequency;
|
||||
|
||||
int assoc;
|
||||
|
@ -1368,12 +1370,14 @@ void P_ParticleEffect_f(void)
|
|||
|
||||
else if (!strcmp(var, "step"))
|
||||
{
|
||||
ptype->countspacing = atof(value);
|
||||
ptype->count = 1/atof(value);
|
||||
if (Cmd_Argc()>2)
|
||||
ptype->countrand = 1/atof(Cmd_Argv(2));
|
||||
}
|
||||
else if (!strcmp(var, "count"))
|
||||
{
|
||||
ptype->countspacing = 0;
|
||||
ptype->count = atof(value);
|
||||
if (Cmd_Argc()>2)
|
||||
ptype->countrand = atof(Cmd_Argv(2));
|
||||
|
@ -2401,7 +2405,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
|
|||
Q_strncatz(outstr, va("tcoords %g %g %g %g %g %i %g\n", ptype->s1, ptype->t1, ptype->s2, ptype->t2, 1.0f, ptype->randsmax, ptype->texsstride), outstrlen);
|
||||
}
|
||||
|
||||
if (ptype->count || all)
|
||||
if (ptype->count || ptype->countrand || ptype->countextra || all)
|
||||
Q_strncatz(outstr, va("count %g %g %i\n", ptype->count, ptype->countrand, ptype->countextra), outstrlen);
|
||||
if (ptype->rainfrequency != 1 || all)
|
||||
Q_strncatz(outstr, va("rainfrequency %g\n", ptype->rainfrequency), outstrlen);
|
||||
|
@ -3152,7 +3156,10 @@ static void P_ImportEffectInfo(char *config, char *line)
|
|||
else if (!strcmp(arg[0], "velocitymultiplier") && args == 2)
|
||||
ptype->veladd = atof(arg[1]);
|
||||
else if (!strcmp(arg[0], "trailspacing") && args == 2)
|
||||
ptype->count = 1 / atof(arg[1]);
|
||||
{
|
||||
ptype->countspacing = atof(arg[1]);
|
||||
ptype->count = 1 / ptype->countspacing;
|
||||
}
|
||||
else if (!strcmp(arg[0], "time") && args == 3)
|
||||
{
|
||||
ptype->die = atof(arg[1]);
|
||||
|
@ -5476,7 +5483,7 @@ static void PScript_RunParticleEffectPalette (const char *nameprefix, vec3_t org
|
|||
}
|
||||
}
|
||||
|
||||
static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype, trailstate_t **tsk, int dlkey, vec3_t dlaxis[3])
|
||||
static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptype, float timeinterval, trailstate_t **tsk, int dlkey, vec3_t dlaxis[3])
|
||||
{
|
||||
vec3_t vec, vstep, right, up, start;
|
||||
float len;
|
||||
|
@ -5528,9 +5535,9 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
|
|||
if (ptype->assoc>=0)
|
||||
{
|
||||
if (ts)
|
||||
P_ParticleTrail(start, end, ptype->assoc, dlkey, NULL, &(ts->assoc));
|
||||
P_ParticleTrail(start, end, ptype->assoc, timeinterval, dlkey, NULL, &(ts->assoc));
|
||||
else
|
||||
P_ParticleTrail(start, end, ptype->assoc, dlkey, NULL, NULL);
|
||||
P_ParticleTrail(start, end, ptype->assoc, timeinterval, dlkey, NULL, NULL);
|
||||
}
|
||||
|
||||
if (r_part_contentswitch.ival && (ptype->flags & (PT_TRUNDERWATER | PT_TROVERWATER)) && cl.worldmodel)
|
||||
|
@ -5561,20 +5568,30 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
|
|||
if (!ptype->die)
|
||||
ts = NULL;
|
||||
|
||||
// use ptype step to calc step vector and step size
|
||||
step = (ptype->count*r_part_density.value) + ptype->countextra;
|
||||
if (step>0)
|
||||
{
|
||||
step = 1/step;
|
||||
if (step < 0.01)
|
||||
step = 0.01;
|
||||
}
|
||||
else
|
||||
step = 0;
|
||||
|
||||
VectorSubtract (end, start, vec);
|
||||
len = VectorNormalize (vec);
|
||||
|
||||
// use ptype step to calc step vector and step size
|
||||
if (ptype->countspacing)
|
||||
{
|
||||
step = ptype->countspacing; //particles per qu
|
||||
step /= r_part_density.value; //scaled...
|
||||
|
||||
//FIXME: countextra
|
||||
}
|
||||
else
|
||||
{
|
||||
step = ptype->count * r_part_density.value * timeinterval;
|
||||
step += ptype->countextra; //particles per frame
|
||||
step += ptype->countoverflow;
|
||||
count = (int)step;
|
||||
ptype->countoverflow = step-count; //the part that we're forgetting, to add to the next frame...
|
||||
if (count<=0)
|
||||
return;
|
||||
else
|
||||
step = len/count; //particles per second
|
||||
}
|
||||
|
||||
if (ptype->flags & PT_AVERAGETRAIL)
|
||||
{
|
||||
float tavg;
|
||||
|
@ -5641,7 +5658,10 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
|
|||
step = 0;
|
||||
VectorClear(vstep);
|
||||
}
|
||||
count += ptype->countextra;
|
||||
// count += ptype->countextra;
|
||||
|
||||
if (count > 1000)
|
||||
count = 1000;
|
||||
|
||||
while (count-->0)//len < stop)
|
||||
{
|
||||
|
@ -5992,14 +6012,14 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
|
|||
return;
|
||||
}
|
||||
|
||||
static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlkey, vec3_t axis[3], trailstate_t **tsk)
|
||||
static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, float timeinterval, int dlkey, vec3_t axis[3], trailstate_t **tsk)
|
||||
{
|
||||
part_type_t *ptype = &part_type[type];
|
||||
|
||||
// TODO: fallback particle system won't have a decent trailstate which will mess up
|
||||
// high fps trails
|
||||
if (type >= FALLBACKBIAS && fallback)
|
||||
return fallback->ParticleTrail(startpos, end, type-FALLBACKBIAS, dlkey, axis, NULL);
|
||||
return fallback->ParticleTrail(startpos, end, type-FALLBACKBIAS, timeinterval, dlkey, axis, NULL);
|
||||
|
||||
if (type < 0 || type >= numparticletypes)
|
||||
return 1; //bad value
|
||||
|
@ -6017,11 +6037,11 @@ static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlk
|
|||
ptype = &part_type[ptype->inwater];
|
||||
}
|
||||
|
||||
P_ParticleTrailDraw (startpos, end, ptype, tsk, dlkey, axis);
|
||||
P_ParticleTrailSpawn (startpos, end, ptype, timeinterval, tsk, dlkey, axis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PScript_ParticleTrailIndex (vec3_t start, vec3_t end, int type, int color, int crnd, trailstate_t **tsk)
|
||||
static void PScript_ParticleTrailIndex (vec3_t start, vec3_t end, int type, float timeinterval, int color, int crnd, trailstate_t **tsk)
|
||||
{
|
||||
if (type == P_INVALID)
|
||||
type = pe_defaulttrail;
|
||||
|
@ -6029,7 +6049,7 @@ static void PScript_ParticleTrailIndex (vec3_t start, vec3_t end, int type, int
|
|||
{
|
||||
part_type[type].colorindex = color;
|
||||
part_type[type].colorrand = crnd;
|
||||
P_ParticleTrail(start, end, type, 0, NULL, tsk);
|
||||
P_ParticleTrail(start, end, type, timeinterval, 0, NULL, tsk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7280,7 +7300,7 @@ static void PScript_DrawParticleTypes (void)
|
|||
if (type->emit >= 0)
|
||||
{
|
||||
if (type->emittime < 0)
|
||||
P_ParticleTrail(oldorg, p->org, type->emit, 0, NULL, &p->state.trailstate);
|
||||
P_ParticleTrail(oldorg, p->org, type->emit, pframetime, 0, NULL, &p->state.trailstate);
|
||||
else if (p->state.nextemit < particletime)
|
||||
{
|
||||
p->state.nextemit = particletime + type->emittime + frandom()*type->emitrand;
|
||||
|
|
|
@ -59,6 +59,8 @@ static csqctreadstate_t *csqcthreads;
|
|||
qboolean csqc_resortfrags;
|
||||
world_t csqc_world;
|
||||
|
||||
float csqc_starttime; //reset on each csqc reload to restore lost precision of cltime on each map restart.
|
||||
|
||||
int csqc_playerseat; //can be negative.
|
||||
static playerview_t *csqc_playerview;
|
||||
qboolean csqc_dp_lastwas3d; //to emulate DP correctly, we need to track whether drawpic/drawfill or clearscene was called last. blame 515.
|
||||
|
@ -423,7 +425,7 @@ static void CSQC_FindGlobals(qboolean nofuncs)
|
|||
if (csqcg.simtime)
|
||||
*csqcg.simtime = cl.servertime;
|
||||
if (csqcg.cltime)
|
||||
*csqcg.cltime = realtime;
|
||||
*csqcg.cltime = realtime-csqc_starttime;
|
||||
|
||||
if (!csqcg.global_gravitydir)
|
||||
csqcg.global_gravitydir = defaultgravity;
|
||||
|
@ -3199,7 +3201,7 @@ static void QCBUILTIN PF_cs_boxparticles(pubprogfuncs_t *prinst, struct globalva
|
|||
if (flags & 128) //PARTICLES_DRAWASTRAIL
|
||||
{
|
||||
flags &= ~128;
|
||||
P_ParticleTrail(org_from, org_to, effectnum, 0, NULL, NULL);
|
||||
P_ParticleTrail(org_from, org_to, effectnum, 1, 0, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3235,6 +3237,7 @@ static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globa
|
|||
csqcedict_t *ent;
|
||||
float *start = G_VECTOR(OFS_PARM2);
|
||||
float *end = G_VECTOR(OFS_PARM3);
|
||||
float timestep = host_frametime;
|
||||
|
||||
if ((unsigned int)G_INT(OFS_PARM1) >= MAX_EDICTS)
|
||||
{ //ents can't be negative, nor can they be huge (like floats are if expressed as an integer)
|
||||
|
@ -3249,9 +3252,9 @@ static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globa
|
|||
efnum = CL_TranslateParticleFromServer(efnum);
|
||||
|
||||
if (!ent->entnum) //world trails are non-state-based.
|
||||
pe->ParticleTrail(start, end, efnum, 0, NULL, NULL);
|
||||
pe->ParticleTrail(start, end, efnum, timestep, 0, NULL, NULL);
|
||||
else
|
||||
pe->ParticleTrail(start, end, efnum, -ent->entnum, NULL, &ent->trailstate);
|
||||
pe->ParticleTrail(start, end, efnum, timestep, -ent->entnum, NULL, &ent->trailstate);
|
||||
}
|
||||
|
||||
void CSQC_ResetTrails(void)
|
||||
|
@ -5064,9 +5067,9 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src
|
|||
//use entnum as a test to see if its new (if the old origin isn't usable)
|
||||
if (ent->xv->entnum)
|
||||
{
|
||||
if (model->particletrail == P_INVALID || pe->ParticleTrail (ent->v->origin, src->origin, model->particletrail, src->number, NULL, &(le->trailstate)))
|
||||
if (model->particletrail == P_INVALID || pe->ParticleTrail (ent->v->origin, src->origin, model->particletrail, host_frametime, src->number, NULL, &(le->trailstate)))
|
||||
if (model->traildefaultindex >= 0)
|
||||
pe->ParticleTrailIndex(ent->v->origin, src->origin, P_INVALID, model->traildefaultindex, 0, &(le->trailstate));
|
||||
pe->ParticleTrailIndex(ent->v->origin, src->origin, P_INVALID, host_frametime, model->traildefaultindex, 0, &(le->trailstate));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7331,6 +7334,10 @@ pbool PDECL CSQC_CheckHeaderCrc(pubprogfuncs_t *progs, progsnum_t num, int crc)
|
|||
csqc_isdarkplaces = true;
|
||||
Con_DPrintf(CON_WARNING "Running darkplaces csprogs.dat version\n");
|
||||
break;
|
||||
case 23147:
|
||||
csqc_isdarkplaces = true;
|
||||
Con_DPrintf(CON_WARNING "Running ^aINVALID^a csprogs.dat version\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Con_Printf(CON_WARNING "Running unknown csprogs.dat version\n");
|
||||
|
@ -7467,6 +7474,7 @@ qboolean CSQC_Init (qboolean anycsqc, const char *csprogsname, unsigned int chec
|
|||
int csaddonnum = -1;
|
||||
in_sensitivityscale = 1;
|
||||
csqcmapentitydataloaded = true;
|
||||
csqc_starttime = realtime;
|
||||
csqcprogs = InitProgs(&csqcprogparms);
|
||||
csqc_world.progs = csqcprogs;
|
||||
csqc_world.usesolidcorpse = true;
|
||||
|
@ -8067,7 +8075,7 @@ qboolean CSQC_DrawView(void)
|
|||
CL_PredictMove ();
|
||||
|
||||
if (csqcg.cltime)
|
||||
*csqcg.cltime = realtime;
|
||||
*csqcg.cltime = realtime-csqc_starttime;
|
||||
if (csqcg.simtime)
|
||||
*csqcg.simtime = cl.servertime;
|
||||
if (csqcg.clientcommandframe)
|
||||
|
@ -8156,7 +8164,7 @@ qboolean CSQC_DrawHud(playerview_t *pv)
|
|||
if (csqcg.frametime)
|
||||
*csqcg.frametime = host_frametime;
|
||||
if (csqcg.cltime)
|
||||
*csqcg.cltime = realtime;
|
||||
*csqcg.cltime = realtime-csqc_starttime;
|
||||
|
||||
G_FLOAT(OFS_PARM0+0) = r_refdef.grect.width;
|
||||
G_FLOAT(OFS_PARM0+1) = r_refdef.grect.height;
|
||||
|
@ -8200,7 +8208,7 @@ qboolean CSQC_DrawScores(playerview_t *pv)
|
|||
if (csqcg.frametime)
|
||||
*csqcg.frametime = host_frametime;
|
||||
if (csqcg.cltime)
|
||||
*csqcg.cltime = realtime;
|
||||
*csqcg.cltime = realtime-csqc_starttime;
|
||||
|
||||
G_FLOAT(OFS_PARM0+0) = r_refdef.grect.width;
|
||||
G_FLOAT(OFS_PARM0+1) = r_refdef.grect.height;
|
||||
|
@ -8629,7 +8637,7 @@ void CSQC_Input_Frame(int seat, usercmd_t *cmd)
|
|||
if (csqcg.simtime)
|
||||
*csqcg.simtime = cl.servertime;
|
||||
if (csqcg.cltime)
|
||||
*csqcg.cltime = realtime;
|
||||
*csqcg.cltime = realtime-csqc_starttime;
|
||||
|
||||
if (csqcg.clientcommandframe)
|
||||
*csqcg.clientcommandframe = cl.movesequence;
|
||||
|
@ -8743,7 +8751,7 @@ void CSQC_ParseEntities(void)
|
|||
if (csqcg.simtime) //estimated server time
|
||||
*csqcg.simtime = cl.servertime;
|
||||
if (csqcg.cltime) //smooth client time.
|
||||
*csqcg.cltime = realtime;
|
||||
*csqcg.cltime = realtime-csqc_starttime;
|
||||
|
||||
if (csqcg.netnewtime)
|
||||
*csqcg.netnewtime = cl.gametime;
|
||||
|
|
|
@ -438,7 +438,7 @@ void QCBUILTIN PF_CL_DrawTextField (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
// Oversight ~eukara
|
||||
R2D_ImageColours(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
R_DrawTextField(pos[0], pos[1], size[0], size[1], text, CON_WHITEMASK, flags, font, scale);
|
||||
G_FLOAT(OFS_RETURN) = R_DrawTextField(pos[0], pos[1], size[0], size[1], text, CON_WHITEMASK, flags, font, scale);
|
||||
}
|
||||
|
||||
//float drawstring(vector position, string text, vector scale, float alpha, float flag) = #455;
|
||||
|
|
|
@ -1728,7 +1728,6 @@ char *particle_set_high =
|
|||
"}\n"
|
||||
"#endif\n"
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
"uniform sampler2D s_t0;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
"vec2 nst;\n"
|
||||
|
|
|
@ -29,6 +29,4 @@ extern char *particle_set_q2part;
|
|||
extern char *particle_set_tsshaft;
|
||||
#define R_PARTSET_BUILTINS_tsshaft {"tsshaft", &particle_set_tsshaft},
|
||||
#define R_PARTSET_BUILTINS R_PARTSET_BUILTINS_spikeset R_PARTSET_BUILTINS_faithful R_PARTSET_BUILTINS_highfps R_PARTSET_BUILTINS_high R_PARTSET_BUILTINS_minimal R_PARTSET_BUILTINS_h2part R_PARTSET_BUILTINS_q2part R_PARTSET_BUILTINS_tsshaft
|
||||
#else
|
||||
#define R_PARTSET_BUILTINS
|
||||
#endif
|
||||
|
|
|
@ -3495,6 +3495,11 @@ static void S_Q2_AddEntitySounds(soundcardinfo_t *sc)
|
|||
if (cls.protocol == CP_QUAKE2)
|
||||
count = CLQ2_GatherSounds(positions, entnums, sounds, countof(sounds));
|
||||
else
|
||||
#endif
|
||||
#ifdef Q3CLIENT
|
||||
if (cls.protocol == CP_QUAKE3)
|
||||
count = CG_GatherLoopingSounds(positions, entnums, sounds, countof(sounds));
|
||||
else
|
||||
#endif
|
||||
return;
|
||||
|
||||
|
@ -3548,7 +3553,11 @@ static void S_Q2_AddEntitySounds(soundcardinfo_t *sc)
|
|||
}
|
||||
if (sc->ChannelUpdate)
|
||||
{ //hardware mixing doesn't support merging
|
||||
VectorCopy(positions[count], c->origin);
|
||||
SND_Spatialize(sc, c);
|
||||
|
||||
if (c->sfx)
|
||||
sc->ChannelUpdate(sc, c, false);
|
||||
}
|
||||
else
|
||||
{ //merge with any other ents, if we can
|
||||
|
|
|
@ -881,7 +881,7 @@ void Con_Editor_GoToLine(console_t *con, int line)
|
|||
con->display = con->display->newer;
|
||||
}
|
||||
}
|
||||
console_t *Con_TextEditor(const char *fname, const char *line, qboolean newfile)
|
||||
console_t *Con_TextEditor(const char *fname, const char *line, pubprogfuncs_t *disasmfuncs)
|
||||
{
|
||||
static int editorcascade;
|
||||
console_t *con;
|
||||
|
@ -926,7 +926,26 @@ console_t *Con_TextEditor(const char *fname, const char *line, qboolean newfile)
|
|||
con->close = Con_Editor_Close;
|
||||
con->maxlines = 0x7fffffff; //line limit is effectively unbounded, for a 31-bit process.
|
||||
|
||||
if (!newfile)
|
||||
if (disasmfuncs)
|
||||
{
|
||||
int i;
|
||||
char buffer[65536];
|
||||
int start = 1;
|
||||
int end = INT_MAX;
|
||||
char *colon = strchr(con->name, ':');
|
||||
if (colon && *colon==':')
|
||||
start = strtol(colon+1, &colon, 0);
|
||||
if (colon && *colon==':')
|
||||
end = strtol(colon+1, &colon, 0);
|
||||
for (i = start; !end || i < end; i++)
|
||||
{
|
||||
disasmfuncs->GenerateStatementString(disasmfuncs, i, buffer, sizeof(buffer));
|
||||
if (!*buffer)
|
||||
break;
|
||||
Con_PrintCon(con, buffer, PFS_FORCEUTF8|PFS_KEEPMARKUP|PFS_NONOTIFY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
file = FS_OpenVFS(fname, "rb", FS_GAME);
|
||||
if (file)
|
||||
|
@ -939,10 +958,9 @@ console_t *Con_TextEditor(const char *fname, const char *line, qboolean newfile)
|
|||
}
|
||||
VFS_CLOSE(file);
|
||||
}
|
||||
|
||||
}
|
||||
for (l = con->oldest; l; l = l->newer)
|
||||
Con_Editor_LineChanged(con, l);
|
||||
}
|
||||
|
||||
con->display = con->oldest;
|
||||
con->selstartline = con->selendline = con->oldest; //put the cursor at the start of the file
|
||||
|
@ -972,10 +990,10 @@ void Con_TextEditor_f(void)
|
|||
Con_Printf("%s [filename[:line]]: edit a file\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
Con_TextEditor(fname, line, false);
|
||||
Con_TextEditor(fname, line, NULL);
|
||||
}
|
||||
|
||||
int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *statement, char *reason, pbool fatal)
|
||||
int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *statement, int firststatement, char *reason, pbool fatal)
|
||||
{
|
||||
char newname[MAX_QPATH];
|
||||
console_t *edit;
|
||||
|
@ -983,7 +1001,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
|
|||
if (!strncmp(filename, "./", 2))
|
||||
filename+=2;
|
||||
|
||||
stepasm = !line || *line < 0;
|
||||
stepasm = !line || *line < 0 || pr_debugger.ival==2;
|
||||
|
||||
//we can cope with no line info by displaying asm
|
||||
if (editormodal || (stepasm && !statement))
|
||||
|
@ -1001,7 +1019,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
|
|||
return DEBUG_TRACE_OFF; //get lost
|
||||
}
|
||||
|
||||
if (qrenderer == QR_NONE || stepasm)
|
||||
if (qrenderer == QR_NONE)// || stepasm)
|
||||
{ //just dump the line of code that's being execed onto the console.
|
||||
int i;
|
||||
char buffer[8192];
|
||||
|
@ -1086,20 +1104,32 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
|
|||
}
|
||||
|
||||
if (stepasm)
|
||||
{
|
||||
if (*statement)
|
||||
{
|
||||
char *fname = va(":%#x:%#x", firststatement, firststatement+300);
|
||||
edit = Con_TextEditor(fname, NULL, prfncs);
|
||||
if (!edit)
|
||||
return DEBUG_TRACE_OFF;
|
||||
firststatement--; //displayed statements are +1
|
||||
executionlinenum = *statement - firststatement;
|
||||
Con_Editor_GoToLine(edit, executionlinenum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fatal)
|
||||
return DEBUG_TRACE_ABORT;
|
||||
return DEBUG_TRACE_OFF; //whoops
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
edit = Con_TextEditor(filename, NULL, false);
|
||||
edit = Con_TextEditor(filename, NULL, NULL);
|
||||
if (!edit)
|
||||
return DEBUG_TRACE_OFF;
|
||||
Con_Editor_GoToLine(edit, *line);
|
||||
}
|
||||
|
||||
executionlinenum = *line;
|
||||
}
|
||||
|
||||
{
|
||||
double oldrealtime = realtime;
|
||||
|
@ -1138,7 +1168,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
|
|||
{
|
||||
if (line)
|
||||
*line = 0;
|
||||
*statement = executionlinenum;
|
||||
*statement = executionlinenum+firststatement;
|
||||
}
|
||||
else if (line)
|
||||
*line = executionlinenum;
|
||||
|
|
|
@ -862,7 +862,7 @@ void R_LightArrays(const entity_t *entity, vecV_t *coords, avec4_t *colours, int
|
|||
//don't include world lights
|
||||
for (lno = rtlights_first; lno < RTL_FIRST; lno++)
|
||||
{
|
||||
if (cl_dlights[lno].radius)
|
||||
if (cl_dlights[lno].radius && (cl_dlights[lno].flags & LFLAG_LIGHTMAP))
|
||||
{
|
||||
VectorSubtract (cl_dlights[lno].origin,
|
||||
entity->origin,
|
||||
|
@ -3341,6 +3341,7 @@ static void *Q1MDL_LoadSkins_SV (galiasinfo_t *galias, dmdl_t *pq1inmodel, dalia
|
|||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
static cvar_t dpcompat_nofloodfill = CVARD("dpcompat_nofloodfill", "0", "Disables the q1mdl floodfill. Setting this to 1 may result in blue seams on the vanilla quake models.");
|
||||
/*
|
||||
=================
|
||||
Mod_FloodFillSkin
|
||||
|
@ -3377,6 +3378,9 @@ static void Mod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight )
|
|||
int filledcolor = -1;
|
||||
int i;
|
||||
|
||||
if (dpcompat_nofloodfill.ival)
|
||||
return;
|
||||
|
||||
if (filledcolor == -1)
|
||||
{
|
||||
filledcolor = 0;
|
||||
|
@ -8541,6 +8545,9 @@ static qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t f
|
|||
void Alias_Register(void)
|
||||
{
|
||||
#ifdef MD1MODELS
|
||||
#ifndef SERVERONLY
|
||||
Cvar_Register(&dpcompat_nofloodfill, NULL);
|
||||
#endif
|
||||
Mod_RegisterModelFormatMagic(NULL, "Quake1 Model (mdl)", IDPOLYHEADER, Mod_LoadQ1Model);
|
||||
Mod_RegisterModelFormatMagic(NULL, "QuakeForge 16bit Model", (('6'<<24)+('1'<<16)+('D'<<8)+'M'), Mod_LoadQ1Model);
|
||||
#ifdef HEXEN2
|
||||
|
|
|
@ -89,9 +89,15 @@ cvar_t r_meshpitch;
|
|||
//#define ODE_DYNAMIC 1
|
||||
//#endif
|
||||
|
||||
//ODE's headers provide version info only as a string, so we don' know when things are deprecated or not.
|
||||
//this then fucks us over when we try using -Werror
|
||||
//so until ODE changes its ways, we'll just have to make assumptions and ignore those warnings.
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#define ODEVERSION MAKE2VER(0,15)
|
||||
#define MAKE2VER(maj,min) (((maj)<<8)|(min))
|
||||
|
||||
// LordHavoc: this large chunk of definitions comes from the ODE library
|
||||
// include files.
|
||||
|
||||
#ifdef ODE_STATIC
|
||||
#undef ODE_DYNAMIC
|
||||
#define dDOUBLE
|
||||
|
@ -1675,8 +1681,16 @@ static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
|||
break;
|
||||
case JOINTTYPE_HINGE2:
|
||||
dJointSetHinge2Anchor(j, origin[0], origin[1], origin[2]);
|
||||
#if ODEVERSION>=MAKE2VER(0,16)
|
||||
{
|
||||
dReal a1[]={forward[0], forward[1], forward[2]}, a2[]={velocity[0], velocity[1], velocity[2]};
|
||||
dJointSetHinge2Axes(j, a1, a2);
|
||||
}
|
||||
#else
|
||||
dJointSetHinge2Axis1(j, forward[0], forward[1], forward[2]);
|
||||
dJointSetHinge2Axis2(j, velocity[0], velocity[1], velocity[2]);
|
||||
#endif
|
||||
|
||||
dJointSetHinge2Param(j, dParamFMax, FMax);
|
||||
dJointSetHinge2Param(j, dParamHiStop, Stop);
|
||||
dJointSetHinge2Param(j, dParamLoStop, -Stop);
|
||||
|
@ -1953,8 +1967,15 @@ static void QDECL World_ODE_RagCreateJoint(world_t *world, rbejoint_t *joint, rb
|
|||
break;
|
||||
case JOINTTYPE_HINGE2:
|
||||
dJointSetHinge2Anchor(joint->joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]);
|
||||
#if ODEVERSION>=MAKE2VER(0,16)
|
||||
{
|
||||
dReal a1[]={aaa2[1][0], aaa2[1][1], aaa2[1][2]}, a2[]={aaa2[2][0], aaa2[2][1], aaa2[2][2]};
|
||||
dJointSetHinge2Axes(joint->joint, a1, a2);
|
||||
}
|
||||
#else
|
||||
dJointSetHinge2Axis1(joint->joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]);
|
||||
dJointSetHinge2Axis2(joint->joint, aaa2[2][0], aaa2[2][1], aaa2[2][2]);
|
||||
#endif
|
||||
dJointSetHinge2Param(joint->joint, dParamFMax, info->FMax);
|
||||
dJointSetHinge2Param(joint->joint, dParamHiStop, info->HiStop);
|
||||
dJointSetHinge2Param(joint->joint, dParamLoStop, info->LoStop);
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool. doesn't support mips.
|
||||
#define IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
|
||||
//#define IMAGEFMT_BLP //legacy crap
|
||||
#define IMAGEFMT_BMP //windows bmp. yuck.
|
||||
#define IMAGEFMT_BMP //windows bmp. yuck. also includes .ico for the luls
|
||||
#define IMAGEFMT_PCX //paletted junk. required for qw player skins, q2 and a few old skyboxes.
|
||||
//#define IMAGEFMT_VTF //hl2 image format
|
||||
#define AVAIL_PNGLIB //.png image format support (read+screenshots)
|
||||
|
|
|
@ -246,7 +246,7 @@ typedef struct {
|
|||
qboolean (*ParticleQuery) (int type, int body, char *outstr, int outstrlen);
|
||||
|
||||
int (*RunParticleEffectTypeString) (vec3_t org, vec3_t dir, float count, char *name);
|
||||
int (*ParticleTrail) (vec3_t startpos, vec3_t end, int type, int dlkey, vec3_t dlaxis[3], trailstate_t **tsk);
|
||||
int (*ParticleTrail) (vec3_t startpos, vec3_t end, int type, float timeinterval, int dlkey, vec3_t dlaxis[3], trailstate_t **tsk);
|
||||
int (*RunParticleEffectState) (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk);
|
||||
void (*RunParticleWeather) (vec3_t minb, vec3_t maxb, vec3_t dir, float count, int colour, char *efname);
|
||||
void (*RunParticleCube) (int typenum, vec3_t minb, vec3_t maxb, vec3_t dir_min, vec3_t dir_max, float count, int colour, qboolean gravity, float jitter); //typenum may be P_INVALID
|
||||
|
@ -256,7 +256,7 @@ typedef struct {
|
|||
void (*RunParticleEffect4) (vec3_t org, float radius, int color, int effect, int count);
|
||||
void (*RunParticleEffectPalette) (const char *nameprefix, vec3_t org, vec3_t dir, int color, int count);
|
||||
|
||||
void (*ParticleTrailIndex) (vec3_t start, vec3_t end, int type, int color, int crnd, trailstate_t **tsk); //P_INVALID is fine for the type here, you'll get a default trail.
|
||||
void (*ParticleTrailIndex) (vec3_t start, vec3_t end, int type, float timeinterval, int color, int crnd, trailstate_t **tsk); //P_INVALID is fine for the type here, you'll get a default trail.
|
||||
qboolean (*InitParticles) (void);
|
||||
void (*ShutdownParticles) (void);
|
||||
void (*DelinkTrailstate) (trailstate_t **tsk);
|
||||
|
|
|
@ -186,7 +186,7 @@ static int debuggerstacky;
|
|||
void INS_UpdateGrabs(int fullscreen, int activeapp);
|
||||
#endif
|
||||
|
||||
int QCLibEditor(pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, char *error, pbool fatal);
|
||||
int QCLibEditor(pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, int firststatement, char *error, pbool fatal);
|
||||
void QCLoadBreakpoints(const char *vmname, const char *progsname)
|
||||
{ //this asks the gui to reapply any active breakpoints and waits for them so that any spawn functions can be breakpointed properly.
|
||||
extern int isPlugin;
|
||||
|
@ -377,7 +377,7 @@ qboolean QCExternalDebuggerCommand(char *text)
|
|||
return true;
|
||||
}
|
||||
|
||||
int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, char *reason, pbool fatal)
|
||||
int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, int firststatement, char *reason, pbool fatal)
|
||||
{
|
||||
//#if defined(_WIN32) && !defined(FTE_SDL) && !defined(_XBOX)
|
||||
if (isPlugin >= 2)
|
||||
|
@ -474,7 +474,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
//#endif
|
||||
|
||||
#ifdef TEXTEDITOR
|
||||
return QCLibEditor(prinst, filename, line, statement, reason, fatal);
|
||||
return QCLibEditor(prinst, filename, line, statement, firststatement, reason, fatal);
|
||||
#else
|
||||
if (fatal)
|
||||
return DEBUG_TRACE_ABORT;
|
||||
|
|
|
@ -517,7 +517,7 @@ void QCBUILTIN PF_gettime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
|
|||
|
||||
void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
||||
int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, char *reason, pbool fatal);
|
||||
int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, int firststatement, char *reason, pbool fatal);
|
||||
void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored);
|
||||
void PR_Common_SaveGame(vfsfile_t *f, pubprogfuncs_t *prinst, qboolean binary);
|
||||
qboolean PR_Common_LoadGame(pubprogfuncs_t *prinst, char *command, const char **file);
|
||||
|
|
|
@ -67,7 +67,7 @@ qboolean UI_OpenMenu(void);
|
|||
void UI_Restart_f(void);
|
||||
qboolean UI_Q2LayoutChanged(void);
|
||||
void UI_StringChanged(int num);
|
||||
qboolean UI_MousePosition(int xpos, int ypos);
|
||||
qboolean UI_MousePosition(float xpos, float ypos);
|
||||
int UI_MenuState(void);
|
||||
qboolean UI_KeyPress(int key, int unicode, qboolean down);
|
||||
void UI_Reset(void);
|
||||
|
|
|
@ -141,6 +141,8 @@ void R_NetGraph (void)
|
|||
|
||||
M_DrawTextBox (x, y, NET_TIMINGS/8, (NET_GRAPHHEIGHT + textheight)/8);
|
||||
x = 8;
|
||||
if (r_netgraph.ival > 1)
|
||||
CL_ShowTrafficUsage(x + NET_TIMINGS + 8, y);
|
||||
y += 8; //top border
|
||||
graphtop = y+textheight;
|
||||
|
||||
|
|
|
@ -3490,17 +3490,21 @@ static void X_StoreIcon(Window wnd)
|
|||
if (!filedata)
|
||||
filedata = FS_LoadMallocFile("icon.jpg", &filesize);
|
||||
#endif
|
||||
#ifdef IMAGEFMT_BMP
|
||||
if (!filedata)
|
||||
filedata = FS_LoadMallocFile("icon.ico", &filesize);
|
||||
#endif
|
||||
if (filedata)
|
||||
{
|
||||
int imagewidth, imageheight;
|
||||
int *iconblob;
|
||||
unsigned long *iconblob; //yes, long, even on 64bit machines. and even when we claim it to be 32bit. xlib legacy cruft that'll get stripped...
|
||||
uploadfmt_t format;
|
||||
qbyte *imagedata = ReadRawImageFile(filedata, filesize, &imagewidth, &imageheight, &format, true, "icon.png");
|
||||
Z_Free(filedata);
|
||||
|
||||
iconblob = BZ_Malloc(sizeof(int)*(2+imagewidth*imageheight));
|
||||
if (imagedata)
|
||||
{
|
||||
iconblob = BZ_Malloc(sizeof(*iconblob)*(2+imagewidth*imageheight));
|
||||
iconblob[0] = imagewidth;
|
||||
iconblob[1] = imageheight;
|
||||
//needs to be 0xARGB, rather than RGBA bytes
|
||||
|
@ -3510,8 +3514,10 @@ static void X_StoreIcon(Window wnd)
|
|||
|
||||
x11.pXChangeProperty(vid_dpy, wnd, propname, proptype, 32, PropModeReplace, (void*)iconblob, 2+imagewidth*imageheight);
|
||||
BZ_Free(iconblob);
|
||||
return;
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
{
|
||||
//fall back to the embedded icon.
|
||||
unsigned long data[64*64+2];
|
||||
|
|
|
@ -429,7 +429,6 @@ r_part te_teleport
|
|||
}
|
||||
#endif
|
||||
#ifdef FRAGMENT_SHADER
|
||||
uniform sampler2D s_t0;
|
||||
void main(void)
|
||||
{
|
||||
vec2 nst;
|
||||
|
|
|
@ -180,6 +180,8 @@ void PDECL PR_GenerateStatementString (pubprogfuncs_t *ppf, int statementnum, ch
|
|||
*out = 0;
|
||||
outlen--;
|
||||
|
||||
if ((unsigned)statementnum >= current_progstate->progs->numstatements)
|
||||
return;
|
||||
switch(current_progstate->structtype)
|
||||
{
|
||||
case PST_DEFAULT:
|
||||
|
@ -1364,7 +1366,7 @@ static const char *lastfile = NULL;
|
|||
lastfile = file;
|
||||
|
||||
faultline = lastline;
|
||||
debugaction = externs->useeditor(&progfuncs->funcs, lastfile, ((lastline!=-1)?&lastline:NULL), &statement, fault, fatal);
|
||||
debugaction = externs->useeditor(&progfuncs->funcs, lastfile, ((lastline!=-1)?&lastline:NULL), &statement, f->first_statement, fault, fatal);
|
||||
|
||||
// if (pn != prinst.pr_typecurrent)
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ typedef struct progexterns_s {
|
|||
void *(VARGS *memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use malloc if you want)
|
||||
void (VARGS *memfree) (void * mem);
|
||||
|
||||
int (PDECL *useeditor) (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, char *reason, pbool fatal); //called on syntax errors or step-by-step debugging. line and statement(if line was set to 0) can be used to change the next line. return value is the new debug state to use/step.
|
||||
int (PDECL *useeditor) (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, int funcstart, char *reason, pbool fatal); //called on syntax errors or step-by-step debugging. line and statement(if line was set to 0) can be used to change the next line. return value is the new debug state to use/step.
|
||||
void (PDECL *addressablerelocated) (pubprogfuncs_t *progfuncs, char *oldb, char *newb, int oldlen); //called when the progs memory was resized. you must fix up all pointers to globals, strings, fields, addressable blocks.
|
||||
|
||||
builtin_t *globalbuiltins; //these are available to all progs
|
||||
|
|
|
@ -562,7 +562,7 @@ public:
|
|||
s->SendScintilla(QsciScintillaBase::SCI_STYLESETBACK, QsciScintillaBase::STYLE_BRACEBAD, QColor(0xff, 0xaf, 0xaf));
|
||||
|
||||
//SCE_C_WORD
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, static_cast<int>(0),
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 0ul,
|
||||
"if else for do not while asm break case const continue "
|
||||
"default enum enumflags extern "
|
||||
"float goto __in __out __inout noref "
|
||||
|
@ -578,11 +578,11 @@ public:
|
|||
{
|
||||
char buffer[65536];
|
||||
GenBuiltinsList(buffer, sizeof(buffer));
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 1, buffer);
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 1ul, buffer);
|
||||
}
|
||||
//SCE_C_COMMENTDOCKEYWORDERROR
|
||||
//SCE_C_GLOBALCLASS
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 3,
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 3ul,
|
||||
""
|
||||
);
|
||||
//preprocessor listing
|
||||
|
@ -590,11 +590,11 @@ public:
|
|||
char *deflist = QCC_PR_GetDefinesList();
|
||||
if (!deflist)
|
||||
deflist = strdup("");
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 4, deflist);
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 4ul, deflist);
|
||||
free(deflist);
|
||||
}
|
||||
//task markers (in comments only)
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 5,
|
||||
s->SendScintilla(QsciScintillaBase::SCI_SETKEYWORDS, 5ul,
|
||||
"TODO FIXME BUG"
|
||||
);
|
||||
|
||||
|
|
|
@ -202,6 +202,9 @@ typedef struct botlib_import_s
|
|||
//
|
||||
int (QDECL *DebugPolygonCreate)(int color, int numPoints, vec3_t *points);
|
||||
void (QDECL *DebugPolygonDelete)(int id);
|
||||
|
||||
//FTE additions...
|
||||
void (QDECL *Error)(const char *error);
|
||||
} botlib_import_t;
|
||||
|
||||
typedef struct aas_export_s
|
||||
|
|
|
@ -10874,7 +10874,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
//312
|
||||
//313
|
||||
//2d (immediate) operations
|
||||
{"drawtextfield", PF_Fixme, 0, 0, 0, 0/*314*/, D("void(vector pos, vector size, float alignflags, string text)", "Draws a multi-line block of text, including word wrapping and alignment. alignflags bits are RTLB, typically 3.")},// (EXT_CSQC)
|
||||
{"drawtextfield", PF_Fixme, 0, 0, 0, 0/*314*/, D("float(vector pos, vector size, float alignflags, string text)", "Draws a multi-line block of text, including word wrapping and alignment. alignflags bits are RTLB, typically 3. Returns the total number of lines.")},// (EXT_CSQC)
|
||||
{"drawline", PF_Fixme, 0, 0, 0, 315, D("void(float width, vector pos1, vector pos2, vector rgb, float alpha, optional float drawflag)", "Draws a 2d line between the two 2d points.")},// (EXT_CSQC)
|
||||
{"iscachedpic", PF_Fixme, 0, 0, 0, 316, D("float(string name)", "Checks to see if the image is currently loaded. Engines might lie, or cache between maps.")},// (EXT_CSQC)
|
||||
{"precache_pic", PF_Fixme, 0, 0, 0, 317, D("string(string name, optional float trywad)", "Forces the engine to load the named image. If trywad is specified, the specified name must any lack path and extension.")},// (EXT_CSQC)
|
||||
|
|
|
@ -1772,19 +1772,49 @@ qboolean SV_Loadgame (const char *unsafe_savename)
|
|||
#ifndef QUAKETC
|
||||
{"%s.sav"},
|
||||
#endif
|
||||
{"%s"}
|
||||
};
|
||||
int bd,best;
|
||||
int bestd=0x7fffffff,best=0;
|
||||
time_t bestt=0,t;
|
||||
|
||||
Q_strncpyz(savename, unsafe_savename, sizeof(savename));
|
||||
if (!*savename || strstr(savename, ".."))
|
||||
strcpy(savename, "quick");
|
||||
{ //if no args, or its invalid, try to pick the last one that was saved (of those listed in the menu)
|
||||
size_t n;
|
||||
static char *autoload[] = { "quick", "a0", "a1", "a2",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9"};
|
||||
strcpy(savename, "quick"); //default...
|
||||
|
||||
for (len = 0, bd=0x7fffffff,best=0; len < countof(savefiles); len++)
|
||||
for (n = 0; n < countof(autoload); n++)
|
||||
{
|
||||
int d = FS_FLocateFile(va(savefiles[len].pattern, savename), FSLF_DONTREFERENCE|FSLF_DEEPONFAILURE, &savefiles[len].loc);
|
||||
if (bd > d)
|
||||
for (len = 0; len < countof(savefiles)-1; len++)
|
||||
{
|
||||
bd = d;
|
||||
int d = FS_FLocateFile(va(savefiles[len].pattern, autoload[n]), FSLF_DONTREFERENCE, &savefiles[len].loc);
|
||||
if (!d)
|
||||
continue;
|
||||
FS_GetLocMTime(&savefiles[len].loc, &t);
|
||||
if (d < bestd || (bestd==d&&t>bestt))
|
||||
{
|
||||
bestd = d;
|
||||
bestt = t;
|
||||
best = len;
|
||||
|
||||
strcpy(savename, autoload[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (len = 0; len < countof(savefiles); len++)
|
||||
{
|
||||
int d = FS_FLocateFile(va(savefiles[len].pattern, savename), FSLF_DONTREFERENCE, &savefiles[len].loc);
|
||||
if (!d)
|
||||
continue;
|
||||
FS_GetLocMTime(&savefiles[len].loc, &t);
|
||||
if (d < bestd || (bestd==d&&t>bestt))
|
||||
{
|
||||
bestd = d;
|
||||
bestt = t;
|
||||
best = len;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -576,12 +576,14 @@ typedef struct client_s
|
|||
|
||||
#ifdef Q3SERVER
|
||||
int gamestatesequence; //the sequence number the initial gamestate was sent in.
|
||||
int last_server_command_num;
|
||||
|
||||
int last_client_command_num;
|
||||
int num_server_commands;
|
||||
int num_client_commands;
|
||||
char server_commands[64][1024];
|
||||
char last_client_command[1024];
|
||||
|
||||
//quake3 does reliables only via this mechanism. basically just like q1's stuffcmds.
|
||||
int server_command_ack; //number known to have been received.
|
||||
int server_command_sequence; //number available.
|
||||
char server_commands[64][1024]; //the commands, to deal with resends
|
||||
#endif
|
||||
|
||||
//true/false/persist
|
||||
|
|
|
@ -779,12 +779,14 @@ void SV_Map_f (void)
|
|||
// gametype->callback = gtcallback;
|
||||
|
||||
/* map_restart doesn't need to handle gametype changes - eukara */
|
||||
if (Q_strcasecmp(Cmd_Argv(0), "map_restart"))
|
||||
if (!isrestart)
|
||||
{
|
||||
if (q3singleplayer)
|
||||
Cvar_ForceSet(gametype, "2");//singleplayer
|
||||
else if (gametype->value == 2)
|
||||
Cvar_ForceSet(gametype, "");//force to ffa deathmatch
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MENU_DAT) && !defined(SERVERONLY)
|
||||
|
|
|
@ -1480,13 +1480,15 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
outno = 0;
|
||||
outmax = frame->maxresend;
|
||||
|
||||
if (msg->cursize + 52 <= msg->maxsize)
|
||||
{
|
||||
/*start writing the packet*/
|
||||
MSG_WriteByte (msg, svcfte_updateentities);
|
||||
if (ISNQCLIENT(client) && (client->fteprotocolextensions2 & PEXT2_PREDINFO))
|
||||
{
|
||||
MSG_WriteShort(msg, client->last_sequence&0xffff);
|
||||
}
|
||||
// Con_Printf("Gen sequence %i\n", sequence);
|
||||
// Con_Printf("Gen sequence %i\n", sequence);
|
||||
MSG_WriteFloat(msg, sv.world.physicstime);
|
||||
|
||||
if (client->pendingdeltabits[0] & UF_REMOVE)
|
||||
|
@ -1503,7 +1505,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
bits = client->pendingdeltabits[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)*/
|
||||
continue;
|
||||
if (msg->cursize + 50 > msg->maxsize)
|
||||
if (msg->cursize + 52 > msg->maxsize)
|
||||
{
|
||||
overflow = true;
|
||||
break; /*give up if it gets full. FIXME: bone data is HUGE.*/
|
||||
|
@ -1518,7 +1520,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
{ //if reset is set, then reset was set eroneously.
|
||||
SV_EmitDeltaEntIndex(msg, j, true, true);
|
||||
resend[outno].bits = UF_REMOVE;
|
||||
// Con_Printf("REMOVE %i @ %i\n", j, sequence);
|
||||
// Con_Printf("REMOVE %i @ %i\n", j, sequence);
|
||||
}
|
||||
else if (client->sentents.entities[j].number) /*only send a new copy of the ent if they actually have one already*/
|
||||
{
|
||||
|
@ -1532,7 +1534,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
/*if reset2, then this is the second packet sent to the client and should have a forced reset (but which isn't tracked)*/
|
||||
resend[outno].bits = bits & ~UF_RESET2;
|
||||
bits = UF_RESET | SVFTE_DeltaCalcBits(&EDICT_NUM_PB(svprogfuncs, j)->baseline, NULL, &client->sentents.entities[j], client->sentents.bonedata);
|
||||
// Con_Printf("RESET2 %i @ %i\n", j, sequence);
|
||||
// Con_Printf("RESET2 %i @ %i\n", j, sequence);
|
||||
}
|
||||
else if (bits & UF_RESET)
|
||||
{
|
||||
|
@ -1540,7 +1542,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
client->pendingdeltabits[j] = UF_RESET2;
|
||||
bits = UF_RESET | SVFTE_DeltaCalcBits(&EDICT_NUM_PB(svprogfuncs, j)->baseline, NULL, &client->sentents.entities[j], client->sentents.bonedata);
|
||||
resend[outno].bits = UF_RESET;
|
||||
// Con_Printf("RESET %i @ %i\n", j, sequence);
|
||||
// Con_Printf("RESET %i @ %i\n", j, sequence);
|
||||
}
|
||||
else
|
||||
resend[outno].bits = bits;
|
||||
|
@ -1555,6 +1557,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
resend[outno++].entnum = j;
|
||||
}
|
||||
MSG_WriteShort(msg, 0);
|
||||
}
|
||||
|
||||
if (j == client->sentents.num_entities) //looks like we sent them all
|
||||
client->nextdeltaindex = 0; //start afresh with the next packet.
|
||||
|
|
|
@ -61,6 +61,7 @@ cvar_t sv_gameplayfix_bouncedownslopes = CVARD( "sv_gameplayfix_grenadebouncedo
|
|||
#if !defined(CLIENTONLY) && defined(NQPROT) && !defined(NOLEGACY)
|
||||
cvar_t sv_gameplayfix_spawnbeforethinks = CVARD( "sv_gameplayfix_spawnbeforethinks", "0", "Fixes an issue where player thinks (including Pre+Post) can be called before PutClientInServer. Unfortunately at least one mod depends upon PreThink being called first in order to correctly determine spawn positions.");
|
||||
#endif
|
||||
cvar_t dpcompat_noretouchground = CVARD( "dpcompat_noretouchground", "0", "Prevents entities that are already standing on an entity from touching the same entity again.");
|
||||
cvar_t sv_sound_watersplash = CVAR( "sv_sound_watersplash", "misc/h2ohit1.wav");
|
||||
cvar_t sv_sound_land = CVAR( "sv_sound_land", "demon/dland2.wav");
|
||||
cvar_t sv_stepheight = CVARAFD("pm_stepheight", "", "sv_stepheight", CVAR_SERVERINFO, "If empty, the value "STRINGIFY(PM_DEFAULTSTEPHEIGHT)" will be used instead. This is the size of the step you can step up or down.");
|
||||
|
@ -98,6 +99,7 @@ void WPhys_Init(void)
|
|||
Cvar_Register (&sv_gameplayfix_multiplethinks, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_gameplayfix_stepdown, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_gameplayfix_bouncedownslopes, cvargroup_serverphysics);
|
||||
Cvar_Register (&dpcompat_noretouchground, cvargroup_serverphysics);
|
||||
|
||||
#if !defined(CLIENTONLY) && defined(NQPROT) && !defined(NOLEGACY)
|
||||
Cvar_Register (&sv_gameplayfix_spawnbeforethinks, cvargroup_serverphysics);
|
||||
|
@ -450,6 +452,12 @@ static int WPhys_FlyMove (world_t *w, wedict_t *ent, const vec3_t gravitydir, fl
|
|||
if (!trace.ent)
|
||||
Host_Error ("SV_FlyMove: !trace.ent");
|
||||
|
||||
if (dpcompat_noretouchground.ival)
|
||||
{ //note: also sets onground AFTER the touch event.
|
||||
if (!((int)ent->v->flags&FL_ONGROUND) || ent->v->groundentity!=EDICT_TO_PROG(w->progs, trace.ent))
|
||||
WPhys_Impact (w, ent, &trace);
|
||||
}
|
||||
|
||||
if (-DotProduct(gravitydir, trace.plane.normal) > 0.7)
|
||||
{
|
||||
blocked |= 1; // floor
|
||||
|
@ -469,6 +477,7 @@ static int WPhys_FlyMove (world_t *w, wedict_t *ent, const vec3_t gravitydir, fl
|
|||
//
|
||||
// run the impact function
|
||||
//
|
||||
if (!dpcompat_noretouchground.ival)
|
||||
WPhys_Impact (w, ent, &trace);
|
||||
if (ED_ISFREE(ent))
|
||||
break; // removed by the impact function
|
||||
|
|
|
@ -2566,7 +2566,12 @@ qboolean SV_SendClientDatagram (client_t *client)
|
|||
}
|
||||
|
||||
if (client->netchan.fragmentsize)
|
||||
{
|
||||
if (client->netchan.remote_address.type == NA_LOOPBACK)
|
||||
clientlimit = countof(buf); //biiiig...
|
||||
else
|
||||
clientlimit = client->netchan.fragmentsize; //try not to overflow
|
||||
}
|
||||
else if (client->protocol == SCP_NETQUAKE)
|
||||
clientlimit = MAX_NQDATAGRAM; //vanilla client is limited.
|
||||
else
|
||||
|
@ -2574,6 +2579,8 @@ qboolean SV_SendClientDatagram (client_t *client)
|
|||
if (clientlimit > countof(buf))
|
||||
clientlimit = countof(buf);
|
||||
msg.maxsize = clientlimit - client->datagram.cursize;
|
||||
if (msg.maxsize <= 0)
|
||||
msg.maxsize = clientlimit; //its going to overflow. favour ents over unreliables. its a little less fatal
|
||||
|
||||
if (sv.world.worldmodel && !client->controller)
|
||||
{
|
||||
|
|
|
@ -34,6 +34,9 @@ static botlib_export_t *FTE_GetBotLibAPI(int apiVersion, botlib_import_t *import
|
|||
{(void**)&pGetBotLibAPI, "GetBotLibAPI"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
if (!botlib && host_parms.binarydir)
|
||||
botlib = Sys_LoadLibrary(va("%slibfteq3bot", host_parms.binarydir), funcs);
|
||||
if (!botlib)
|
||||
botlib = Sys_LoadLibrary("botlib", funcs);
|
||||
if (!botlib)
|
||||
|
@ -764,8 +767,8 @@ void SVQ3_SendServerCommand(client_t *cl, char *str)
|
|||
return;
|
||||
}
|
||||
|
||||
cl->num_server_commands++;
|
||||
Q_strncpyz(cl->server_commands[cl->num_server_commands & TEXTCMD_MASK], str, sizeof(cl->server_commands[0]));
|
||||
cl->server_command_sequence++;
|
||||
Q_strncpyz(cl->server_commands[cl->server_command_sequence & TEXTCMD_MASK], str, sizeof(cl->server_commands[0]));
|
||||
}
|
||||
|
||||
void SVQ3_SendConfigString(client_t *dest, int num, char *string)
|
||||
|
@ -832,11 +835,11 @@ static int SVQ3_BotGetConsoleMessage( int client, char *buf, int size )
|
|||
cl = &svs.clients[client];
|
||||
// cl->lastPacketTime = svs.time;
|
||||
|
||||
if (cl->last_server_command_num == cl->num_server_commands)
|
||||
if (cl->server_command_ack == cl->server_command_sequence)
|
||||
return false;
|
||||
|
||||
cl->last_server_command_num++;
|
||||
index = cl->last_server_command_num & TEXTCMD_MASK;
|
||||
cl->server_command_ack++;
|
||||
index = cl->server_command_ack & TEXTCMD_MASK;
|
||||
|
||||
if ( !cl->server_commands[index][0] )
|
||||
return false;
|
||||
|
@ -1804,6 +1807,10 @@ static void QDECL BL_DebugLineShow(int line, vec3_t start, vec3_t end, int color
|
|||
static int QDECL BL_DebugPolygonCreate(int color, int numPoints, vec3_t *points) {return 0;}
|
||||
static void QDECL BL_DebugPolygonDelete(int id) {}
|
||||
|
||||
void QDECL BL_Error(const char *msg)
|
||||
{
|
||||
Sys_Error("%s", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SV_InitBotLib(void)
|
||||
|
@ -1840,6 +1847,8 @@ static void SV_InitBotLib(void)
|
|||
import.DebugPolygonCreate= BL_DebugPolygonCreate;
|
||||
import.DebugPolygonDelete = BL_DebugPolygonDelete;
|
||||
|
||||
import.Error = BL_Error;
|
||||
|
||||
// Z_FreeTags(Z_TAG_BOTLIB);
|
||||
botlibmemoryavailable = 1024*1024*16;
|
||||
if (bot_enable->value)
|
||||
|
@ -2690,6 +2699,23 @@ static void SVQ3Q1_SendGamestateConfigstrings(sizebuf_t *msg)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void SVQ3_WriteServerCommandsToClient(client_t *client, sizebuf_t *msg)
|
||||
{
|
||||
int i;
|
||||
int j, len;
|
||||
char *str;
|
||||
|
||||
for(i=client->server_command_ack+1; i<=client->server_command_sequence; i++)
|
||||
{
|
||||
MSG_WriteBits(msg, svcq3_serverCommand, 8);
|
||||
MSG_WriteBits(msg, i, 32);
|
||||
str = client->server_commands[i & TEXTCMD_MASK];
|
||||
len = strlen(str);
|
||||
for (j = 0; j <= len; j++)
|
||||
MSG_WriteBits(msg, str[j], 8);
|
||||
}
|
||||
}
|
||||
|
||||
//writes initial gamestate
|
||||
void SVQ3_SendGameState(client_t *client)
|
||||
{
|
||||
|
@ -2709,8 +2735,10 @@ void SVQ3_SendGameState(client_t *client)
|
|||
// write last clientCommand number we have processed
|
||||
MSG_WriteBits(&msg, client->last_client_command_num, 32);
|
||||
|
||||
SVQ3_WriteServerCommandsToClient(client, &msg);
|
||||
|
||||
MSG_WriteBits(&msg, svcq3_gamestate, 8 );
|
||||
MSG_WriteBits(&msg, client->num_client_commands, 32);
|
||||
MSG_WriteBits(&msg, client->server_command_sequence, 32);
|
||||
|
||||
switch (svs.gametype)
|
||||
{
|
||||
|
@ -2781,23 +2809,6 @@ void SVQ3_SendGameState(client_t *client)
|
|||
client->gamestatesequence = client->last_sequence;
|
||||
}
|
||||
|
||||
void SVQ3_WriteServerCommandsToClient(client_t *client, sizebuf_t *msg)
|
||||
{
|
||||
int i;
|
||||
int j, len;
|
||||
char *str;
|
||||
|
||||
for(i=client->last_server_command_num+1; i<=client->num_server_commands; i++)
|
||||
{
|
||||
MSG_WriteBits(msg, svcq3_serverCommand, 8);
|
||||
MSG_WriteBits(msg, i, 32);
|
||||
str = client->server_commands[i & TEXTCMD_MASK];
|
||||
len = strlen(str);
|
||||
for (j = 0; j <= len; j++)
|
||||
MSG_WriteBits(msg, str[j], 8);
|
||||
}
|
||||
}
|
||||
|
||||
void SVQ3_SendMessage(client_t *client)
|
||||
{
|
||||
qbyte buffer[MAX_OVERALLMSGLEN];
|
||||
|
@ -2992,7 +3003,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
|
|||
return; // was dropped
|
||||
|
||||
// calculate key for usercmd decryption
|
||||
string = client->server_commands[client->last_server_command_num & TEXTCMD_MASK];
|
||||
string = client->server_commands[client->server_command_ack & TEXTCMD_MASK];
|
||||
key = client->last_sequence ^ fs_key ^ StringKey(string, 32);
|
||||
|
||||
// read delta sequenced usercmds
|
||||
|
@ -3207,11 +3218,11 @@ void SVQ3_ParseClientMessage(client_t *client)
|
|||
}
|
||||
|
||||
// read last server command number client received
|
||||
client->last_server_command_num = MSG_ReadBits(32);
|
||||
if( client->last_server_command_num <= client->num_server_commands - TEXTCMD_BACKUP )
|
||||
client->last_server_command_num = client->num_server_commands - TEXTCMD_BACKUP + 1;
|
||||
else if( client->last_server_command_num > client->num_server_commands )
|
||||
client->last_server_command_num = client->num_server_commands;
|
||||
client->server_command_ack = MSG_ReadBits(32);
|
||||
if( client->server_command_ack <= client->server_command_sequence - TEXTCMD_BACKUP )
|
||||
client->server_command_ack = client->server_command_sequence - TEXTCMD_BACKUP + 1; //too old
|
||||
else if( client->server_command_ack > client->server_command_sequence )
|
||||
client->server_command_ack = client->server_command_sequence; //client is from the future? o.O make fatal?
|
||||
|
||||
// check if message is from a previous level
|
||||
if( serverid != svs.spawncount )
|
||||
|
@ -3243,7 +3254,7 @@ void SVQ3_ParseClientMessage(client_t *client)
|
|||
|
||||
if(msg_readcount > net_message.cursize)
|
||||
{
|
||||
Con_Printf("corrupted packet from %s\n", client->name);
|
||||
Con_Printf("corrupt packet from %s\n", client->name);
|
||||
client->drop = true;
|
||||
return;
|
||||
}
|
||||
|
@ -3257,7 +3268,7 @@ void SVQ3_ParseClientMessage(client_t *client)
|
|||
switch(c)
|
||||
{
|
||||
default:
|
||||
Con_Printf("corrupted packet from %s\n", client->name);
|
||||
Con_Printf("corrupt packet from %s\n", client->name);
|
||||
client->drop = true;
|
||||
return;
|
||||
case clcq3_nop:
|
||||
|
|
Loading…
Reference in a new issue