misc hexen2 compat fixes. added/improved most missing particle effects in some form.

hopefully this won't break quake too much.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4638 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-04-12 03:31:59 +00:00
parent 5be72a87b8
commit faeb62f4ee
29 changed files with 1657 additions and 359 deletions

View File

@ -192,6 +192,7 @@ extern cvar_t scr_showpause;
extern cvar_t scr_printspeed;
extern cvar_t scr_allowsnap;
extern cvar_t scr_sshot_type;
extern cvar_t scr_sshot_prefix;
extern cvar_t scr_sshot_compression;
extern cvar_t crosshair;
extern cvar_t scr_consize;
@ -1934,7 +1935,7 @@ SCR_ScreenShot_f
void SCR_ScreenShot_f (void)
{
char sysname[1024];
char pcxname[80];
char pcxname[MAX_QPATH];
int i;
vfsfile_t *vfs;
void *rgbbuffer;
@ -1958,23 +1959,22 @@ void SCR_ScreenShot_f (void)
}
else
{
int stop = 1000;
char date[MAX_QPATH];
time_t tm = time(NULL);
strftime(date, sizeof(date), "%Y%m%d%H%M%S", localtime(&tm));
//
// find a file name to save it to
//
Q_snprintfz(pcxname, sizeof(pcxname), "screenshots/fte00000.%s", scr_sshot_type.string);
for (i=0 ; i<=100000 ; i++)
for (i=0 ; i<stop ; i++)
{
pcxname[16] = (i%10000)/1000 + '0';
pcxname[17] = (i%1000)/100 + '0';
pcxname[18] = (i%100)/10 + '0';
pcxname[19] = (i%10) + '0';
Q_snprintfz(pcxname, sizeof(pcxname), "%s-%s-%i.%s", scr_sshot_prefix.string, date, i, scr_sshot_type.string);
if (!(vfs = FS_OpenVFS(pcxname, "rb", FS_GAMEONLY)))
break; // file doesn't exist
VFS_CLOSE(vfs);
}
if (i==100000)
if (i==stop)
{
Con_Printf ("SCR_ScreenShot_f: Couldn't create sequentially named file\n");
return;

View File

@ -204,11 +204,14 @@ typedef struct
vec3_t avel;
int flags;
float gravity;
float alpha;
float startalpha;
float endalpha;
float start;
float framerate;
model_t *model;
int skinnum;
int traileffect;
trailstate_t *trailstate;
} explosion_t;
explosion_t *cl_explosions;
@ -517,29 +520,11 @@ int CLQ2_RegisterTEntModels (void)
return true;
}
#endif
/*
=================
CL_ClearTEnts
=================
*/
void CL_ClearTEnts (void)
{
CL_ClearTEntParticleState();
CL_ShutdownTEnts();
cl_beams_max = 0;
BZ_Free(cl_beams);
cl_beams = NULL;
beams_running = 0;
cl_explosions_max = 0;
BZ_Free(cl_explosions);
cl_explosions = NULL;
explosions_running = 0;
}
static void CL_ClearExplosion(explosion_t *exp)
static void CL_ClearExplosion(explosion_t *exp, vec3_t org)
{
exp->endalpha = 0;
exp->startalpha = 1;
exp->gravity = 0;
exp->flags = 0;
exp->model = NULL;
@ -548,6 +533,34 @@ static void CL_ClearExplosion(explosion_t *exp)
VectorClear(exp->velocity);
VectorClear(exp->angles);
VectorClear(exp->avel);
P_DelinkTrailstate(&(exp->trailstate));
exp->traileffect = P_INVALID;
VectorCopy(org, exp->origin);
VectorCopy(org, exp->oldorigin);
}
/*
=================
CL_ClearTEnts
=================
*/
void CL_ClearTEnts (void)
{
int i;
CL_ClearTEntParticleState();
CL_ShutdownTEnts();
cl_beams_max = 0;
BZ_Free(cl_beams);
cl_beams = NULL;
beams_running = 0;
for (i = 0; i < cl_explosions_max; i++)
CL_ClearExplosion(cl_explosions+i, vec3_origin);
cl_explosions_max = 0;
BZ_Free(cl_explosions);
cl_explosions = NULL;
explosions_running = 0;
}
/*
@ -555,7 +568,7 @@ static void CL_ClearExplosion(explosion_t *exp)
CL_AllocExplosion
=================
*/
explosion_t *CL_AllocExplosion (void)
explosion_t *CL_AllocExplosion (vec3_t org)
{
int i;
float time;
@ -565,7 +578,7 @@ explosion_t *CL_AllocExplosion (void)
{
if (!cl_explosions[i].model)
{
CL_ClearExplosion(&cl_explosions[i]);
CL_ClearExplosion(&cl_explosions[i], org);
return &cl_explosions[i];
}
}
@ -576,10 +589,11 @@ explosion_t *CL_AllocExplosion (void)
{
cl_explosions_max = (i+1)*2;
cl_explosions = BZ_Realloc(cl_explosions, sizeof(*cl_explosions)*cl_explosions_max);
memset(cl_explosions + i, 0, sizeof(*cl_explosions)*(cl_explosions_max-i));
}
explosions_running++;
CL_ClearExplosion(&cl_explosions[i]);
CL_ClearExplosion(&cl_explosions[i], org);
return &cl_explosions[i];
}
@ -593,7 +607,7 @@ explosion_t *CL_AllocExplosion (void)
time = cl_explosions[i].start;
index = i;
}
CL_ClearExplosion(&cl_explosions[index]);
CL_ClearExplosion(&cl_explosions[index], org);
return &cl_explosions[index];
}
@ -922,6 +936,10 @@ void CL_ParseStream (int type)
b->model = Mod_ForName("models/fambeam.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_famine");
break;
case TEH2_STREAM_CHAIN:
b->model = Mod_ForName("models/stchain.mdl", MLV_WARN);
b->particleeffect = P_FindParticleType("te_stream_chain");
break;
default:
Con_Printf("CL_ParseStream: type %i\n", type);
break;
@ -1191,10 +1209,10 @@ void CL_ParseTEnt (void)
// sprite
if (cl_expsprite.ival) // temp hopefully
{
explosion_t *ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
explosion_t *ex = CL_AllocExplosion (pos);
ex->start = cl.time;
ex->model = Mod_ForName ("progs/s_explod.spr", MLV_WARN);
ex->endalpha = ex->startalpha; //don't fade out
}
break;
case TE_EXPLOSION: // rocket explosion
@ -1231,8 +1249,7 @@ void CL_ParseTEnt (void)
// sprite
if (cl_expsprite.ival && !nqprot) // temp hopefully
{
explosion_t *ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
explosion_t *ex = CL_AllocExplosion (pos);
ex->start = cl.time;
ex->model = Mod_ForName ("progs/s_explod.spr", MLV_WARN);
}
@ -2141,25 +2158,29 @@ void CL_ParseParticleEffect4 (void)
P_RunParticleEffect4 (org, radius, color, effect, msgcount);
}
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity)
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity, int traileffect)
{
explosion_t *ex;
vec3_t spos;
float dlen;
ex = CL_AllocExplosion ();
VectorCopy (org, ex->origin);
ex = CL_AllocExplosion (org);
ex->start = cl.time;
ex->model = model;
ex->firstframe = startframe;
ex->numframes = framecount;
ex->framerate = framerate;
ex->alpha = alpha;
ex->skinnum = 0;
ex->traileffect = traileffect;
if (model->type == mod_alias)
if (alpha >= -1 && alpha < 1)
ex->flags |= RF_TRANSLUCENT;
//sprites always use a fixed alpha. models can too if the alpha is < 0
if (model->type == mod_sprite || alpha < 0)
ex->endalpha = fabs(alpha);
ex->startalpha = fabs(alpha);
if (randspin)
{
ex->angles[0] = frandom()*360;
@ -2192,6 +2213,7 @@ void CL_ParseEffect (qboolean effect2)
int startframe;
int framecount;
int framerate;
model_t *mod;
org[0] = MSG_ReadCoord();
org[1] = MSG_ReadCoord();
@ -2210,8 +2232,8 @@ void CL_ParseEffect (qboolean effect2)
framecount = MSG_ReadByte();
framerate = MSG_ReadByte();
CL_SpawnSpriteEffect(org, vec3_origin, cl.model_precache[modelindex], startframe, framecount, framerate, 1, 0, 0);
mod = cl.model_precache[modelindex];
CL_SpawnSpriteEffect(org, vec3_origin, mod, startframe, framecount, framerate, mod->type==mod_sprite?-1:1, 0, 0, P_INVALID);
}
#ifdef Q2CLIENT
@ -2219,18 +2241,15 @@ void CL_SmokeAndFlash(vec3_t origin)
{
explosion_t *ex;
ex = CL_AllocExplosion ();
VectorCopy (origin, ex->origin);
ex = CL_AllocExplosion (origin);
VectorClear(ex->angles);
// ex->type = ex_misc;
ex->numframes = 4;
ex->flags = RF_TRANSLUCENT;
ex->alpha = 1;
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_smoke].modelname, MLV_WARN);
ex = CL_AllocExplosion ();
VectorCopy (origin, ex->origin);
ex = CL_AllocExplosion (origin);
VectorClear(ex->angles);
// ex->type = ex_flash;
ex->flags = Q2RF_FULLBRIGHT;
@ -2241,10 +2260,11 @@ void CL_SmokeAndFlash(vec3_t origin)
void CL_Laser (vec3_t start, vec3_t end, int colors)
{
explosion_t *ex = CL_AllocExplosion();
explosion_t *ex = CL_AllocExplosion(start);
ex->firstframe = 0;
ex->numframes = 10;
ex->alpha = 0.33f;
ex->startalpha = 0.33f;
ex->endalpha = 0;
ex->model = NULL;
ex->skinnum = (colors >> ((rand() % 4)*8)) & 0xff;
VectorCopy (start, ex->origin);
@ -2394,14 +2414,12 @@ void CLQ2_ParseTEnt (void)
if (cl_legacystains.ival) Surf_AddStain(pos, 0, -5, -10, 20);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, MLV_WARN);
ex->firstframe = 0;
ex->numframes = 4;
ex->flags = Q2RF_FULLBRIGHT|RF_ADDITIVE|RF_NOSHADOW|RF_TRANSLUCENT;
ex->alpha = 1;
ex->angles[0] = acos(dir[2])/M_PI*180;
// PMM - fixed to correct for pitch of 0
@ -2481,13 +2499,11 @@ void CLQ2_ParseTEnt (void)
// if (!R_ParticleExplosionHeart(pos))
{
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
VectorClear(ex->angles);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, MLV_WARN);
ex->firstframe = 30;
ex->alpha = 1;
ex->flags |= RF_TRANSLUCENT;
ex->numframes = 19;
}
@ -2576,12 +2592,10 @@ void CLQ2_ParseTEnt (void)
// sprite
// if (!R_ParticleExplosionHeart(pos))
{
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
VectorClear(ex->angles);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, MLV_WARN);
ex->alpha = 1;
ex->flags |= RF_TRANSLUCENT;
if (rand()&1)
ex->firstframe = 15;
@ -2725,8 +2739,7 @@ void CLQ2_ParseTEnt (void)
if (cl_legacystains.ival) Surf_AddStain(pos, -10, 0, -10, 20);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, MLV_WARN);
ex->firstframe = 0;
@ -2775,8 +2788,7 @@ void CLQ2_ParseTEnt (void)
if (cl_legacystains.ival) Surf_AddStain(pos, -10, -2, 0, 20);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
ex->start = cl.time;
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, MLV_WARN);
ex->firstframe = 0;
@ -2831,8 +2843,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_PLAIN_EXPLOSION:
MSG_ReadPos (pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
// ex->type = ex_poly;
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
ex->angles[1] = rand() % 360;
@ -3019,8 +3030,7 @@ void CLQ2_ParseTEnt (void)
Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type);
case CRTE_BLASTER_MUZZLEFLASH:
MSG_ReadPos (pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
ex->start = cl.q2frame.servertime - 100;
CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0.1, 0);
@ -3028,8 +3038,7 @@ void CLQ2_ParseTEnt (void)
break;
case CRTE_BLUE_MUZZLEFLASH:
MSG_ReadPos (pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
ex->start = cl.q2frame.servertime - 100;
CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0.1, 0);
@ -3037,8 +3046,7 @@ void CLQ2_ParseTEnt (void)
break;
case CRTE_SMART_MUZZLEFLASH:
MSG_ReadPos (pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin);
ex = CL_AllocExplosion (pos);
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
ex->start = cl.q2frame.servertime - 100;
CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0, 0.2);
@ -3048,7 +3056,7 @@ void CLQ2_ParseTEnt (void)
Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type);
case CRTE_DEATHFIELD:
MSG_ReadPos (pos);
ex = CL_AllocExplosion ();
ex = CL_AllocExplosion (pos);
VectorCopy (pos, ex->origin);
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
ex->start = cl.q2frame.servertime - 100;
@ -3330,6 +3338,7 @@ void CL_UpdateExplosions (void)
int lastrunningexplosion = -1;
vec3_t pos, norm;
static float oldtime;
float scale;
float frametime = cl.time - oldtime;
if (frametime < 0 || frametime > 100)
frametime = 0;
@ -3354,12 +3363,20 @@ void CL_UpdateExplosions (void)
}
of = (int)f-1;
if ((int)f >= numframes || (int)f < 0)
if (ex->endalpha && (int)f == numframes)
{
scale = 1-(f-(int)f); //if we have endalpha not 0, then there is a final 'bonus' frame where the model scales down to 0. use numframes+framerate to control how fast it fades.
f = of; //clamp it to the old frame
}
else if ((int)f >= numframes || (int)f < 0)
{
ex->model = NULL;
ex->flags = 0;
P_DelinkTrailstate(&(ex->trailstate));
continue;
}
else
scale = 1;
if (of < 0)
of = 0;
@ -3407,12 +3424,15 @@ void CL_UpdateExplosions (void)
ent->framestate.g[FS_REG].frame[1] = (int)f+firstframe;
ent->framestate.g[FS_REG].frame[0] = of+firstframe;
ent->framestate.g[FS_REG].lerpfrac = (f - (int)f);
if (ent->model && ent->model->type == mod_sprite)
ent->shaderRGBAf[3] = ex->alpha; /*sprites don't fade over time, the animation should do it*/
else
ent->shaderRGBAf[3] = (1.0 - f/(numframes))*ex->alpha;
ent->shaderRGBAf[3] = (1.0 - f/(numframes))*(ex->startalpha-ex->endalpha) + ex->endalpha;
ent->flags = ex->flags;
ent->scale = scale;
ent->drawflags = SCALE_ORIGIN_ORIGIN;
if (ex->traileffect != P_INVALID)
pe->ParticleTrail(ent->oldorigin, ent->origin, ex->traileffect, 0, &(ex->trailstate));
if (!(ex->flags & Q2RF_BEAM))
VectorCopy(ent->origin, ex->oldorigin); //don't corrupt q2 beams
if (ex->flags & Q2RF_BEAM)
{
ent->rtype = RT_BEAM;

View File

@ -1086,7 +1086,7 @@ void CL_ParseParticleEffect4 (void);
int CL_TranslateParticleFromServer(int sveffect);
void CL_ParseTrailParticles(void);
void CL_ParsePointParticles(qboolean compact);
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, struct model_s *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity); /*called from the particlesystem*/
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, struct model_s *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity, int traileffect); /*called from the particlesystem*/
//
// cl_ents.c

View File

@ -116,6 +116,9 @@ void Con_Destroy (console_t *con)
if (con->footerline)
Z_Free(con->footerline);
con->footerline = NULL;
if (con->completionline)
Z_Free(con->completionline);
con->completionline = NULL;
if (con == &con_main)
{

View File

@ -177,13 +177,14 @@ char *ReadGreyTargaFile (qbyte *data, int flen, tgaheader_t *tgahead, int asgrey
//remember to free it
qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, qboolean *hasalpha, int asgrey)
{
//tga files sadly lack a true magic header thing.
unsigned char *data;
qboolean flipped;
tgaheader_t tgaheader;
tgaheader_t tgaheader; //things are misaligned, so no pointer.
if (length < 18 || (buf[16] != 8 && buf[16] != 16 && buf[16] != 24 && buf[16] != 32))
if (length < 18 || buf[1] > 1 || (buf[16] != 8 && buf[16] != 16 && buf[16] != 24 && buf[16] != 32))
return NULL; //BUMMER!
tgaheader.id_len = buf[0];
@ -199,6 +200,27 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, qboolean *
tgaheader.bpp = buf[16];
tgaheader.attribs = buf[17];
switch(tgaheader.version)
{
case 0: //No image data included.
return NULL; //not really valid for us. reject it after all
case 1: //Uncompressed, color-mapped images.
case 2: //Uncompressed, RGB images.
case 3: //Uncompressed, black and white images.
case 9: //Runlength encoded color-mapped images.
case 10: //Runlength encoded RGB images.
case 11: //Compressed, black and white images.
case 32: //Compressed color-mapped data, using Huffman, Delta, and runlength encoding.
case 33: //Compressed color-mapped data, using Huffman, Delta, and runlength encoding. 4-pass quadtree-type process.
break;
default:
return NULL;
}
//validate the size to some sanity limit.
if ((unsigned short)tgaheader.width > 8192 || (unsigned short)tgaheader.height > 8192)
return NULL;
flipped = !((tgaheader.attribs & 0x20) >> 5);
#ifndef NPFTE
if (r_dodgytgafiles.value)
@ -626,7 +648,7 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, qboolean *
return initbuf;
}
else
Con_Printf("Unsupported version\n");
Con_Printf("TGA: Unsupported version\n");
return NULL;
}

View File

@ -169,6 +169,7 @@ typedef struct {
float frameend;
float framerate;
float alpha;
int traileffect;
} partmodels_t;
// TODO: merge in alpha with rgb to gain benefit of vector opts
typedef struct part_type_s {
@ -907,7 +908,7 @@ static void P_ParticleEffect_f(void)
for (i = 0; i < 64; i++)
{
parenttype = ptype - part_type;
snprintf(newname, sizeof(newname), "+%i%s", i, var);
snprintf(newname, sizeof(newname), "+%i%s", i, ptype->name);
ptype = P_GetParticleType(config, newname);
if (!ptype->loaded)
{
@ -1172,12 +1173,21 @@ static void P_ParticleEffect_f(void)
}
else if (!strcmp(var, "model"))
{
if (*Cmd_Argv(6))
{
assoc = P_AllocateParticleType(config, Cmd_Argv(6));//careful - this can realloc all the particle types
ptype = &part_type[pnum];
}
else
assoc = -1;
ptype->models = BZ_Realloc(ptype->models, sizeof(partmodels_t)*(ptype->nummodels+1));
Q_strncpyz(ptype->models[ptype->nummodels].name, Cmd_Argv(1), sizeof(ptype->models[ptype->nummodels].name));
ptype->models[ptype->nummodels].framestart = atof(Cmd_Argv(2));
ptype->models[ptype->nummodels].frameend = atof(Cmd_Argv(3));
ptype->models[ptype->nummodels].framerate = atof(Cmd_Argv(4));
ptype->models[ptype->nummodels].alpha = atof(Cmd_Argv(5));
ptype->models[ptype->nummodels].traileffect = assoc;
ptype->nummodels++;
}
else if (!strcmp(var, "colorindex"))
@ -1654,11 +1664,15 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
for (i = 0; i < ptype->nummodels; i++)
{
Q_strncatz(outstr, va("model %s %g %g %g %g\n", ptype->models[i].name, ptype->models[i].framestart, ptype->models[i].frameend, ptype->models[i].framerate, ptype->models[i].alpha), outstrlen);
Q_strncatz(outstr, va("model \"%s\" %g %g %g %g \"%s\"\n", ptype->models[i].name, ptype->models[i].framestart, ptype->models[i].frameend, ptype->models[i].framerate, ptype->models[i].alpha, ptype->assoc==P_INVALID?"":part_type[ptype->assoc].name), outstrlen);
}
if (*ptype->texname)
Q_strncatz(outstr, va("texture %s\n", ptype->texname), outstrlen);
{
Q_strncatz(outstr, va("texture \"%s\"\n", ptype->texname), 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)
Q_strncatz(outstr, va("count %g\n", ptype->count), outstrlen);
@ -1709,8 +1723,6 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
if (ptype->assoc != P_INVALID)
Q_strncatz(outstr, va("assoc \"%s\"\n", part_type[ptype->assoc].name), 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);
Q_strncatz(outstr, va("rotationstart %g %g\n", ptype->rotationstartmin*180/M_PI, (ptype->rotationstartmin+ptype->rotationstartrand)*180/M_PI), outstrlen);
Q_strncatz(outstr, va("rotationspeed %g %g\n", ptype->rotationmin*180/M_PI, (ptype->rotationmin+ptype->rotationrand)*180/M_PI), outstrlen);
@ -1729,6 +1741,9 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
}
if (ptype->stain_radius)
Q_strncatz(outstr, va("spawnstain %g %g %g %g\n", ptype->stain_radius, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2]), outstrlen);
if (ptype->stainonimpact)
Q_strncatz(outstr, va("stains %g\n", ptype->stainonimpact), outstrlen);
return true;
@ -2239,19 +2254,19 @@ static void P_ImportEffectInfo_f(void)
ptype->dl_cubemapnum = atoi(arg[1]);
#if 1
else if (!strcmp(arg[0], "staincolor") && args == 3)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
else if (!strcmp(arg[0], "stainalpha") && args == 3)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
else if (!strcmp(arg[0], "stainsize") && args == 3)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
else if (!strcmp(arg[0], "staintex") && args == 3)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
else if (!strcmp(arg[0], "stainless") && args == 2)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
else if (!strcmp(arg[0], "rotate") && args == 3)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
else if (!strcmp(arg[0], "rotate") && args == 5)
Con_DPrintf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
Con_DPrintf("Particle effect %s not supported\n", arg[0]);
#endif
else
Con_Printf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
@ -2532,7 +2547,7 @@ static qboolean P_LoadParticleSet(char *name, qboolean implicit)
if (partset_list[i].data)
{
Cbuf_AddText(va("\nr_part namespace %s %i\n", name, implicit), restrictlevel);
Cbuf_AddText(*partset_list[i].data, RESTRICT_LOCAL);
Cbuf_AddText(*partset_list[i].data, restrictlevel);
Cbuf_AddText("\nr_part namespace \"\" 0\n", restrictlevel);
}
return true;
@ -3179,7 +3194,7 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, in
{
vec3_t morg, mdir;
PScript_ApplyOrgVel(morg, mdir, org, dir, i, count, ptype);
CL_SpawnSpriteEffect(morg, mdir, mod->model, mod->framestart, (mod->frameend?mod->frameend:(mod->model->numframes - mod->framestart)), mod->framerate?mod->framerate:10, ptype->alpha?ptype->alpha:1, ptype->rotationmin*180/M_PI, ptype->gravity);
CL_SpawnSpriteEffect(morg, mdir, mod->model, mod->framestart, (mod->frameend?mod->frameend:(mod->model->numframes - mod->framestart)), mod->framerate?mod->framerate:10, mod->alpha?mod->alpha:1, ptype->rotationmin*180/M_PI, ptype->gravity, mod->traileffect);
}
}
}

View File

@ -2954,7 +2954,7 @@ void QCBUILTIN PF_cl_effect(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
mdl = Mod_ForName(name, MLV_WARN);
if (mdl)
CL_SpawnSpriteEffect(org, NULL, mdl, startframe, endframe, framerate, 1, 0, 0);
CL_SpawnSpriteEffect(org, NULL, mdl, startframe, endframe, framerate, mdl->type==mod_sprite?-1:1, 0, 0, P_INVALID);
else
Con_Printf("PF_cl_effect: Couldn't load model %s\n", name);
}
@ -5253,6 +5253,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
int i;
string_t *str;
csqcedict_t *worldent;
char *cheats;
if (csprogs_promiscuous != anycsqc || csprogs_checksum != checksum)
CSQC_Shutdown();
csprogs_promiscuous = anycsqc;
@ -5261,7 +5262,8 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
csqc_mayread = false;
csqc_singlecheats = cls.demoplayback;
if (atoi(Info_ValueForKey(cl.serverinfo, "*cheats")))
cheats = Info_ValueForKey(cl.serverinfo, "*cheats");
if (!Q_strcasecmp(cheats, "ON") || atoi(cheats))
csqc_singlecheats = true;
#ifndef CLIENTONLY
else if (sv.state == ss_active && sv.allocated_client_slots == 1)

View File

@ -1891,7 +1891,228 @@ char *particle_set_minimal =
char *particle_set_h2part =
"r_part t_rocket\n"
//hexen2-compatible particle config
//for the purposes of faithfulness, I'm using uhexen2 (with gl_missile_glows etc set to 0) as a baseline.
//the engine uses the h2part namespace for all hexen2 effects, thus ensuring that the builtin config is loaded.
//specifying this explicitly means that the engine can find these effects properly even if this config is loaded via some name other than h2part.
//this line doesn't affect weak/strong stuff, so r_particledesc will still override builtin ones.
"r_part namespace h2part\n"
//transparent sprites look stupid when alpha tested too. really this shouldn't be here, but its needed to override fps_preset stuff...
"gl_blendsprites 1\n"
//pe4 effect 255 is reused for the generic
//move the vel to org and ignore the spawn velocity to mimic hexen2's particleexplosion
//colour gets overriden
"r_part pe4_255\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 1\n"
"scale 4\n"
"alpha 0.6\n"
"die 0.5\n"
"randomvel 256\n"
"veladd 0\n"
"orgadd 1\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//icemace hitting a monster
"r_part pe2_14_145\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 20\n"
"scale 4\n"
"alpha 1\n"
"die 1\n"
"randomvel 256\n"
"rgb 160 160 240\n"
"veladd 0\n"
"orgadd 1\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//praevus flame summoning particles
"r_part pe2_7 //_427\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 1\n"
"scale 4\n"
"alpha 3\n"
"die 2\n"
"randomvel 0\n"
"veladd 1\n"
"spawnorg 8\n"
"spawnvel 0\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"gravity 0\n"
"scalefactor 0.8\n"
"}\n"
//grav. identical to slowgrav. used for the necro's boneshard particle puffs
"r_part pe4_1\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 1\n"
"scale 6\n"
"alpha 1\n"
"die 1\n"
"randomvel 0\n"
"veladd 1\n"
"orgadd 0\n"
"spawnorg 8\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"gravity 200\n"
"scalefactor 0.3\n"
"}\n"
//slowgrav, used for the assassin's grenade's trail, stupidly enough
"r_part pe4_3\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 1\n"
"scale 4\n"
"alpha 0.6\n"
"die 0.5\n"
"randomvel 0\n"
"veladd 1\n"
"orgadd 0\n"
"spawnorg 8\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//pt_fastgrav. blood splatters (like in the assassin's tomed set staff when the monster is chained up).
"r_part pe4_2\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 1\n"
"scale 8\n"
"alpha 2\n"
"die 1\n"
"randomvel 0\n"
"veladd 2\n"
"orgadd 0\n"
"spawnorg 8\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"gravity 800\n"
"scalefactor 0.8\n"
"}\n"
//the 'rocket trail' flag from quake was repurposed in hexen2 for spider gibs
"r_part tr_rocket\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 2\n"
"scale 4\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 16 160 16\n"
"rgbrand 16 64 16\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//used for the meteor staff trail (projectile and gibs)
"r_part tr_grenade\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 1\n"
"die 1\n"
"randomvel 8\n"
"veladd 10\n"
"gravity -40\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"rgb 16\n"
"rgbrand 48\n"
"rgbrandsync 1\n"
"scalefactor 0.8\n"
"}\n"
//used on ice chunks (paladin ice wand thing)
"r_part tr_ice\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"rgb 160 160 240\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//hexen2 uses the exact same effect for blood and slightblood, just slightblood is half as dense.
"r_part tr_slightblood\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 6\n"
"scale 4\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"rgb 240 0 0\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
"r_part tr_blood\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 3\n"
"scale 4\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 360\n"
"rotationstart 0 360\n"
"rgb 240 0 0\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//fixme: test
"r_part tr_bloodshot\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
@ -1903,33 +2124,270 @@ char *particle_set_h2part =
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 16 32 16\n"
"rgbrand 16 64 16\n"
"rgb 0 255 0 //fixme\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//demoness acid projectile trails
"r_part tr_acidball\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 16 160 16\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.4\n"
"}\n"
//fixme:test
"r_part tr_meteor\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 32\n"
"scale 64\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 0 255 0 //fixme\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"scaledelta -10\n"
"stains 2\n"
"}\n"
//hydra spit. generally blackish
"r_part tr_spit \n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 3\n"
"scale 4\n"
"alpha 1\n"
"die 1\n"
"randomvel 5\n"
"veladd 10\n"
"up 2\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 0 0 0\n"
"rgbrand 0 0 0\n"
"gravity 0\n"
"scalefactor 0.3\n"
"}\n"
//famine missiles
"r_part tr_spell\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 1\n"
"die 1\n"
"randomvel 16\n"
"spawnorg 4\n"
"spawnvel 2\n"
"veladd 64\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 200 32 32\n"
"rgbrand 0 0 0\n"
"gravity 0\n"
"scalefactor 0.3\n"
"}\n"
//tomed barbarian weapon2 trail
"r_part tr_vorpmissile\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 0.6\n"
"die 0.5\n"
"randomvel 4\n"
"spawnorg 32 4\n"
"veladd 64\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 128 128 128\n"
"rgbrand 0 0 0\n"
"gravity 0\n"
"scalefactor 0.8\n"
"}\n"
//this fades out much faster than regular hexen2. also slightly flies forwards with the missile
"r_part tr_magicmissile\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 1\n"
"die 0.5\n"
"randomvel 64\n"
"veladd -128\n"
"spawnorg 8\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 100 100 160\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
"r_part tr_boneshard\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 4\n"
"scale 4\n"
"alpha 1\n"
"die 0.5\n"
"randomvel 64\n"
"veladd -128\n"
"spawnorg 8\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 200 180 85\n"
"rgbrand 0 0 0\n"
"gravity 200\n"
"scalefactor 0.8\n"
"}\n"
//imp fireballs
"r_part tr_fireball\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 97 97 191 191 256\n"
"step 1\n"
"scale 12\n"
"alpha 0.4\n"
"die 0.5\n"
"rgb 255 127 100\n"
"rgbdelta -14 -300 -300\n"
"blend add\n"
"scalefactor 1\n"
"scaledelta -15\n"
"}\n"
"r_part +tr_fireball\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 97 97 191 191 256\n"
"step 5\n"
"scale 30\n"
"alpha 0.2\n"
"die 0.75\n"
//diesubrand 10.25
"randomvel 0.2\n"
"rgb 5 5 5\n"
//rgbdelta -230 -45 -9
"gravity -15\n"
"scalefactor 1\n"
"scaledelta 20\n"
"spawnvel 5\n"
"}\n"
//assassin weapon4
"r_part tr_setstaff\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 2\n"
"scale 4\n"
"alpha 0.6\n"
"die 1\n"
"spawnorg 3 5\n"
"randomvel 3.5\n"
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 220 200 100 \n"
"rgbrand 0 0 0\n"
"gravity 40\n"
"scalefactor 0.8\n"
"}\n"
//assassin weapon4's tomed projectile trail thing. barely visible in hexen2. framerate dependant. nasty. this effect is not faithful.
"r_part tr_scarab\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 2\n"
"scale 4\n"
"alpha 0.3\n"
"die 0.2\n"
"spawnorg 1 2\n"
"randomvel 1\n"
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 220 200 100 \n"
"rgbrand 0 0 0\n"
"gravity 40\n"
"scalefactor 0.8\n"
"}\n"
//generic rain. rgb comes from the gamecode's palette index. blurgh. real men specify things precisely.
"r_part te_rain\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"count 1 2 1\n"
"scale 5\n"
"alpha 3\n"
"die 2\n"
"spawnorg 64 64\n"
"spawnvel 1\n"
"veladd 0.5\n"
"rotationspeed 90\n"
"rotationstart 0 30\n"
"rgb 255 255 255\n"
"scalefactor 0.8\n"
"}\n"
//Hexen2 triggers various client-side sprite/model effects.
//model term:
//model MODELNAME framestart frameend framerate alpha traileffect
//sprites will always use a fixed alpha (frames should shrink in size or whatever).
//models will fade out gradually, but can be forced to a constant alpha if a negative alpha is used (will be fabsed as needed) if you have a decent animation.
"r_part ce_white_smoke_05\n"
"{\n"
"model models/whtsmk1.spr 0 0 20 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_white_smoke_10\n"
"{\n"
"model models/whtsmk1.spr 0 0 10 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_white_smoke_15\n"
"{\n"
"model models/whtsmk1.spr 0 0 6.666 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_white_smoke_20\n"
"{\n"
"model models/whtsmk1.spr 0 0 5 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_white_smoke_50\n"
"{\n"
"model models/whtsmk1.spr 0 0 2 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_bluespark\n"
@ -1994,31 +2452,38 @@ char *particle_set_h2part =
"r_part ce_green_smoke_05\n"
"{\n"
"model models/grnsmk1.spr 0 0 20 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_green_smoke_10\n"
"{\n"
"model models/grnsmk1.spr 0 0 10 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_green_smoke_15\n"
"{\n"
"model models/grnsmk1.spr 0 0 6.666 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_green_smoke_20\n"
"{\n"
"model models/grnsmk1.spr 0 0 5 0.5\n"
"veladd 1\n"
"}\n"
// ce_grey_smoke
"r_part ce_grey_smoke_15\n"
"{\n"
"model models/grysmk1.spr 0 0 6.666 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_red_smoke\n"
"{\n"
"model models/redsmk1.spr 0 0 6.666 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_slow_white_smoke\n"
"{\n"
"model models/whtsmk1.spr 0 0 20 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_redspark\n"
"{\n"
@ -2030,11 +2495,13 @@ char *particle_set_h2part =
"}\n"
"r_part ce_telesmk1\n"
"{\n"
"model models/telesmk1.spr 0 0 15 1\n"
"model models/telesmk1.spr 0 0 15 0.5\n"
"veladd 1\n"
"}\n"
"r_part ce_telesmk2\n"
"{\n"
"model models/telesmk2.spr 0 0 15 1\n"
"veladd 1\n"
"}\n"
"r_part ce_icehit\n"
"{\n"
@ -2069,7 +2536,11 @@ char *particle_set_h2part =
"{\n"
"model models/bonexpld.spr 0 0 20 1\n"
"}\n"
// ce_redcloud
//famine teleport effect
"r_part ce_redcloud\n"
"{\n"
"model models/rcloud.spr 0 0 20 1\n"
"}\n"
"r_part ce_teleporterpuffs\n"
"{\n"
// model models/telesmk2.spr 0 0 20 1
@ -2077,17 +2548,40 @@ char *particle_set_h2part =
// ce_teleporterbody
// ce_boneshard
// ce_boneshrapnel
//this is transparent so it doesn't obscure your view
"r_part ce_flamestream\n"
"{\n"
"model models/flamestr.spr 0 0 20 1\n"
"model models/flamestr.spr 0 0 20 0.4\n"
"veladd 1\n"
"}\n"
"r_part ce_gravitywell\n"
"{\n"
"spawnmode ball\n"
"count 100\n"
"spawnorg 128\n"
"spawnvel -64\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"scale 4\n"
"alpha 1\n"
"die 2\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 220 200 100\n"
"rgbrand 0 0 0\n"
"gravity 0\n"
"scalefactor 0.4\n"
"}\n"
// ce_snow,
// ce_gravitywell
"r_part ce_bldrn_expl\n"
"{\n"
"model models/xplsn_1.spr 0 0 20 1\n"
"}\n"
// ce_acid_muzzfl
//demoness tomed acid trail
"r_part ce_acid_muzzfl\n"
"{\n"
"model models/muzzle1.spr 0 0 20 0.4\n"
"veladd 1\n"
"}\n"
"r_part ce_acid_hit\n"
"{\n"
"model models/axplsn_2.spr 0 0 20 1\n"
@ -2104,6 +2598,23 @@ char *particle_set_h2part =
"{\n"
"model models/firewal4.spr 0 0 20 1\n"
"}\n"
"r_part ce_onfire\n"
"{\n"
"model models/firewal1.spr 0 0 20 0.4\n"
"model models/firewal2.spr 0 0 20 0.4\n"
"model models/firewal3.spr 0 0 20 0.4\n"
"veladd 1\n"
"}\n"
"r_part ce_flamewall\n"
"{\n"
"model models/firewal1.spr 0 0 20 1\n"
"veladd 1\n"
"}\n"
"r_part ce_flamewall2\n"
"{\n"
"model models/firewal2.spr 0 0 20 0.4\n"
"veladd 1\n"
"}\n"
"r_part ce_lball_expl\n"
"{\n"
"model models/Bluexp3.spr 0 0 20 1\n"
@ -2188,9 +2699,9 @@ char *particle_set_h2part =
"}\n"
"r_part ce_chunk_flesh\n"
"{\n"
"model models/flesh1.mdl 0 1 0.25 1\n"
"model models/flesh2.mdl 0 1 0.25 1\n"
"model models/flesh3.mdl 0 1 0.25 1\n"
"model models/flesh1.mdl 0 1 0.25 1 tr_bloodshot\n"
"model models/flesh2.mdl 0 1 0.25 1 tr_bloodshot\n"
"model models/flesh3.mdl 0 1 0.25 1 tr_bloodshot\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
@ -2327,11 +2838,11 @@ char *particle_set_h2part =
"}\n"
"r_part ce_chunk_webs\n"
"{\n"
"model models/shard1.mdl 3 1 0.25 0.5\n"
"model models/shard2.mdl 3 1 0.25 0.5\n"
"model models/shard3.mdl 3 1 0.25 0.5\n"
"model models/shard4.mdl 3 1 0.25 0.5\n"
"model models/shard5.mdl 3 1 0.25 0.5\n"
"model models/shard1.mdl 3 1 0.25 -0.5\n"
"model models/shard2.mdl 3 1 0.25 -0.5\n"
"model models/shard3.mdl 3 1 0.25 -0.5\n"
"model models/shard4.mdl 3 1 0.25 -0.5\n"
"model models/shard5.mdl 3 1 0.25 -0.5\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 500\n"
@ -2351,19 +2862,20 @@ char *particle_set_h2part =
"}\n"
"r_part ce_chunk_ice\n"
"{\n"
"model models/shard.mdl 0 1 0.25 0.5\n"
"model models/shard.mdl 1 1 0.25 0.5\n"
"model models/shard.mdl 0 1 0.25 -0.4 tr_ice\n"
"model models/shard.mdl 1 1 0.25 -0.4 tr_ice\n"
"rotationspeed 30\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"}\n"
"r_part ce_chunk_clearglass\n"
"{\n"
"model models/shard1.mdl 1 1 0.25 0.5\n"
"model models/shard2.mdl 1 1 0.25 0.5\n"
"model models/shard3.mdl 1 1 0.25 0.5\n"
"model models/shard4.mdl 1 1 0.25 0.5\n"
"model models/shard5.mdl 1 1 0.25 0.5\n"
"model models/shard1.mdl 1 1 0.25 -0.5\n"
"model models/shard2.mdl 1 1 0.25 -0.5\n"
"model models/shard3.mdl 1 1 0.25 -0.5\n"
"model models/shard4.mdl 1 1 0.25 -0.5\n"
"model models/shard5.mdl 1 1 0.25 -0.5\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
@ -2383,7 +2895,7 @@ char *particle_set_h2part =
"}\n"
"r_part ce_chunk_acid\n"
"{\n"
"model models/sucwp2p.mdl 0 1 0.25 1\n"
"model models/sucwp2p.mdl 0 1 0.25 1 tr_acidball\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
@ -2391,7 +2903,7 @@ char *particle_set_h2part =
"}\n"
"r_part ce_chunk_meteor\n"
"{\n"
"model models/tempmetr.mdl 0 1 0.25 1\n"
"model models/tempmetr.mdl 0 1 0.25 1 tr_meteor\n"
"randomvel 360\n"
"spawnorg 0\n"
"gravity 800\n"
@ -2399,9 +2911,9 @@ char *particle_set_h2part =
"}\n"
"r_part ce_chunk_greenflesh\n"
"{\n"
"model models/sflesh1.mdl 0 1 0.25 1\n"
"model models/sflesh2.mdl 0 1 0.25 1\n"
"model models/sflesh3.mdl 0 1 0.25 1\n"
"model models/sflesh1.mdl 0 1 0.25 1 tr_acidball\n"
"model models/sflesh2.mdl 0 1 0.25 1 tr_acidball\n"
"model models/sflesh3.mdl 0 1 0.25 1 tr_acidball\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
@ -2455,6 +2967,49 @@ char *particle_set_h2part =
"veladd 1\n"
"gravity 200\n"
"}\n"
//this teleport effect is nothing like hexen2's. hopefully it'll be acceptable :s
//the down ring
"r_part ce_teleporterbody\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 193 1 255 63 256\n"
"count 32\n"
"scale 16\n"
"scalefactor 1\n"
"alpha 0.3\n"
"die 1\n"
"veladd -52\n"
"rgb 255 255 255\n"
"friction 1\n"
"spawnorg 32 0\n"
"spawnmode uniformcircle\n"
"}\n"
//the up ring
"r_part +ce_teleporterbody\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 193 1 255 63 256\n"
"count 32\n"
"scale 16\n"
"scalefactor 1\n"
"alpha 0.3\n"
"die 1\n"
"veladd 52\n"
"rgb 255 255 255\n"
"friction 1\n"
"spawnorg 32 0\n"
"spawnmode uniformcircle\n"
"}\n"
//h2part.ce_rain was not loaded
//h2part.ce_quake was not loaded
//h2part.ce_ghost was not loaded
//h2part.ce_teleporterbody_1 was not loaded
//h2part.ce_grey_smoke_100 was not loaded
//h2part.ce_chunk_fire was not loaded
;

View File

@ -97,7 +97,7 @@ cvar_t r_fb_models = CVARAF ("r_fb_models", "1",
"gl_fb_models", CVAR_SEMICHEAT);
cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1",
CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_globalskin_first = CVARFD ("r_globalskin_first", "100", CVAR_RENDERERLATCH, "Specifies the first .skin value that is a global skin. See also: r_globalskin_count.");
cvar_t r_globalskin_first = CVARFD ("r_globalskin_first", "100", CVAR_RENDERERLATCH, "Specifies the first .skin value that is a global skin. Entities within this range will use the shader/image called 'gfx/skinSKIN.lmp' instead of their regular skin. See also: r_globalskin_count.");
cvar_t r_globalskin_count = CVARFD ("r_globalskin_count", "10", CVAR_RENDERERLATCH, "Specifies how many globalskins there are.");
cvar_t r_coronas = SCVARF ("r_coronas", "0",
CVAR_ARCHIVE);
@ -172,7 +172,8 @@ cvar_t scr_showpause = SCVAR ("showpause", "1");
cvar_t scr_showturtle = SCVAR ("showturtle", "0");
cvar_t scr_turtlefps = SCVAR ("scr_turtlefps", "10");
cvar_t scr_sshot_compression = SCVAR ("scr_sshot_compression", "75");
cvar_t scr_sshot_type = SCVAR ("scr_sshot_type", "jpg");
cvar_t scr_sshot_type = SCVAR ("scr_sshot_type", "png");
cvar_t scr_sshot_prefix = SCVAR ("scr_sshot_prefix", "screenshots/fte");
cvar_t scr_viewsize = CVARFC("viewsize", "100",
CVAR_ARCHIVE,
SCR_Viewsize_Callback);
@ -649,6 +650,7 @@ void Renderer_Init(void)
Cvar_Register (&scr_sshot_type, SCREENOPTIONS);
Cvar_Register (&scr_sshot_compression, SCREENOPTIONS);
Cvar_Register (&scr_sshot_prefix, SCREENOPTIONS);
Cvar_Register(&cl_cursor, SCREENOPTIONS);
Cvar_Register(&cl_cursorsize, SCREENOPTIONS);
@ -706,6 +708,8 @@ void Renderer_Init(void)
Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES);
Cvar_Register (&r_fb_models, GRAPHICALNICETIES);
Cvar_Register (&r_skin_overlays, GRAPHICALNICETIES);
Cvar_Register (&r_globalskin_first, GRAPHICALNICETIES);
Cvar_Register (&r_globalskin_count, GRAPHICALNICETIES);
Cvar_Register (&r_shadows, GRAPHICALNICETIES);
Cvar_Register (&r_replacemodels, GRAPHICALNICETIES);

View File

@ -1945,6 +1945,32 @@ void Sbar_DrawScoreboard (void)
}
static void Sbar_Hexen2DrawActiveStuff(playerview_t *pv)
{
int x = r_refdef.grect.x + r_refdef.grect.width;
mpic_t *pic;
if (pv->stats[STAT_H2_ARTIFACT_ACTIVE] & 4)
{
pic = R2D_SafeCachePic(va("gfx/pwrbook%d.lmp", ((int)(cl.time*16)%15)+1));
x -= 32;
R2D_ScalePic(x, r_refdef.grect.y, 32, 32, pic);
x -= 18;
}
if (pv->stats[STAT_H2_ARTIFACT_ACTIVE] & 1)
{
pic = R2D_SafeCachePic(va("gfx/durhst%d.lmp", ((int)(cl.time*16)%15)+1));
x -= 32;
R2D_ScalePic(x, r_refdef.grect.y, 32, 32, pic);
x -= 18;
}
if (pv->stats[STAT_H2_ARTIFACT_ACTIVE] & 2)
{
pic = R2D_SafeCachePic(va("gfx/durshd%d.lmp", ((int)(cl.time*16)%15)+1));
x -= 32;
R2D_ScalePic(x, r_refdef.grect.y, 32, 32, pic);
x -= 18;
}
}
static void Sbar_Hexen2DrawItem(playerview_t *pv, float x, float y, int itemnum)
{
int num;
@ -2461,6 +2487,8 @@ void Sbar_Draw (playerview_t *pv)
if (cl.deathmatch)
Sbar_MiniDeathmatchOverlay (pv);
Sbar_Hexen2DrawActiveStuff(pv);
}
else if (sbarfailed) //files failed to load.
{

View File

@ -2828,6 +2828,7 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran
"{\n"
"map $diffuse\n"
"blendfunc gl_one_minus_src_alpha gl_src_alpha\n"
"alphagen entity\n"
"rgbgen lightingDiffuse\n"
"cull disable\n"
"depthwrite\n"
@ -2838,17 +2839,21 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran
"{\n"
"{\n"
"map $diffuse\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"alphafunc ge128\n"
"rgbgen lightingDiffuse\n"
"alphagen entity\n"
"depthwrite\n"
"}\n"
"}\n");
else if (skintranstype)
shaders[0] = R_RegisterShader(skinname, SUF_NONE,
"{\n"
// "program defaultskin\n"
"{\n"
"map $diffuse\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"alphagen entity\n"
"rgbgen lightingDiffuse\n"
"depthwrite\n"
"}\n"
@ -3049,10 +3054,10 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
//skins
skinstart = (daliasskintype_t *)((char*)pq1inmodel+hdrsize);
if( mod->flags & MFH2_HOLEY )
skintranstype = 3; //hexen2
else if( mod->flags & MFH2_TRANSPARENT )
if( mod->flags & MFH2_TRANSPARENT )
skintranstype = 2; //hexen2
else if( mod->flags & MFH2_HOLEY )
skintranstype = 3; //hexen2
else if( mod->flags & MFH2_SPECIAL_TRANS )
skintranstype = 4; //hexen2
else

View File

@ -1410,11 +1410,15 @@ void Cvar_Shutdown(void)
Cvar_DefaultFree(var->defaultstr);
var->defaultstr = NULL;
}
Z_Free(var->latched_string);
Z_Free(var->string);
if (var->flags & CVAR_POINTER)
Z_Free(var);
else
{
var->string = NULL;
var->latched_string = NULL;
}
}
grp = cvar_groups;

View File

@ -2304,8 +2304,8 @@ void COM_Gamedir (const char *dir)
#define NEXCFG DPCOMPAT "set r_particlesdesc effectinfo\nset sv_bigcoords 1\nset sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\npr_enable_uriget 0\n"
/*some modern non-compat settings*/
#define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n"
/*set some stuff so our regular qw client appears more like hexen2*/
#define HEX2CFG "set com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n"
/*set some stuff so our regular qw client appears more like hexen2. sv_mintic is required to 'fix' the ravenstaff so that its projectiles don't impact upon each other*/
#define HEX2CFG "set com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.015\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n"
/*yay q2!*/
#define Q2CFG "com_nogamedirnativecode 0\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
@ -3158,14 +3158,18 @@ void FS_Shutdown(void)
fs_manifest = NULL;
}
//returns false if the directory is not suitable.
//returns true if it contains a known package. if we don't actually know of any packages that it should have, we just have to assume that its okay.
static qboolean FS_DirHasAPackage(char *basedir, ftemanifest_t *man)
{
qboolean defaultret = true;
int j;
vfsfile_t *f;
for (j = 0; j < sizeof(fs_manifest->package) / sizeof(fs_manifest->package[0]); j++)
{
if (!man->package[j].path)
continue;
defaultret = false;
f = VFSOS_Open(va("%s%s", basedir, man->package[j].path), "rb");
if (f)
@ -3174,7 +3178,7 @@ static qboolean FS_DirHasAPackage(char *basedir, ftemanifest_t *man)
return true;
}
}
return false;
return defaultret;
}
//just check each possible file, see if one is there.

View File

@ -1652,9 +1652,17 @@ qboolean FTENET_Loop_SendPacket(ftenet_generic_connection_t *con, int length, co
void FTENET_Loop_Close(ftenet_generic_connection_t *con)
{
int i;
int sock = con->thesocket;
sock &= 1;
loopbacks[sock].inited = false;
for (i = 0; i < MAX_LOOPBACK; i++)
{
BZ_Free(loopbacks[sock].msgs[i].data);
loopbacks[sock].msgs[i].data = NULL;
loopbacks[sock].msgs[i].datalen = 0;
loopbacks[sock].msgs[i].datamax = 0;
}
Z_Free(con);
}

View File

@ -477,9 +477,9 @@ static LRESULT WINAPI D3D11_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
if (modestate == MS_FULLDIB)
ShowWindow(mainwindow, SW_SHOWNORMAL);
if (ActiveApp && modestate == MS_FULLSCREEN)
if (modestate == MS_FULLSCREEN)
{
IDXGISwapChain_SetFullscreenState(d3dswapchain, modestate == MS_FULLSCREEN, d3dscreen);
IDXGISwapChain_SetFullscreenState(d3dswapchain, ActiveApp, d3dscreen);
D3D11_DoResize();
}
Cvar_ForceCallback(&v_gamma);

View File

@ -1427,6 +1427,13 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
if (SHADER_SORT_PORTAL < sort && sort < SHADER_SORT_BLEND)
sort = SHADER_SORT_BLEND;
}
else if (e->drawflags & DRF_TRANSLUCENT)
{
b->flags |= BEF_FORCETRANSPARENT;
if (SHADER_SORT_PORTAL < sort && sort < SHADER_SORT_BLEND)
sort = SHADER_SORT_BLEND;
e->shaderRGBAf[3] = r_wateralpha.value;
}
if (e->flags & RF_NODEPTHTEST)
{
b->flags |= BEF_FORCENODEPTH;

View File

@ -4155,6 +4155,8 @@ char *Shader_DefaultBSPWater(const char *shortname)
wstyle = r_lavastyle.ival;
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && !strncmp(shortname, "*slime", 5) && *r_slimestyle.string)
wstyle = r_slimestyle.ival;
else if (!strncmp(shortname, "*lava", 5))
wstyle = -2;
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && strncmp(shortname, "*lava", 5))
wstyle = r_waterstyle.ival<1?1:r_waterstyle.ival;
#endif
@ -4174,6 +4176,17 @@ char *Shader_DefaultBSPWater(const char *shortname)
"surfaceparm nodlight\n"
"}\n"
);
case -2: //regular with r_wateralpha forced off.
return (
"{\n"
"program defaultwarp\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
case 0: //fastturb
return (
"{\n"

View File

@ -1,4 +1,225 @@
r_part t_rocket
//hexen2-compatible particle config
//for the purposes of faithfulness, I'm using uhexen2 (with gl_missile_glows etc set to 0) as a baseline.
//the engine uses the h2part namespace for all hexen2 effects, thus ensuring that the builtin config is loaded.
//specifying this explicitly means that the engine can find these effects properly even if this config is loaded via some name other than h2part.
//this line doesn't affect weak/strong stuff, so r_particledesc will still override builtin ones.
r_part namespace h2part
//transparent sprites look stupid when alpha tested too. really this shouldn't be here, but its needed to override fps_preset stuff...
gl_blendsprites 1
//pe4 effect 255 is reused for the generic
//move the vel to org and ignore the spawn velocity to mimic hexen2's particleexplosion
//colour gets overriden
r_part pe4_255
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 1
scale 4
alpha 0.6
die 0.5
randomvel 256
veladd 0
orgadd 1
rotationspeed 360
rotationstart 0 360
gravity 200
scalefactor 0.8
}
//icemace hitting a monster
r_part pe2_14_145
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 20
scale 4
alpha 1
die 1
randomvel 256
rgb 160 160 240
veladd 0
orgadd 1
rotationspeed 360
rotationstart 0 360
gravity 200
scalefactor 0.8
}
//praevus flame summoning particles
r_part pe2_7 //_427
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 1
scale 4
alpha 3
die 2
randomvel 0
veladd 1
spawnorg 8
spawnvel 0
rotationspeed 360
rotationstart 0 360
gravity 0
scalefactor 0.8
}
//grav. identical to slowgrav. used for the necro's boneshard particle puffs
r_part pe4_1
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 1
scale 6
alpha 1
die 1
randomvel 0
veladd 1
orgadd 0
spawnorg 8
rotationspeed 360
rotationstart 0 360
gravity 200
scalefactor 0.3
}
//slowgrav, used for the assassin's grenade's trail, stupidly enough
r_part pe4_3
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 1
scale 4
alpha 0.6
die 0.5
randomvel 0
veladd 1
orgadd 0
spawnorg 8
rotationspeed 360
rotationstart 0 360
gravity 200
scalefactor 0.8
}
//pt_fastgrav. blood splatters (like in the assassin's tomed set staff when the monster is chained up).
r_part pe4_2
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 1
scale 8
alpha 2
die 1
randomvel 0
veladd 2
orgadd 0
spawnorg 8
rotationspeed 360
rotationstart 0 360
gravity 800
scalefactor 0.8
}
//the 'rocket trail' flag from quake was repurposed in hexen2 for spider gibs
r_part tr_rocket
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 2
scale 4
alpha 0.6
die 1
randomvel 64
veladd 10
rotationspeed 90
rotationstart 0 360
rgb 16 160 16
rgbrand 16 64 16
gravity 200
scalefactor 0.8
}
//used for the meteor staff trail (projectile and gibs)
r_part tr_grenade
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 1
die 1
randomvel 8
veladd 10
gravity -40
rotationspeed 360
rotationstart 0 360
rgb 16
rgbrand 48
rgbrandsync 1
scalefactor 0.8
}
//used on ice chunks (paladin ice wand thing)
r_part tr_ice
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 0.6
die 1
randomvel 64
veladd 10
rotationspeed 360
rotationstart 0 360
rgb 160 160 240
rgbrand 0 0 0
gravity 200
scalefactor 0.8
}
//hexen2 uses the exact same effect for blood and slightblood, just slightblood is half as dense.
r_part tr_slightblood
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 6
scale 4
alpha 0.6
die 1
randomvel 64
veladd 10
rotationspeed 360
rotationstart 0 360
rgb 240 0 0
rgbrand 0 0 0
gravity 200
scalefactor 0.8
}
r_part tr_blood
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 3
scale 4
alpha 0.6
die 1
randomvel 64
veladd 10
rotationspeed 360
rotationstart 0 360
rgb 240 0 0
rgbrand 0 0 0
gravity 200
scalefactor 0.8
}
//fixme: test
r_part tr_bloodshot
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
@ -10,33 +231,270 @@ r_part t_rocket
veladd 10
rotationspeed 90
rotationstart 0 360
rgb 16 32 16
rgbrand 16 64 16
rgb 0 255 0 //fixme
rgbrand 0 0 0
gravity 200
scalefactor 0.8
}
//demoness acid projectile trails
r_part tr_acidball
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 0.6
die 1
randomvel 64
veladd 10
rotationspeed 90
rotationstart 0 360
rgb 16 160 16
rgbrand 0 0 0
gravity 200
scalefactor 0.4
}
//fixme:test
r_part tr_meteor
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 32
scale 64
alpha 0.6
die 1
randomvel 64
veladd 10
rotationspeed 90
rotationstart 0 360
rgb 0 255 0 //fixme
rgbrand 0 0 0
gravity 200
scalefactor 0.8
scaledelta -10
stains 2
}
//hydra spit. generally blackish
r_part tr_spit
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 3
scale 4
alpha 1
die 1
randomvel 5
veladd 10
up 2
rotationspeed 90
rotationstart 0 360
rgb 0 0 0
rgbrand 0 0 0
gravity 0
scalefactor 0.3
}
//famine missiles
r_part tr_spell
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 1
die 1
randomvel 16
spawnorg 4
spawnvel 2
veladd 64
rotationspeed 90
rotationstart 0 360
rgb 200 32 32
rgbrand 0 0 0
gravity 0
scalefactor 0.3
}
//tomed barbarian weapon2 trail
r_part tr_vorpmissile
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 0.6
die 0.5
randomvel 4
spawnorg 32 4
veladd 64
rotationspeed 90
rotationstart 0 360
rgb 128 128 128
rgbrand 0 0 0
gravity 0
scalefactor 0.8
}
//this fades out much faster than regular hexen2. also slightly flies forwards with the missile
r_part tr_magicmissile
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 1
die 0.5
randomvel 64
veladd -128
spawnorg 8
rotationspeed 90
rotationstart 0 360
rgb 100 100 160
rgbrand 0 0 0
gravity 200
scalefactor 0.8
}
r_part tr_boneshard
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 4
scale 4
alpha 1
die 0.5
randomvel 64
veladd -128
spawnorg 8
rotationspeed 90
rotationstart 0 360
rgb 200 180 85
rgbrand 0 0 0
gravity 200
scalefactor 0.8
}
//imp fireballs
r_part tr_fireball
{
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 1
scale 12
alpha 0.4
die 0.5
rgb 255 127 100
rgbdelta -14 -300 -300
blend add
scalefactor 1
scaledelta -15
}
r_part +tr_fireball
{
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 5
scale 30
alpha 0.2
die 0.75
//diesubrand 10.25
randomvel 0.2
rgb 5 5 5
//rgbdelta -230 -45 -9
gravity -15
scalefactor 1
scaledelta 20
spawnvel 5
}
//assassin weapon4
r_part tr_setstaff
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 2
scale 4
alpha 0.6
die 1
spawnorg 3 5
randomvel 3.5
veladd 10
rotationspeed 90
rotationstart 0 360
rgb 220 200 100
rgbrand 0 0 0
gravity 40
scalefactor 0.8
}
//assassin weapon4's tomed projectile trail thing. barely visible in hexen2. framerate dependant. nasty. this effect is not faithful.
r_part tr_scarab
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 2
scale 4
alpha 0.3
die 0.2
spawnorg 1 2
randomvel 1
veladd 10
rotationspeed 90
rotationstart 0 360
rgb 220 200 100
rgbrand 0 0 0
gravity 40
scalefactor 0.8
}
//generic rain. rgb comes from the gamecode's palette index. blurgh. real men specify things precisely.
r_part te_rain
{
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
count 1 2 1
scale 5
alpha 3
die 2
spawnorg 64 64
spawnvel 1
veladd 0.5
rotationspeed 90
rotationstart 0 30
rgb 255 255 255
scalefactor 0.8
}
//Hexen2 triggers various client-side sprite/model effects.
//model term:
//model MODELNAME framestart frameend framerate alpha traileffect
//sprites will always use a fixed alpha (frames should shrink in size or whatever).
//models will fade out gradually, but can be forced to a constant alpha if a negative alpha is used (will be fabsed as needed) if you have a decent animation.
r_part ce_white_smoke_05
{
model models/whtsmk1.spr 0 0 20 0.5
veladd 1
}
r_part ce_white_smoke_10
{
model models/whtsmk1.spr 0 0 10 0.5
veladd 1
}
r_part ce_white_smoke_15
{
model models/whtsmk1.spr 0 0 6.666 0.5
veladd 1
}
r_part ce_white_smoke_20
{
model models/whtsmk1.spr 0 0 5 0.5
veladd 1
}
r_part ce_white_smoke_50
{
model models/whtsmk1.spr 0 0 2 0.5
veladd 1
}
r_part ce_bluespark
@ -101,31 +559,38 @@ r_part ce_blue_explosion
r_part ce_green_smoke_05
{
model models/grnsmk1.spr 0 0 20 0.5
veladd 1
}
r_part ce_green_smoke_10
{
model models/grnsmk1.spr 0 0 10 0.5
veladd 1
}
r_part ce_green_smoke_15
{
model models/grnsmk1.spr 0 0 6.666 0.5
veladd 1
}
r_part ce_green_smoke_20
{
model models/grnsmk1.spr 0 0 5 0.5
veladd 1
}
// ce_grey_smoke
r_part ce_grey_smoke_15
{
model models/grysmk1.spr 0 0 6.666 0.5
veladd 1
}
r_part ce_red_smoke
{
model models/redsmk1.spr 0 0 6.666 0.5
veladd 1
}
r_part ce_slow_white_smoke
{
model models/whtsmk1.spr 0 0 20 0.5
veladd 1
}
r_part ce_redspark
{
@ -137,11 +602,13 @@ r_part ce_greenspark
}
r_part ce_telesmk1
{
model models/telesmk1.spr 0 0 15 1
model models/telesmk1.spr 0 0 15 0.5
veladd 1
}
r_part ce_telesmk2
{
model models/telesmk2.spr 0 0 15 1
veladd 1
}
r_part ce_icehit
{
@ -176,7 +643,11 @@ r_part ce_bone_explosion
{
model models/bonexpld.spr 0 0 20 1
}
// ce_redcloud
//famine teleport effect
r_part ce_redcloud
{
model models/rcloud.spr 0 0 20 1
}
r_part ce_teleporterpuffs
{
// model models/telesmk2.spr 0 0 20 1
@ -184,17 +655,40 @@ r_part ce_teleporterpuffs
// ce_teleporterbody
// ce_boneshard
// ce_boneshrapnel
//this is transparent so it doesn't obscure your view
r_part ce_flamestream
{
model models/flamestr.spr 0 0 20 1
model models/flamestr.spr 0 0 20 0.4
veladd 1
}
r_part ce_gravitywell
{
spawnmode ball
count 100
spawnorg 128
spawnvel -64
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
scale 4
alpha 1
die 2
rotationspeed 90
rotationstart 0 360
rgb 220 200 100
rgbrand 0 0 0
gravity 0
scalefactor 0.4
}
// ce_snow,
// ce_gravitywell
r_part ce_bldrn_expl
{
model models/xplsn_1.spr 0 0 20 1
}
// ce_acid_muzzfl
//demoness tomed acid trail
r_part ce_acid_muzzfl
{
model models/muzzle1.spr 0 0 20 0.4
veladd 1
}
r_part ce_acid_hit
{
model models/axplsn_2.spr 0 0 20 1
@ -211,6 +705,23 @@ r_part ce_firewall_large
{
model models/firewal4.spr 0 0 20 1
}
r_part ce_onfire
{
model models/firewal1.spr 0 0 20 0.4
model models/firewal2.spr 0 0 20 0.4
model models/firewal3.spr 0 0 20 0.4
veladd 1
}
r_part ce_flamewall
{
model models/firewal1.spr 0 0 20 1
veladd 1
}
r_part ce_flamewall2
{
model models/firewal2.spr 0 0 20 0.4
veladd 1
}
r_part ce_lball_expl
{
model models/Bluexp3.spr 0 0 20 1
@ -295,9 +806,9 @@ r_part ce_chunk_metal
}
r_part ce_chunk_flesh
{
model models/flesh1.mdl 0 1 0.25 1
model models/flesh2.mdl 0 1 0.25 1
model models/flesh3.mdl 0 1 0.25 1
model models/flesh1.mdl 0 1 0.25 1 tr_bloodshot
model models/flesh2.mdl 0 1 0.25 1 tr_bloodshot
model models/flesh3.mdl 0 1 0.25 1 tr_bloodshot
randomvel 210 70 280
spawnorg 0
gravity 800
@ -434,11 +945,11 @@ r_part ce_chunk_metal_cloth
}
r_part ce_chunk_webs
{
model models/shard1.mdl 3 1 0.25 0.5
model models/shard2.mdl 3 1 0.25 0.5
model models/shard3.mdl 3 1 0.25 0.5
model models/shard4.mdl 3 1 0.25 0.5
model models/shard5.mdl 3 1 0.25 0.5
model models/shard1.mdl 3 1 0.25 -0.5
model models/shard2.mdl 3 1 0.25 -0.5
model models/shard3.mdl 3 1 0.25 -0.5
model models/shard4.mdl 3 1 0.25 -0.5
model models/shard5.mdl 3 1 0.25 -0.5
randomvel 210 70 280
spawnorg 0
gravity 500
@ -458,8 +969,8 @@ r_part ce_chunk_glass
}
r_part ce_chunk_ice
{
model models/shard.mdl 0 1 0.25 0.5
model models/shard.mdl 1 1 0.25 0.5
model models/shard.mdl 0 1 0.25 -0.4 tr_ice
model models/shard.mdl 1 1 0.25 -0.4 tr_ice
rotationspeed 30
randomvel 210 70 280
spawnorg 0
@ -467,11 +978,11 @@ r_part ce_chunk_ice
}
r_part ce_chunk_clearglass
{
model models/shard1.mdl 1 1 0.25 0.5
model models/shard2.mdl 1 1 0.25 0.5
model models/shard3.mdl 1 1 0.25 0.5
model models/shard4.mdl 1 1 0.25 0.5
model models/shard5.mdl 1 1 0.25 0.5
model models/shard1.mdl 1 1 0.25 -0.5
model models/shard2.mdl 1 1 0.25 -0.5
model models/shard3.mdl 1 1 0.25 -0.5
model models/shard4.mdl 1 1 0.25 -0.5
model models/shard5.mdl 1 1 0.25 -0.5
randomvel 210 70 280
spawnorg 0
gravity 800
@ -491,7 +1002,7 @@ r_part ce_chunk_redglass
}
r_part ce_chunk_acid
{
model models/sucwp2p.mdl 0 1 0.25 1
model models/sucwp2p.mdl 0 1 0.25 1 tr_acidball
randomvel 210 70 280
spawnorg 0
gravity 800
@ -499,7 +1010,7 @@ r_part ce_chunk_acid
}
r_part ce_chunk_meteor
{
model models/tempmetr.mdl 0 1 0.25 1
model models/tempmetr.mdl 0 1 0.25 1 tr_meteor
randomvel 360
spawnorg 0
gravity 800
@ -507,9 +1018,9 @@ r_part ce_chunk_meteor
}
r_part ce_chunk_greenflesh
{
model models/sflesh1.mdl 0 1 0.25 1
model models/sflesh2.mdl 0 1 0.25 1
model models/sflesh3.mdl 0 1 0.25 1
model models/sflesh1.mdl 0 1 0.25 1 tr_acidball
model models/sflesh2.mdl 0 1 0.25 1 tr_acidball
model models/sflesh3.mdl 0 1 0.25 1 tr_acidball
randomvel 210 70 280
spawnorg 0
gravity 800
@ -565,16 +1076,44 @@ r_part ce_snow
}
//this teleport effect is nothing like hexen2's. hopefully it'll be acceptable :s
//the down ring
r_part ce_teleporterbody
{
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
count 32
scale 16
scalefactor 1
alpha 0.3
die 1
veladd -52
rgb 255 255 255
friction 1
spawnorg 32 0
spawnmode uniformcircle
}
//the up ring
r_part +ce_teleporterbody
{
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
count 32
scale 16
scalefactor 1
alpha 0.3
die 1
veladd 52
rgb 255 255 255
friction 1
spawnorg 32 0
spawnmode uniformcircle
}
//h2part.ce_rain was not loaded
//h2part.ce_quake was not loaded
//h2part.ce_ghost was not loaded
//h2part.ce_redcloud was not loaded
//h2part.ce_teleporterbody was not loaded
//h2part.ce_gravitywell was not loaded
//h2part.ce_acid_muzzfl was not loaded
//h2part.ce_flamewall was not loaded
//h2part.ce_flamewall2 was not loaded
//h2part.ce_onfire was not loaded
//h2part.ce_teleporterbody_1 was not loaded
//h2part.ce_grey_smoke_100 was not loaded
//h2part.ce_chunk_fire was not loaded

View File

@ -425,9 +425,15 @@ typedef struct statement32_s
unsigned int a,b,c;
} dstatement32_t;
#define QCC_dstatement16_t dstatement16_t
#define QCC_dstatement_t dstatement32_t
#define QCC_dstatement32_t dstatement32_t
typedef struct qcc_statement_s
{
unsigned int op;
unsigned int a,b,c;
unsigned int linenum;
} QCC_statement_t;
//these should be the same except the string type
typedef struct ddef16_s
{

View File

@ -179,6 +179,12 @@ typedef struct
int priority; //FIXME: priority should be done differently...
enum {ASSOC_LEFT, ASSOC_RIGHT, ASSOC_RIGHT_RESULT} associative;
struct QCC_type_s **type_a, **type_b, **type_c;
unsigned int flags;
//ASSIGNS_B
//ASSIGNS_IB
//ASSIGNS_C
//ASSIGNS_IC
} QCC_opcode_t;
extern QCC_opcode_t pr_opcodes[]; // sized by initialization

View File

@ -575,7 +575,7 @@ extern int optres_logicops;
pbool CompileParams(progfuncs_t *progfuncs, int doall, int nump, char **parms);
void QCC_PR_PrintStatement (QCC_dstatement_t *s);
void QCC_PR_PrintStatement (QCC_statement_t *s);
void QCC_PR_Lex (void);
// reads the next token into pr_token and classifies its type
@ -889,9 +889,8 @@ extern unsigned int numpr_globals;
extern char *strings;
extern int strofs;
extern QCC_dstatement_t *statements;
extern QCC_statement_t *statements;
extern int numstatements;
extern int *statement_linenums;
extern QCC_dfunction_t *functions;
extern int numfunctions;

View File

@ -166,7 +166,7 @@ enum
STFL_CONVERTB=1<<3
};
#define QCC_PR_Statement(op,a,b,st) QCC_PR_StatementFlags(op,a,b,st,STFL_CONVERTA|STFL_CONVERTB)
QCC_def_t *QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement, unsigned int flags);
QCC_def_t *QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_statement_t **outstatement, unsigned int flags);
void QCC_PR_ParseState (void);
pbool expandedemptymacro;
@ -1016,7 +1016,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
return false;
// if (num >= OP_MULSTORE_F && num <= OP_SUBSTOREP_V)
// return false;
if (num <= OP_CALL8H) //CALLXH are fixed up. This is to provide more dynamic switching...??
if (num <= OP_CALL8H) //CALLXH are fixed up. This is to provide more dynamic switching...
return true;
return false;
case QCF_FTEH2:
@ -1547,7 +1547,7 @@ static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement
QCC_def_t *def;
int newofs;
QCC_dstatement_t *st;
QCC_statement_t *st;
int i;
newofs = 0;
@ -1839,7 +1839,7 @@ int QCC_PR_FindSourceForAssignedOffset(int ofs, int firstst)
pbool QCC_Temp_Describe(QCC_def_t *def, char *buffer, int buffersize)
{
QCC_dstatement_t *s;
QCC_statement_t *s;
int st;
temp_t *t = def->temp;
if (!t)
@ -1859,15 +1859,15 @@ pbool QCC_Temp_Describe(QCC_def_t *def, char *buffer, int buffersize)
return true;
}
QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force);
QCC_statement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force);
QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement, unsigned int flags)
QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_statement_t **outstatement, unsigned int flags)
{
char typea[256], typeb[256];
QCC_dstatement_t *statement;
QCC_statement_t *statement;
QCC_def_t *var_c=NULL, *temp=NULL;
if (outstatement == (QCC_dstatement_t **)0xffffffff)
if (outstatement == (QCC_statement_t **)0xffffffff)
{
outstatement = NULL;
flags &= ~(STFL_CONVERTA|STFL_CONVERTB);
@ -2591,21 +2591,18 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_ADDSTORE_I:
op = &pr_opcodes[OP_ADD_I];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_ADDSTORE_FI:
op = &pr_opcodes[OP_ADD_FI];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
// case OP_ADDSTORE_IF:
// fixme: result is a float but needs to be an int
@ -2613,7 +2610,6 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
// var_c = var_b;
// var_b = var_a;
// var_a = var_c;
// var_c = var_a;
// break;
case OP_SUBSTORE_F:
@ -2621,14 +2617,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_SUBSTORE_FI:
op = &pr_opcodes[OP_SUB_FI];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
// case OP_SUBSTORE_IF:
// fixme: result is a float but needs to be an int
@ -2636,14 +2630,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
// var_c = var_b;
// var_b = var_a;
// var_a = var_c;
// var_c = var_a;
// break;
case OP_SUBSTORE_I:
op = &pr_opcodes[OP_SUB_I];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_BINARYNOT_I:
@ -2654,7 +2646,7 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
case OP_BINARYNOT_F:
op = &pr_opcodes[OP_SUB_F];
var_b = var_a;
var_a = QCC_MakeFloatConst(0xffffff); //due to fpu precision, we only use 24 bits.
var_a = QCC_MakeFloatConst(-1); //divVerent says -1 is safe, even with floats. I guess I'm just too paranoid.
break;
case OP_DIVSTORE_F:
@ -2662,14 +2654,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_DIVSTORE_FI:
op = &pr_opcodes[OP_DIV_FI];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
// case OP_DIVSTORE_IF:
// fixme: result is a float, but needs to be an int
@ -2677,14 +2667,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
// var_c = var_b;
// var_b = var_a;
// var_a = var_c;
// var_c = var_a;
// break;
case OP_DIVSTORE_I:
op = &pr_opcodes[OP_DIV_I];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_MULSTORE_F:
@ -2692,7 +2680,6 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
// case OP_MULSTORE_IF:
// fixme: result is a float, but needs to be an int
@ -2700,14 +2687,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
// var_c = var_b;
// var_b = var_a;
// var_a = var_c;
// var_c = var_a;
// break;
case OP_MULSTORE_FI:
op = &pr_opcodes[OP_MUL_FI];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_ADDSTORE_V:
@ -2715,7 +2700,6 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_SUBSTORE_V:
@ -2723,7 +2707,6 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_MULSTORE_VF:
@ -2731,14 +2714,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_MULSTORE_VI:
op = &pr_opcodes[OP_MUL_VI];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_BITSETSTORE_I:
@ -2746,14 +2727,12 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_BITSETSTORE_F:
op = &pr_opcodes[OP_BITOR_F];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_STOREP_P:
@ -2881,25 +2860,25 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
}
/*generate new OP_ADDRESS instruction - FIXME: the arguments may have changed since the original instruction*/
statement_linenums[statement-statements] = statement_linenums[st];
statement->op = OP_ADDRESS;
statement->a = statements[st].a;
statement->b = statements[st].b;
statement->c = var_c->ofs;
statement->linenum = statements[st].linenum;
/*convert old one to an OP_LOAD*/
statement_linenums[st] = pr_token_line_last;
statements[st].op = ((*op->type_c)->type==ev_vector)?OP_LOAD_V:OP_LOAD_F;
// statements[st].a = statements[st].a;
// statements[st].b = statements[st].b;
// statements[st].c = statements[st].c;
statements[st].linenum = pr_token_line_last;
}
}
statement = &statements[numstatements];
numstatements++;
statement_linenums[statement-statements] = pr_token_line_last;
statement->linenum = pr_token_line_last;
switch(op - pr_opcodes)
{
case OP_SUBSTOREP_V:
@ -2973,7 +2952,7 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
statement = &statements[numstatements];
numstatements++;
statement_linenums[statement-statements] = pr_token_line_last;
statement->linenum = pr_token_line_last;
statement->op = OP_SUB_F;
//t = c & i
@ -3039,7 +3018,7 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t
if (outstatement)
*outstatement = statement;
statement_linenums[statement-statements] = pr_token_line_last;
statement->linenum = pr_token_line_last;
statement->op = op - pr_opcodes;
statement->a = var_a ? var_a->ofs : 0;
statement->b = var_b ? var_b->ofs : 0;
@ -3112,29 +3091,29 @@ QCC_PR_SimpleStatement
Emits a primitive statement, returning the var it places it's value in
============
*/
QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force)
QCC_statement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force)
{
QCC_dstatement_t *statement;
QCC_statement_t *statement;
if (!force && !QCC_OPCodeValid(pr_opcodes+op))
{
QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", pr_opcodes[op].name, pr_opcodes[op].opname);
}
statement_linenums[numstatements] = pr_token_line_last;
statement = &statements[numstatements];
numstatements++;
statement->op = op;
statement->a = var_a;
statement->b = var_b;
statement->c = var_c;
statement->linenum = pr_token_line_last;
return statement;
}
void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_def_t *var_c, int force)
{
QCC_dstatement_t *statement;
QCC_statement_t *statement;
if (!force && !QCC_OPCodeValid(op))
{
@ -3146,11 +3125,11 @@ void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, Q
statement = &statements[numstatements];
numstatements++;
statement_linenums[statement-statements] = pr_token_line_last;
statement->op = op - pr_opcodes;
statement->a = var_a ? var_a->ofs : 0;
statement->b = var_b ? var_b->ofs : 0;
statement->c = var_c ? var_c->ofs : 0;
statement->linenum = pr_token_line_last;
}
/*
@ -3493,7 +3472,7 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *newself, QCC_def_t *func, QCC
// int np;
int callconvention;
QCC_dstatement_t *st;
QCC_statement_t *st;
func->timescalled++;
@ -3628,11 +3607,11 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *newself, QCC_def_t *func, QCC
//generate the call
if (argcount>MAX_PARMS)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+MAX_PARMS], func, 0, (QCC_dstatement_t **)&st));
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+MAX_PARMS], func, 0, (QCC_statement_t **)&st));
else if (argcount)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+argcount], func, 0, (QCC_dstatement_t **)&st));
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+argcount], func, 0, (QCC_statement_t **)&st));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CALL0], func, 0, (QCC_dstatement_t **)&st));
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CALL0], func, 0, (QCC_statement_t **)&st));
if (callconvention == OP_CALL1H)
{
@ -3906,7 +3885,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou
{
if (d)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
QCC_def_t *t;
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
@ -4311,16 +4290,16 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou
e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
QCC_PR_Expect(")");
e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, QCC_MakeIntConst(1), (QCC_dstatement_t **)0xffffffff);
e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, QCC_MakeIntConst(1), (QCC_statement_t **)0xffffffff);
d = QCC_PR_GetDef(NULL, "nextent", NULL, false, 0, false);
if (!d)
QCC_PR_ParseError(0, "the nextent builtin is not defined");
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], e, &def_parms[0], (QCC_statement_t **)0xffffffff));
d = QCC_PR_Statement(&pr_opcodes[OP_CALL0], d, NULL, NULL);
d = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], d, QCC_MakeIntConst(1), (QCC_dstatement_t **)0xffffffff);
d = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], d, QCC_MakeIntConst(1), (QCC_statement_t **)0xffffffff);
e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, d, (QCC_dstatement_t **)0xffffffff);
e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, d, (QCC_statement_t **)0xffffffff);
return e;
}
@ -4390,11 +4369,11 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou
e = &def_parms[arg];
e->ofs = OFS_PARM0+0;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[0]), e, (QCC_dstatement_t **)0xffffffff));
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[0]), e, (QCC_statement_t **)0xffffffff));
e->ofs = OFS_PARM0+1;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[1]), e, (QCC_dstatement_t **)0xffffffff));
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[1]), e, (QCC_statement_t **)0xffffffff));
e->ofs = OFS_PARM0+2;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[2]), e, (QCC_dstatement_t **)0xffffffff));
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[2]), e, (QCC_statement_t **)0xffffffff));
e->ofs = OFS_PARM0;
e->type = type_vector;
@ -5316,12 +5295,12 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
}
/* else if (d->type->type == ev_vector && d->arraysize == 0)
{ //array notation on vectors (non-field)
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff);
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_statement_t **)0xffffffff);
d->type = type_float;
}
*//* else if (d->type->type == ev_field && d->type->aux_type->type == ev_vector && d->arraysize == 0)
{ //array notation on vectors (fields)
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff);
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_statement_t **)0xffffffff);
d->type = type_floatfield;
}
*/ else
@ -5418,19 +5397,19 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
d = QCC_GetTemp(type_vector);
d->type = type_float;
if (x->type->type == ev_float)
QCC_PR_Statement(pr_opcodes + OP_STORE_F, x, d, (QCC_dstatement_t **)0xffffffff);
QCC_PR_Statement(pr_opcodes + OP_STORE_F, x, d, (QCC_statement_t **)0xffffffff);
else
QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, x, d, (QCC_dstatement_t **)0xffffffff);
QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, x, d, (QCC_statement_t **)0xffffffff);
d->ofs++;
if (y->type->type == ev_float)
QCC_PR_Statement(pr_opcodes + OP_STORE_F, y, d, (QCC_dstatement_t **)0xffffffff);
QCC_PR_Statement(pr_opcodes + OP_STORE_F, y, d, (QCC_statement_t **)0xffffffff);
else
QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, y, d, (QCC_dstatement_t **)0xffffffff);
QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, y, d, (QCC_statement_t **)0xffffffff);
d->ofs++;
if (z->type->type == ev_float)
QCC_PR_Statement(pr_opcodes + OP_STORE_F, z, d, (QCC_dstatement_t **)0xffffffff);
QCC_PR_Statement(pr_opcodes + OP_STORE_F, z, d, (QCC_statement_t **)0xffffffff);
else
QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, z, d, (QCC_dstatement_t **)0xffffffff);
QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, z, d, (QCC_statement_t **)0xffffffff);
d->ofs++;
d->ofs -= 3;
d->type = type_vector;
@ -5995,7 +5974,7 @@ QCC_def_t *QCC_CollapseStore(QCC_def_t *dest, QCC_def_t *source, QCC_type_t *typ
{
if (source->temp)
{
QCC_dstatement_t *statement = &statements[numstatements-1];
QCC_statement_t *statement = &statements[numstatements-1];
statement->c = dest->ofs;
dest->references++;
@ -6296,7 +6275,7 @@ QCC_def_t *QCC_LoadFromArray(QCC_def_t *base, QCC_def_t *index, QCC_type_t *t, p
for (i = 0; i < t->size; i++)
{
if (i)
args[0] = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], index, QCC_MakeFloatConst(i), (QCC_dstatement_t **)0xffffffff);
args[0] = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], index, QCC_MakeFloatConst(i), (QCC_statement_t **)0xffffffff);
else
{
args[0] = index;
@ -6305,7 +6284,7 @@ QCC_def_t *QCC_LoadFromArray(QCC_def_t *base, QCC_def_t *index, QCC_type_t *t, p
r = QCC_PR_GenerateFunctionCall(NULL, funcretr, args, &type_float, 1);
opt_assignments = old_op;
QCC_UnFreeTemp(index);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], r, base, (QCC_dstatement_t **)0xffffffff));
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], r, base, (QCC_statement_t **)0xffffffff));
base->ofs++;
}
QCC_FreeTemp(index);
@ -6777,39 +6756,36 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
while (1)
{
if (priority == FUNC_PRIORITY)
if (priority == FUNC_PRIORITY && QCC_PR_CheckToken ("(") )
{
if (QCC_PR_CheckToken ("(") )
{
qcc_usefulstatement=true;
lhsd = QCC_PR_ParseFunctionCall (lhsr);
lhsd = QCC_PR_ParseArrayPointer(lhsd, true, true);
lhsr = QCC_DefToRef(retbuf, lhsd);
}
if (QCC_PR_CheckToken ("?"))
{
QCC_def_t *val, *r;
QCC_dstatement32_t *fromj, *elsej;
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], QCC_RefToDef(lhsr, true), NULL, &fromj));
val = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
r = QCC_GetTemp(val->type);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(r->type->size>=3)?OP_STORE_V:OP_STORE_F], val, r, (QCC_dstatement_t **)0xffffffff));
//r can be stomped upon until its reused anyway
QCC_UnFreeTemp(r);
qcc_usefulstatement=true;
lhsd = QCC_PR_ParseFunctionCall (lhsr);
lhsd = QCC_PR_ParseArrayPointer(lhsd, true, true);
lhsr = QCC_DefToRef(retbuf, lhsd);
}
if (priority == FUNC_PRIORITY && QCC_PR_CheckToken ("?"))
{
QCC_def_t *val, *r;
QCC_statement_t *fromj, *elsej;
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], QCC_RefToDef(lhsr, true), NULL, &fromj));
val = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
r = QCC_GetTemp(val->type);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(r->type->size>=3)?OP_STORE_V:OP_STORE_F], val, r, (QCC_statement_t **)0xffffffff));
//r can be stomped upon until its reused anyway
QCC_UnFreeTemp(r);
QCC_PR_Expect(":");
QCC_PR_Statement(&pr_opcodes[OP_GOTO], NULL, NULL, &elsej);
fromj->b = &statements[numstatements] - fromj;
val = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
QCC_PR_Expect(":");
QCC_PR_Statement(&pr_opcodes[OP_GOTO], NULL, NULL, &elsej);
fromj->b = &statements[numstatements] - fromj;
val = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
if (typecmp(val->type, r->type) != 0)
QCC_PR_ParseError(0, "Ternary operator with mismatching types\n");
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(r->type->size>=3)?OP_STORE_V:OP_STORE_F], val, r, (QCC_dstatement_t **)0xffffffff));
QCC_UnFreeTemp(r);
if (typecmp(val->type, r->type) != 0)
QCC_PR_ParseError(0, "Ternary operator with mismatching types\n");
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(r->type->size>=3)?OP_STORE_V:OP_STORE_F], val, r, (QCC_statement_t **)0xffffffff));
QCC_UnFreeTemp(r);
elsej->a = &statements[numstatements] - elsej;
return QCC_DefToRef(retbuf, r);
}
elsej->a = &statements[numstatements] - elsej;
return QCC_DefToRef(retbuf, r);
}
opnum=0;
@ -7059,7 +7035,7 @@ int QCC_PR_IntConstExpr(void)
return true;
}
void QCC_PR_GotoStatement (QCC_dstatement_t *patch2, char *labelname)
void QCC_PR_GotoStatement (QCC_statement_t *patch2, char *labelname)
{
if (num_gotos >= max_gotos)
{
@ -7074,7 +7050,7 @@ void QCC_PR_GotoStatement (QCC_dstatement_t *patch2, char *labelname)
num_gotos++;
}
pbool QCC_PR_StatementBlocksMatch(QCC_dstatement_t *p1, int p1count, QCC_dstatement_t *p2, int p2count)
pbool QCC_PR_StatementBlocksMatch(QCC_statement_t *p1, int p1count, QCC_statement_t *p2, int p2count)
{
if (p1count != p2count)
return false;
@ -7098,9 +7074,9 @@ pbool QCC_PR_StatementBlocksMatch(QCC_dstatement_t *p1, int p1count, QCC_dstatem
}
//vanilla qc only has an OP_IFNOT_I, others will be emulated as required, so we tend to need to emulate other opcodes.
QCC_dstatement_t *QCC_Generate_OP_IF(QCC_def_t *e)
QCC_statement_t *QCC_Generate_OP_IF(QCC_def_t *e)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
switch(e->type->type)
{
//int/pointer types
@ -7143,9 +7119,9 @@ QCC_dstatement_t *QCC_Generate_OP_IF(QCC_def_t *e)
}
return st;
}
QCC_dstatement_t *QCC_Generate_OP_IFNOT(QCC_def_t *e)
QCC_statement_t *QCC_Generate_OP_IFNOT(QCC_def_t *e)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
switch(e->type->type)
{
//int/pointer types
@ -7201,7 +7177,7 @@ void QCC_PR_ParseStatement (void)
int cases;
int i;
QCC_def_t *e, *e2;
QCC_dstatement_t *patch1, *patch2, *patch3;
QCC_statement_t *patch1, *patch2, *patch3;
int statementstart = pr_source_line;
pbool wasuntil;
@ -7382,8 +7358,7 @@ void QCC_PR_ParseStatement (void)
int old_numstatements;
int numtemp, i;
int linenum[32];
QCC_dstatement_t temp[sizeof(linenum)/sizeof(linenum[0])];
QCC_statement_t temp[32];
continues = num_continues;
breaks = num_breaks;
@ -7412,12 +7387,11 @@ void QCC_PR_ParseStatement (void)
QCC_FreeTemp(QCC_PR_Expression(TOP_PRIORITY, 0));
numtemp = numstatements - old_numstatements;
if (numtemp > sizeof(linenum)/sizeof(linenum[0]))
if (numtemp > sizeof(temp)/sizeof(temp[0]))
QCC_PR_ParseError(ERR_TOOCOMPLEX, "Update expression too large");
numstatements = old_numstatements;
for (i = 0 ; i < numtemp ; i++)
{
linenum[i] = statement_linenums[numstatements + i];
temp[i] = statements[numstatements + i];
}
@ -7435,7 +7409,6 @@ void QCC_PR_ParseStatement (void)
patch3 = &statements[numstatements];
for (i = 0 ; i < numtemp ; i++)
{
statement_linenums[numstatements] = linenum[i];
statements[numstatements++] = temp[i];
}
QCC_PR_SimpleStatement(OP_GOTO, patch2 - &statements[numstatements], 0, 0, false);
@ -8229,7 +8202,7 @@ void QCC_PR_ParseState (void)
void QCC_PR_ParseAsm(void)
{
QCC_dstatement_t *patch1;
QCC_statement_t *patch1;
int op, p;
QCC_def_t *a, *b, *c;
@ -8769,7 +8742,7 @@ int QCC_CheckOneUninitialised(int firststatement, int laststatement, unsigned in
{
int ret;
int i;
QCC_dstatement32_t *st;
QCC_statement_t *st;
for (i = firststatement; i < laststatement; i++)
{
@ -8891,7 +8864,7 @@ pbool QCC_CheckUninitialised(int firststatement, int laststatement)
err = QCC_CheckOneUninitialised(firststatement, laststatement, min, max);
if (err > 0)
{
QCC_PR_Warning(WARN_UNINITIALIZED, strings+s_file, statement_linenums[err], "Potentially uninitialised variable %s", local->name);
QCC_PR_Warning(WARN_UNINITIALIZED, strings+s_file, statements[err].linenum, "Potentially uninitialised variable %s", local->name);
result = true;
// break;
}
@ -8902,7 +8875,7 @@ pbool QCC_CheckUninitialised(int firststatement, int laststatement)
void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
unsigned int i;
for (i = firststatement, st = &statements[i]; i < laststatement; i++, st++)
@ -9082,7 +9055,7 @@ void QCC_WriteAsmFunction(QCC_def_t *sc, unsigned int firststatement, gofs_t fir
}
}
}
fprintf(asmfile, "; /*%i*/\n", statement_linenums[i]);
fprintf(asmfile, "; /*%i*/\n", statements[i].linenum);
}
fprintf(asmfile, "}\n\n");
@ -9379,7 +9352,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int min, int max)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
QCC_def_t *eq;
int stride;
@ -9420,7 +9393,7 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi
//This is useful when we have a load of indexes.
void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_def_t *array, QCC_def_t *index, int min, int max)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
QCC_def_t *eq;
if (min == max || min+1 == max)
{
@ -9517,7 +9490,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *thearray, char *ar
QCC_dfunction_t *df;
QCC_def_t *index;
QCC_dstatement_t *st;
QCC_statement_t *st;
QCC_def_t *eq;
QCC_def_t *fasttrackpossible;
@ -9651,7 +9624,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *thearray, char *ar
void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t *value, int min, int max)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
QCC_def_t *eq;
int stride;
@ -9734,7 +9707,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, QCC_def_t *thearray, char *ar
if (fasttrackpossible)
{
QCC_dstatement_t *st;
QCC_statement_t *st;
QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, fasttrackpossible, NULL, &st);
//note that the array size is coded into the globals, one index before the array.

View File

@ -89,7 +89,7 @@ void GoToDefinition(char *name)
fnc = &functions[((int *)qcc_pr_globals)[def->ofs]];
if (fnc->first_statement>=0 && fnc->s_file)
{
EditFile(fnc->s_file+strings, statement_linenums[fnc->first_statement]);
EditFile(fnc->s_file+strings, statements[fnc->first_statement].linenum);
return;
}
}

View File

@ -63,9 +63,8 @@ unsigned int numpr_globals;
char *strings;
int strofs;
QCC_dstatement_t *statements;
QCC_statement_t *statements;
int numstatements;
int *statement_linenums;
QCC_dfunction_t *functions;
int numfunctions;
@ -684,6 +683,7 @@ pbool QCC_WriteData (int crc)
pbool types = false;
int outputsttype = PST_DEFAULT;
pbool warnedunref = false;
int *statement_linenums;
if (numstatements==1 && numfunctions==1 && numglobaldefs==1 && numfielddefs==1)
{
@ -1072,16 +1072,27 @@ strofs = (strofs+3)&~3;
}
}
if (debugtarget || opt_filenames)
{
statement_linenums = qccHunkAlloc(sizeof(statement_linenums) * numstatements);
for (i = 0; i < numstatements; i++)
statement_linenums[i] = statements[i].linenum;
}
else
statement_linenums = NULL;
switch(outputsttype)
{
case PST_KKQWSV:
case PST_FTE32:
#define statements32 ((QCC_dstatement32_t*) statements)
for (i=0 ; i<numstatements ; i++)
{
statements[i].op = PRLittleLong/*PRLittleShort*/(statements[i].op);
statements[i].a = PRLittleLong/*PRLittleShort*/(statements[i].a);
statements[i].b = PRLittleLong/*PRLittleShort*/(statements[i].b);
statements[i].c = PRLittleLong/*PRLittleShort*/(statements[i].c);
statements32[i].op = PRLittleLong/*PRLittleShort*/(statements[i].op);
statements32[i].a = PRLittleLong/*PRLittleShort*/(statements[i].a);
statements32[i].b = PRLittleLong/*PRLittleShort*/(statements[i].b);
statements32[i].c = PRLittleLong/*PRLittleShort*/(statements[i].c);
}
if (progs.blockscompressed&1)
@ -1095,13 +1106,13 @@ strofs = (strofs+3)&~3;
SafeSeek(h, i, SEEK_SET);
}
else
SafeWrite (h, statements, numstatements*sizeof(QCC_dstatement32_t));
SafeWrite (h, statements32, numstatements*sizeof(QCC_dstatement32_t));
break;
case PST_QTEST:
#define qtst ((qtest_statement_t*) statements)
for (i=0 ; i<numstatements ; i++) // scale down from 16-byte internal to 12-byte qtest
{
QCC_dstatement_t stmt = statements[i];
QCC_statement_t stmt = statements[i];
qtst[i].line = 0; // no line support
qtst[i].op = PRLittleShort((unsigned short)stmt.op);
if (stmt.a < 0)
@ -3203,9 +3214,8 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
strings = (void *)qccHunkAlloc(sizeof(char) * MAX_STRINGS);
strofs = 2;
statements = (void *)qccHunkAlloc(sizeof(QCC_dstatement_t) * MAX_STATEMENTS);
statements = (void *)qccHunkAlloc(sizeof(QCC_statement_t) * MAX_STATEMENTS);
numstatements = 0;
statement_linenums = (void *)qccHunkAlloc(sizeof(int) * MAX_STATEMENTS);
functions = (void *)qccHunkAlloc(sizeof(QCC_dfunction_t) * MAX_FUNCTIONS);
numfunctions=0;

View File

@ -2831,7 +2831,7 @@ static void QCBUILTIN PF_particle2 (pubprogfuncs_t *prinst, globalvars_t *pr_glo
MSG_WriteFloat (&sv.multicast, dmax[2]);
MSG_WriteShort (&sv.multicast, color);
MSG_WriteByte (&sv.multicast, count);
MSG_WriteByte (&sv.multicast, bound(0, count, 255));
MSG_WriteByte (&sv.multicast, effect);
SV_MulticastProtExt (org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_HEXEN2, 0);
@ -2898,10 +2898,10 @@ static void QCBUILTIN PF_particle4 (pubprogfuncs_t *prinst, globalvars_t *pr_glo
MSG_WriteCoord (&sv.multicast, org[0]);
MSG_WriteCoord (&sv.multicast, org[1]);
MSG_WriteCoord (&sv.multicast, org[2]);
MSG_WriteByte (&sv.multicast, radius);
MSG_WriteByte (&sv.multicast, bound(0, radius, 255));
MSG_WriteShort (&sv.multicast, color);
MSG_WriteByte (&sv.multicast, count);
MSG_WriteByte (&sv.multicast, bound(0, count, 255));
MSG_WriteByte (&sv.multicast, effect);
SV_MulticastProtExt (org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_HEXEN2, 0);
@ -2909,24 +2909,26 @@ static void QCBUILTIN PF_particle4 (pubprogfuncs_t *prinst, globalvars_t *pr_glo
static void QCBUILTIN PF_h2particleexplosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//used by the ice staff
Con_Printf("H2FIXME: PF_h2particleexplosion not implemented\n");
/*
//used by the (regular) ice staff, and multiple other things.
float *org;
int color,radius,counter;
int color,radius,count, effect;
org = G_VECTOR(OFS_PARM0);
color = G_FLOAT(OFS_PARM1);
radius = G_FLOAT(OFS_PARM2);
counter = G_FLOAT(OFS_PARM3);
MSG_WriteByte(&sv.datagram, svc_particle_explosion);
MSG_WriteCoord(&sv.datagram, org[0]);
MSG_WriteCoord(&sv.datagram, org[1]);
MSG_WriteCoord(&sv.datagram, org[2]);
MSG_WriteShort(&sv.datagram, color);
MSG_WriteShort(&sv.datagram, radius);
MSG_WriteShort(&sv.datagram, counter);
*/
radius = G_FLOAT(OFS_PARM1);
color = G_FLOAT(OFS_PARM2);
effect = 255; //special explosion thing
count = G_FLOAT(OFS_PARM3);
MSG_WriteByte (&sv.multicast, svcfte_particle4);
MSG_WriteCoord (&sv.multicast, org[0]);
MSG_WriteCoord (&sv.multicast, org[1]);
MSG_WriteCoord (&sv.multicast, org[2]);
MSG_WriteByte (&sv.multicast, bound(0, radius, 255));
MSG_WriteShort (&sv.multicast, color);
MSG_WriteByte (&sv.multicast, count);
MSG_WriteByte (&sv.multicast, effect);
SV_MulticastProtExt (org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_HEXEN2, 0);
}
/*
@ -5076,23 +5078,41 @@ PF_changelevel
*/
void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *s, *spot;
char newmap[MAX_QPATH];
char startspot[MAX_QPATH];
// make sure we don't issue two changelevels (unless the last one failed)
if (sv.mapchangelocked)
return;
sv.mapchangelocked = true;
if (svprogfuncs->callargc == 2)
if (progstype == PROG_H2)
{
s = PR_GetStringOfs(prinst, OFS_PARM0);
spot = PR_GetStringOfs(prinst, OFS_PARM1);
Cbuf_AddText (va("\nchangelevel %s %s\n",s, spot), RESTRICT_LOCAL);
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM1), startspot, sizeof(startspot));
//these flags disable the whole levelcache thing. the spawnspot is meant to still and always be specified.
//hexen2 ALWAYS specifies two arguments, and it seems that raven left it blank in some single-player maps too.
//if we don't want to be stupid/broken in deathmatch, we might as well do the fully compatible thing
if ((int)pr_global_struct->serverflags & (16|32))
{
COM_QuotedString(va("*%s", PR_GetStringOfs(prinst, OFS_PARM0)), newmap, sizeof(newmap));
Cbuf_AddText (va("\nmap %s %s\n", newmap, startspot), RESTRICT_LOCAL);
}
else
{
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM0), newmap, sizeof(newmap));
Cbuf_AddText (va("\nchangelevel %s %s\n", newmap, startspot), RESTRICT_LOCAL);
}
}
else
{
s = PR_GetStringOfs(prinst, OFS_PARM0);
Cbuf_AddText (va("\nmap %s\n",s), RESTRICT_LOCAL);
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM0), newmap, sizeof(newmap));
if (svprogfuncs->callargc == 2)
{
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM1), startspot, sizeof(startspot));
Cbuf_AddText (va("\nchangelevel %s %s\n", newmap, startspot), RESTRICT_LOCAL);
}
else
Cbuf_AddText (va("\nmap %s\n", newmap), RESTRICT_LOCAL);
}
}
@ -7053,7 +7073,7 @@ void SV_RegisterH2CustomTents(void)
h2customtents[ce_bone_explosion] = SV_CustomTEnt_Register("h2part.ce_bone_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_redcloud] = SV_CustomTEnt_Register("h2part.ce_redcloud", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterpuffs] = SV_CustomTEnt_Register("h2part.ce_teleporterpuffs", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterbody] = SV_CustomTEnt_Register("h2part.ce_teleporterbody", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterbody] = SV_CustomTEnt_Register("h2part.ce_teleporterbody", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_boneshard] = SV_CustomTEnt_Register("h2part.ce_boneshard", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_boneshrapnel] = SV_CustomTEnt_Register("h2part.ce_boneshrapnel", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_flamestream] = SV_CustomTEnt_Register("h2part.ce_flamestream", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
@ -7384,15 +7404,35 @@ static void QCBUILTIN PF_h2endeffect(pubprogfuncs_t *prinst, struct globalvars_s
static void QCBUILTIN PF_h2rain_go(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
/*
//used by (tomed) icemace.hc
float *min = G_VECTOR(OFS_PARM0);
float *max = G_VECTOR(OFS_PMAR1);
float *max = G_VECTOR(OFS_PARM1);
float *size = G_VECTOR(OFS_PARM2);
float *dir = G_VECTOR(OFS_PARM3);
float colour = G_FLOAT(OFS_PARM4);
float count = G_FLOAT(OFS_PARM5);
*/
Con_DPrintf("FTE-H2 FIXME: rain_go not implemented\n");
//this is some hacky alternative.
//fixme: the effect isn't bounded to the box
MSG_WriteByte(&sv.multicast, svc_temp_entity);
MSG_WriteByte(&sv.multicast, TEDP_PARTICLERAIN);
// min
MSG_WriteCoord(&sv.multicast, min[0]);
MSG_WriteCoord(&sv.multicast, min[1]);
MSG_WriteCoord(&sv.multicast, max[2]);
// max
MSG_WriteCoord(&sv.multicast, max[0]);
MSG_WriteCoord(&sv.multicast, max[1]);
MSG_WriteCoord(&sv.multicast, max[2]);
// velocity
MSG_WriteCoord(&sv.multicast, dir[0]);
MSG_WriteCoord(&sv.multicast, dir[1]);
MSG_WriteCoord(&sv.multicast, -(frandom()*700+256)); //dir not valid. fill in a default downwards direction
// count
MSG_WriteShort(&sv.multicast, min(count, 65535));
// colour
MSG_WriteByte(&sv.multicast, (int)colour&0xff);
SV_Multicast(NULL, MULTICAST_ALL);
}
static void QCBUILTIN PF_h2StopSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -10375,10 +10415,10 @@ void PR_DumpPlatform_f(void)
{"PVSF_IGNOREPVS", "const float", QW|NQ, "Ignores pvs. This entity is visible whereever you are on the map.", PVSF_IGNOREPVS},
{"PVSF_NOREMOVE", "const float", QW|NQ, "Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses.", PVSF_NOREMOVE},
//most of these are there for documentation rather than anything else.
{"INFOKEY_P_IP", "const string", QW|NQ, NULL, 0, "\"ip\""},
{"INFOKEY_P_REALIP", "const string", QW|NQ, NULL, 0, "\"realip\""},
{"INFOKEY_P_CSQCACTIVE","const string", QW|NQ, "Client has csqc enabled. CSQC ents etc will be sent to this player.", 0, "\"csqcactive\""},
{"INFOKEY_P_PING", "const string", CS|QW|NQ, NULL, 0, "\"ping\""},
{"INFOKEY_P_SVPING", "const string", QW|NQ, NULL, 0, "\"svping\""},
{"INFOKEY_P_GUID", "const string", QW|NQ, "Some hash string which should be reasonably unique to this player's quake installation.", 0, "\"guid\""},
{"INFOKEY_P_CHALLENGE", "const string", QW|NQ, NULL, 0, "\"challenge\""},
@ -10386,6 +10426,18 @@ void PR_DumpPlatform_f(void)
{"INFOKEY_P_DOWNLOADPCT","const string",QW|NQ, NULL, 0, "\"download\""},
{"INFOKEY_P_TRUSTLEVEL","const string", QW|NQ, NULL, 0, "\"trustlevel\""},
{"INFOKEY_P_PROTOCOL", "const string", QW|NQ, "The network protocol the client is using to connect to the server.", 0, "\"protocol\""},
{"INFOKEY_P_VIP", "const string", QW|NQ, "1 if the player has the VIP 'penalty'.", 0, "\"*VIP\""},
{"INFOKEY_P_ISMUTED", "const string", QW|NQ, "1 if the player has the 'mute' penalty and is not allowed to use the say/say_team commands.", 0, "\"*ismuted\""},
{"INFOKEY_P_ISDEAF", "const string", QW|NQ, "1 if the player has the 'deaf' penalty and cannot see other people's say/say_team commands.", 0, "\"*isdeaf\""},
{"INFOKEY_P_ISCRIPPLED","const string", QW|NQ, "1 if the player has the cripple penalty, and their movement values are ignored (.movement is locked to 0).", 0, "\"*ismuted\""},
{"INFOKEY_P_ISCUFFED", "const string", QW|NQ, "1 if the player has the cuff penalty, and is unable to attack or use impulses(.button0 and .impulse fields are locked to 0).", 0, "\"*ismuted\""},
{"INFOKEY_P_ISLAGGED", "const string", QW|NQ, "1 if the player has the fakelag penalty and has an extra 200ms of lag.", 0, "\"*ismuted\""},
{"INFOKEY_P_PING", "const string", CS|QW|NQ, "The player's ping time, in milliseconds.", 0, "\"ping\""},
{"INFOKEY_P_NAME", "const string", CS|QW|NQ, "The player's name.", 0, "\"name\""},
{"INFOKEY_P_TOPCOLOR", "const string", CS|QW|NQ, "The player's upper/shirt colour (palette index).", 0, "\"topcolor\""},
{"INFOKEY_P_BOTTOMCOLOR","const string", CS|QW|NQ, "The player's lower/pants/trouser colour (palette index).", 0, "\"bottomcolor\""},
{"INFOKEY_P_TOPCOLOR_RGB","const string", CS, "The player's upper/shirt colour as an rgb value in a format usable with stov.", 0, "\"topcolor_rgb\""},
{"INFOKEY_P_BOTTOMCOLOR_RGB","const string", CS, "The player's lower/pants/trouser colour as an rgb value in a format usable with stov.", 0, "\"bottomcolor_rgb\""},
{"INFOKEY_P_MUTED", "const string", CS, "0: we can see the result of the player's say/say_team commands. 1: we see no say/say_team messages from this player. Use the ignore command to toggle this value.", 0, "\"ignored\""},
{"INFOKEY_P_VOIP_MUTED","const string", CS, "0: we can hear this player when they speak (assuming voip is generally enabled). 1: we ignore everything this player says. Use cl_voip_mute to change the values.", 0, "\"vignored\""},
{"INFOKEY_P_ENTERTIME", "const string", CS, "Reads the timestamp at which the player entered the game, in terms of csqc's time global.", 0, "\"entertime\""},
@ -10413,8 +10465,8 @@ void PR_DumpPlatform_f(void)
{"FL_CLASS_DEPENDENT", "const float", H2, NULL, FL_CLASS_DEPENDENT},
{"MOVE_NORMAL", "const float", QW|NQ|CS, NULL, MOVE_NORMAL},
{"MOVE_NOMONSTERS", "const float", QW|NQ|CS, NULL, MOVE_NOMONSTERS},
{"MOVE_MISSILE", "const float", QW|NQ|CS, NULL, MOVE_MISSILE},
{"MOVE_NOMONSTERS", "const float", QW|NQ|CS, "The trace will ignore all non-solid_bsp entities.", MOVE_NOMONSTERS},
{"MOVE_MISSILE", "const float", QW|NQ|CS, "The trace will use a bbox size of +/- 15 against entities with FL_MONSTER set.", MOVE_MISSILE},
{"MOVE_HITMODEL", "const float", QW|NQ|CS, "Traces will impact the actual mesh of the model instead of merely their bounding box. Should generally only be used for tracelines. Note that this flag is unreliable as an object can animate through projectiles. The bounding box MUST be set to completely encompass the entity or those extra areas will be non-solid (leaving a hole for things to go through).", MOVE_HITMODEL},
{"MOVE_TRIGGERS", "const float", QW|NQ|CS, "This trace type will impact only triggers. It will ignore non-solid entities.", MOVE_TRIGGERS},
{"MOVE_EVERYTHING", "const float", QW|NQ|CS, "This type of trace will hit solids and triggers alike. Even non-solid entities.", MOVE_EVERYTHING},

View File

@ -1640,6 +1640,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
SV_MVD_SendInitialGamestate(NULL);
SSV_UpdateAddresses();
//some mods stuffcmd these, and it would be a shame if they didn't work. we still need the earlier call in case the mod does extra stuff.
SV_SetMoveVars();
}
#endif

View File

@ -74,12 +74,14 @@ realcheck:
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*movevars.stepheight;
savedhull = ent->xv->hull;
ent->xv->hull = 0;
ent->xv->hull = 0; //stop the hull from breaking tracelines
trace = World_Move (world, start, vec3_origin, vec3_origin, stop, true, ent);
ent->xv->hull = savedhull;
if (trace.fraction == 1.0)
{
ent->xv->hull = savedhull;
return false;
}
mid = bottom = trace.endpos[2];
// the corners must be within 16 of the midpoint
@ -89,18 +91,19 @@ realcheck:
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
savedhull = ent->xv->hull;
ent->xv->hull = 0;
trace = World_Move (world, start, vec3_origin, vec3_origin, stop, true, ent);
ent->xv->hull = savedhull;
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
if (trace.fraction == 1.0 || mid - trace.endpos[2] > movevars.stepheight)
{
ent->xv->hull = savedhull;
return false;
}
}
c_yes++;
ent->xv->hull = savedhull;
return true;
}

View File

@ -62,7 +62,7 @@ cvar_t sv_stepheight = CVARAFD("pm_stepheight", "", "sv_stepheight", CVAR_SERV
cvar_t pm_ktjump = CVARF("pm_ktjump", "", CVAR_SERVERINFO);
cvar_t pm_bunnyspeedcap = CVARFD("pm_bunnyspeedcap", "", CVAR_SERVERINFO, "0 or 1, ish. If the player is traveling faster than this speed while turning, their velocity will be gracefully reduced to match their current maxspeed. You can still rocket-jump to gain high velocity, but turning will reduce your speed back to the max. This can be used to disable bunny hopping.");
cvar_t pm_watersinkspeed = CVARFD("pm_watersinkspeed", "", CVAR_SERVERINFO, "This is the speed tht players will sink at while inactive in water. Empty means 60.");
cvar_t pm_watersinkspeed = CVARFD("pm_watersinkspeed", "", CVAR_SERVERINFO, "This is the speed that players will sink at while inactive in water. Empty means 60.");
cvar_t pm_slidefix = CVARF("pm_slidefix", "", CVAR_SERVERINFO);
cvar_t pm_slidyslopes = CVARF("pm_slidyslopes", "", CVAR_SERVERINFO);
cvar_t pm_airstep = CVARF("pm_airstep", "", CVAR_SERVERINFO);
@ -728,7 +728,7 @@ static qboolean WPhys_PushAngles (world_t *w, wedict_t *pusher, vec3_t move, vec
// if it is ok to leave in the old position, do it
// this is only relevent for riding entities, not pushed
// FIXME: this doesn't acount for rotation
VectorCopy (pushed_p->origin, check->v->origin);
VectorCopy (pushed_p[-1].origin, check->v->origin);
block = World_TestEntityPosition (w, check);
if (!block)
{
@ -746,9 +746,9 @@ static qboolean WPhys_PushAngles (world_t *w, wedict_t *pusher, vec3_t move, vec
for (i = 0; i < 8 && block; i++)
{
//precision errors can strike when you least expect it. lets try and reduce them.
check->v->origin[0] = check->v->origin[0] + ((i&1)?-1:1)/8.0;
check->v->origin[1] = check->v->origin[1] + ((i&2)?-1:1)/8.0;
check->v->origin[2] = check->v->origin[2] + ((i&4)?-1:1)/8.0;
check->v->origin[0] = move[0] + ((i&1)?-1:1)/8.0;
check->v->origin[1] = move[1] + ((i&2)?-1:1)/8.0;
check->v->origin[2] = move[2] + ((i&4)?-1:1)/8.0;
block = World_TestEntityPosition (w, check);
}
if (!block)
@ -904,19 +904,35 @@ static qboolean WPhys_Push (world_t *w, wedict_t *pusher, vec3_t move, vec3_t am
continue;
}
if (block)
{
//try to nudge it forward by an epsilon to avoid precision issues
float movelen = VectorLength(move);
VectorMA(check->v->origin, (1/8.0)/movelen, move, check->v->origin);
block = World_TestEntityPosition (w, check);
if (!block)
{ //okay, that got it. we're all good.
World_LinkEdict (w, check, false);
continue;
}
}
// if it is ok to leave in the old position, do it
VectorSubtract (check->v->origin, move, check->v->origin);
VectorCopy (moved_from[num_moved-1], check->v->origin);
block = World_TestEntityPosition (w, check);
if (!block)
{
//if leaving it where it was, allow it to drop to the floor again (useful for plats that move downward)
check->v->flags = (int)check->v->flags & ~FL_ONGROUND;
if (check->v->movetype != MOVETYPE_WALK)
check->v->flags = (int)check->v->flags & ~FL_ONGROUND;
num_moved--;
continue;
}
// if it is still inside the pusher, block
// its blocking us. this is probably a problem.
//corpses
if (check->v->mins[0] == check->v->maxs[0])
{
World_LinkEdict (w, check, false);
@ -930,7 +946,7 @@ static qboolean WPhys_Push (world_t *w, wedict_t *pusher, vec3_t move, vec3_t am
continue;
}
//these pushes are contents brushes, and are not solid. water cannot crush. the player just enters the water.
//these pushers are contents brushes, and are not solid. water cannot crush. the player just enters the water.
//but, the player will be moved along with the water.
if (pusher->v->skin < 0)
continue;
@ -1280,7 +1296,8 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
if (trace.allsolid)
{
trace.fraction = 0;
if (progstype != PROG_H2)
trace.fraction = 0;
#pragma warningmsg("The following line might help boost framerates a lot in rmq, not sure if they violate expected behaviour in other mods though - check that they're safe.")
VectorNegate(gravitydir, trace.plane.normal);

View File

@ -1020,7 +1020,7 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, const cha
if (extfield_mask & NQSND_VOLUME)
MSG_WriteByte (&sv.multicast, volume);
if (extfield_mask & NQSND_ATTENUATION)
MSG_WriteByte (&sv.multicast, attenuation*64);
MSG_WriteByte (&sv.multicast, bound(0, attenuation*64, 255));
if (extfield_mask & FTESND_PITCHADJ)
MSG_WriteByte (&sv.multicast, pitchadj);
if (extfield_mask & DPSND_LARGEENTITY)
@ -1058,7 +1058,7 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, const cha
if (qwflags & SND_VOLUME)
MSG_WriteByte (&sv.multicast, volume);
if (qwflags & SND_ATTENUATION)
MSG_WriteByte (&sv.multicast, attenuation*64);
MSG_WriteByte (&sv.multicast, bound(0, attenuation*64, 255));
MSG_WriteByte (&sv.multicast, sound_num);
for (i=0 ; i<3 ; i++)
MSG_WriteCoord (&sv.multicast, origin[i]);
@ -1075,7 +1075,7 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, const cha
if (extfield_mask & NQSND_VOLUME)
MSG_WriteByte (&sv.nqmulticast, volume);
if (extfield_mask & NQSND_ATTENUATION)
MSG_WriteByte (&sv.nqmulticast, attenuation*64);
MSG_WriteByte (&sv.nqmulticast, bound(0, attenuation*64, 255));
if (extfield_mask & FTESND_PITCHADJ)
MSG_WriteByte (&sv.nqmulticast, pitchadj);
if (extfield_mask & DPSND_LARGEENTITY)