added cl_sendguid cvar, defaulting to 0. this disables the guid feature by default.

reworked a few q2 particle effects. q2 should feel a bit better now. by no means complete.
ssqcless csqc should have time progressing.
q3ui+console should be a bit less stupid.
stripped old huffman code. copied over from ioquake3. should help avoid bugs in that shit.
system mouse cursor should now always be hidden when running windowed. soft-cursor only.
added bindlist.lst feature.
particle system can now support weighted/randomized sounds. model command now more verbose, and supports renderflags.
renamed debugger cvar to pr_debugger, in the hopes that it'll be easier to find. also added to menu a little more visibly in a politically-motivated move.
fix q2+viewsize 30
'high' particles now have scrag+hknight impact effects. perhaps I overdid the scrag one.
fixed q2 player icons on the scoreboard.
added q3bsp_surf_meshcollision_* cvars.
dedicated servers now use the same bsp etc loading code as clients. the dedicated-server-only stuff is no longer needed, which is a good thing because it seemed a little buggy last time I tried.
split vertex+fragment shader compilation, for systems that secretly thread that.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4651 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-05-10 13:42:13 +00:00
parent 88994352f8
commit 589b09ae1d
54 changed files with 2891 additions and 1912 deletions

View File

@ -1769,6 +1769,11 @@ void CL_SendCmd (double frametime, qboolean mainloop)
if (fullsend)
{
if (!cls.state)
{
msecs -= (double)msecstouse;
return;
}
switch (cls.protocol)
{
#ifdef NQPROT

View File

@ -142,6 +142,7 @@ cvar_t cl_gunanglex = CVAR("cl_gunanglex", "0");
cvar_t cl_gunangley = CVAR("cl_gunangley", "0");
cvar_t cl_gunanglez = CVAR("cl_gunanglez", "0");
cvar_t cl_sendguid = CVARD("cl_sendguid", "0", "Send a randomly generated 'globally unique' id to servers, which can be used by servers for score rankings and stuff. Different servers will see different guids. Delete the 'qkey' file in order to appear as a different user.");
cvar_t cl_download_csprogs = CVARFD("cl_download_csprogs", "1", CVAR_NOTFROMSERVER, "Download updated client gamecode if available. Warning: If you clear this to avoid downloading vm code, you should also clear cl_download_packages.");
cvar_t cl_download_redirection = CVARFD("cl_download_redirection", "2", CVAR_NOTFROMSERVER, "Follow download redirection to download packages instead of individual files. 2 allows redirection only to named packages files. Also allows the server to send nearly arbitary download commands.");
cvar_t cl_download_mapsrc = CVARD("cl_download_mapsrc", "", "Specifies an http location prefix for map downloads. EG: \"http://bigfoot.morphos-team.net/misc/quakemaps/\"");
@ -225,7 +226,7 @@ static struct
qboolean istransfer; //ignore the user's desired server (don't change connect.adr).
netadr_t adr; //address that we're trying to transfer to.
int mtu;
qboolean compress;
unsigned int compresscrc;
int protocol; //tracked as part of guesswork based upon what replies we get.
int challenge; //tracked as part of guesswork based upon what replies we get.
double time; //for connection retransmits
@ -395,6 +396,9 @@ char *CL_GUIDString(netadr_t *adr)
void *blocks[2];
int lens[2];
if (!cl_sendguid.ival)
return NULL;
if (*connectinfo.guid && connectinfo.istransfer)
return connectinfo.guid;
@ -606,11 +610,11 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
if (compressioncrc && net_compress.ival && Huff_CompressionCRC(compressioncrc))
{
Q_strncatz(data, va("0x%x 0x%x\n", PROTOCOL_VERSION_HUFFMAN, LittleLong(compressioncrc)), sizeof(data));
connectinfo.compress = true;
connectinfo.compresscrc = compressioncrc;
}
else
#endif
connectinfo.compress = false;
connectinfo.compresscrc = 0;
info = CL_GUIDString(to);
if (info)
@ -790,7 +794,12 @@ void CL_CheckForResend (void)
connectinfo.trying = false;
}
else
{
if (!connectinfo.challenge)
connectinfo.challenge = rand();
cls.challenge = connectinfo.challenge;
CL_SendConnectPacket (NULL, 8192-16, pext1, pext2, false);
}
return;
}
#endif
@ -1339,6 +1348,7 @@ void CL_ClearState (void)
cl.oldgametime = 0;
cl.gametime = 0;
cl.gametimemark = 0;
cl.splitclients = 1;
}
/*
@ -1490,6 +1500,8 @@ void CL_Disconnect_f (void)
#endif
CL_Disconnect ();
connectinfo.trying = false;
}
/*
@ -2735,7 +2747,11 @@ client_connect: //fixme: make function
cls.challenge = connectinfo.challenge;
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, cls.qport);
cls.netchan.fragmentsize = connectinfo.mtu;
cls.netchan.compress = connectinfo.compress;
#ifdef HUFFNETWORK
cls.netchan.compresstable = Huff_CompressionCRC(connectinfo.compresscrc);
#else
cls.netchan.compresstable = NULL;
#endif
CL_ParseEstablished();
#ifdef Q3CLIENT
if (cls.protocol != CP_QUAKE3)
@ -2885,7 +2901,7 @@ void CLNQ_ConnectionlessPacket(void)
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, cls.qport);
CL_ParseEstablished();
cls.netchan.isnqprotocol = true;
cls.netchan.compress = 0;
cls.netchan.compresstable = NULL;
cls.protocol = CP_NETQUAKE;
cls.state = ca_connected;
Con_TPrintf ("Connected.\n");
@ -3422,6 +3438,7 @@ void CL_Init (void)
Cvar_Register (&cfg_save_name, cl_controlgroup);
Cvar_Register (&cl_sendguid, cl_controlgroup);
Cvar_Register (&cl_defaultport, cl_controlgroup);
Cvar_Register (&cl_servername, cl_controlgroup);
Cvar_Register (&cl_serveraddress, cl_controlgroup);
@ -3696,6 +3713,7 @@ void VARGS Host_EndGame (char *message, ...)
CL_Disconnect ();
SV_UnspawnServer();
connectinfo.trying = false;
Cvar_Set(&cl_shownet, "0");
@ -4422,7 +4440,8 @@ double Host_Frame (double time)
// resend a connection request if necessary
if (cls.state == ca_disconnected)
{
IN_Move(NULL, 0, time);
CL_SendCmd (host_frametime, true);
// IN_Move(NULL, 0, time);
CL_CheckForResend ();
#ifdef VOICECHAT

View File

@ -4540,41 +4540,41 @@ void CLQ2_ParseMuzzleFlash (void)
switch (weapon)
{
case Q2MZ_BLASTER:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_BLUEHYPERBLASTER:
dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 0.2;
dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_HYPERBLASTER:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_MACHINEGUN:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
break;
case Q2MZ_SHOTGUN:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0);
Q2S_StartSound (NULL, i, CHAN_AUTO, S_PrecacheSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1);
break;
case Q2MZ_SSHOTGUN:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_CHAINGUN1:
dl->radius = 200 + (rand()&31);
dl->color[0] = 0.2;dl->color[1] = 0.05;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 0.25;dl->color[2] = 0;
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
break;
case Q2MZ_CHAINGUN2:
dl->radius = 225 + (rand()&31);
dl->color[0] = 0.2;dl->color[1] = 0.1;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
dl->die = cl.time + 0.1; // long delay
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
@ -4583,7 +4583,7 @@ void CLQ2_ParseMuzzleFlash (void)
break;
case Q2MZ_CHAINGUN3:
dl->radius = 250 + (rand()&31);
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
dl->die = cl.time + 0.1; // long delay
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
@ -4594,92 +4594,92 @@ void CLQ2_ParseMuzzleFlash (void)
break;
case Q2MZ_RAILGUN:
dl->color[0] = 0.1;dl->color[1] = 0.1;dl->color[2] = 0.2;
dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_ROCKET:
dl->color[0] = 0.2;dl->color[1] = 0.1;dl->color[2] = 0.04;
dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0);
Q2S_StartSound (NULL, i, CHAN_AUTO, S_PrecacheSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1);
break;
case Q2MZ_GRENADE:
dl->color[0] = 0.2;dl->color[1] = 0.1;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0);
Q2S_StartSound (NULL, i, CHAN_AUTO, S_PrecacheSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1);
break;
case Q2MZ_BFG:
dl->color[0] = 0;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_LOGIN:
dl->color[0] = 0;dl->color[1] = 0.2; dl->color[2] = 0;
dl->color[0] = 0;dl->color[1] = 1; dl->color[2] = 0;
dl->die = cl.time + 1.0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
// CL_LogoutEffect (pl->current.origin, weapon);
break;
case Q2MZ_LOGOUT:
dl->color[0] = 0.2;dl->color[1] = 0; dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 0; dl->color[2] = 0;
dl->die = cl.time + 1.0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
// CL_LogoutEffect (pl->current.origin, weapon);
break;
case Q2MZ_RESPAWN:
dl->color[0] = 0.2;dl->color[1] = 0.2; dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1; dl->color[2] = 0;
dl->die = cl.time + 1.0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
// CL_LogoutEffect (pl->current.origin, weapon);
break;
// RAFAEL
case Q2MZ_PHALANX:
dl->color[0] = 0.2;dl->color[1] = 0.1; dl->color[2] = 0.1;
dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/plasshot.wav"), volume, ATTN_NORM, 0);
break;
// RAFAEL
case Q2MZ_IONRIPPER:
dl->color[0] = 0.2;dl->color[1] = 0.1; dl->color[2] = 0.1;
dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/rippfire.wav"), volume, ATTN_NORM, 0);
break;
// ======================
// PGM
case Q2MZ_ETF_RIFLE:
dl->color[0] = 0.18;dl->color[1] = 0.14;dl->color[2] = 0;
dl->color[0] = 0.9;dl->color[1] = 0.7;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/nail1.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_SHOTGUN2:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/shotg2.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_HEATBEAM:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
dl->die = cl.time + 100;
// Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_BLASTER2:
dl->color[0] = 0;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
// FIXME - different sound for blaster2 ??
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_TRACKER:
// negative flashes handled the same in gl/soft until CL_AddDLights
dl->color[0] = -0.2;dl->color[1] = -0.2;dl->color[2] = -0.2;
dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1;
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound("weapons/disint2.wav"), volume, ATTN_NORM, 0);
break;
case Q2MZ_NUKE1:
dl->color[0] = 0.2;dl->color[1] = 0;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 0;dl->color[2] = 0;
dl->die = cl.time + 100;
break;
case Q2MZ_NUKE2:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
dl->die = cl.time + 100;
break;
case Q2MZ_NUKE4:
dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 0.2;
dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1;
dl->die = cl.time + 100;
break;
case Q2MZ_NUKE8:
dl->color[0] = 0;dl->color[1] = 0.2;dl->color[2] = 0.2;
dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 1;
dl->die = cl.time + 100;
break;
// PGM

View File

@ -170,7 +170,7 @@ q2trace_t VARGS CLQ2_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end
trace_t t;
// check against world
t = CM_BoxTrace (cl.worldmodel, start, end, mins, maxs, MASK_PLAYERSOLID);
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, mins, maxs, MASK_PLAYERSOLID, &t);
if (t.fraction < 1.0)
t.ent = (struct edict_s *)1;
@ -535,7 +535,9 @@ short LerpAngles16(short to, short from, float frac)
void CL_CalcClientTime(void)
{
extern float demtime;
if (cls.protocol != CP_QUAKE3)
if (!cls.state)
cl.servertime += host_frametime;
else if (cls.protocol != CP_QUAKE3)
{
float oldst = realtime;

View File

@ -1719,12 +1719,13 @@ void SCR_SetUpToDrawConsole (void)
//go fullscreen if we're not doing anything
#ifdef VM_UI
if (UI_MenuState() || UI_OpenMenu())
;
scr_con_current = scr_conlines = 0;
else
#endif
if (cls.state < ca_demostart)
Key_Dest_Add(kdm_console);
scr_con_current = scr_conlines = vid.height * fullscreenpercent;
if (Key_Dest_Has(kdm_console))
scr_con_current = scr_conlines = vid.height * fullscreenpercent;
}
else if (Key_Dest_Has(kdm_console) || scr_chatmode)
{

View File

@ -461,14 +461,28 @@ void CL_RegisterParticles(void)
ptqw_blood = P_FindParticleType("TE_BLOOD");
ptqw_lightningblood = P_FindParticleType("TE_LIGHTNINGBLOOD");
ptq2_blood = P_FindParticleType("TE_BLOOD");
rtq2_railtrail = P_FindParticleType("TR_RAILTRAIL");
rtq2_blastertrail = P_FindParticleType("TR_BLASTERTRAIL");
ptq2_blasterparticles = P_FindParticleType("TE_BLASTERPARTICLES");
rtq2_bubbletrail = P_FindParticleType("TE_BUBBLETRAIL");
rtq2_gib = P_FindParticleType("TR_GIB");
rtq2_rocket = P_FindParticleType("TR_ROCKET");
rtq2_grenade = P_FindParticleType("TR_GRENADE");
if (cls.protocol == CP_QUAKE2)
{
ptq2_blood = P_FindParticleType("q2part.TEQ2_BLOOD");
rtq2_railtrail = P_FindParticleType("q2part.TR_RAILTRAIL");
rtq2_blastertrail = P_FindParticleType("q2part.TR_BLASTERTRAIL");
ptq2_blasterparticles = P_FindParticleType("TE_BLASTERPARTICLES");
rtq2_bubbletrail = P_FindParticleType("TE_BUBBLETRAIL");
rtq2_gib = P_FindParticleType("TR_GIB");
rtq2_rocket = P_FindParticleType("TR_ROCKET");
rtq2_grenade = P_FindParticleType("TR_GRENADE");
}
else
{
ptq2_blood = P_INVALID;
rtq2_railtrail = P_INVALID;
rtq2_blastertrail = P_INVALID;
ptq2_blasterparticles = P_INVALID;
rtq2_bubbletrail = P_INVALID;
rtq2_gib = P_INVALID;
rtq2_rocket = P_INVALID;
rtq2_grenade = P_INVALID;
}
rtqw_railtrail = P_FindParticleType("TE_RAILTRAIL");
rtfte_lightning1 = P_FindParticleType("TE_LIGHTNING1");
@ -2162,11 +2176,9 @@ 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, int traileffect)
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, vec3_t orientationup, model_t *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity, int traileffect, unsigned int renderflags)
{
explosion_t *ex;
vec3_t spos;
float dlen;
ex = CL_AllocExplosion (org);
ex->start = cl.time;
@ -2177,14 +2189,16 @@ void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe
ex->skinnum = 0;
ex->traileffect = traileffect;
if (alpha >= -1 && alpha < 1)
ex->flags |= RF_TRANSLUCENT;
ex->flags |= renderflags;
//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 (ex->endalpha < 1 || ex->startalpha < 1)
ex->flags |= RF_TRANSLUCENT;
if (randspin)
{
ex->angles[0] = frandom()*360;
@ -2197,12 +2211,30 @@ void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe
}
ex->gravity = gravity;
if (orientationup)
{
ex->angles[0] = acos(orientationup[2])/M_PI*180;
if (orientationup[0])
ex->angles[1] = atan2(orientationup[1], orientationup[0])/M_PI*180;
else if (orientationup[1] > 0)
ex->angles[1] = 90;
else if (orientationup[1] < 0)
ex->angles[1] = 270;
else
ex->angles[1] = 0;
ex->angles[0]*=-1;
}
if (dir)
{
// vec3_t spos;
// float dlen;
// dlen = -10/VectorLength(dir);
// VectorMA(ex->origin, dlen, dir, spos);
// TraceLineN(spos, org, ex->origin, NULL);
VectorCopy(dir, ex->velocity);
dlen = -10/VectorLength(dir);
VectorMA(ex->origin, dlen, dir, spos);
TraceLineN(spos, org, ex->origin, NULL);
}
else
VectorClear(ex->velocity);
@ -2237,7 +2269,7 @@ void CL_ParseEffect (qboolean effect2)
framerate = MSG_ReadByte();
mod = cl.model_precache[modelindex];
CL_SpawnSpriteEffect(org, vec3_origin, mod, startframe, framecount, framerate, mod->type==mod_sprite?-1:1, 0, 0, P_INVALID);
CL_SpawnSpriteEffect(org, NULL, NULL, mod, startframe, framecount, framerate, mod->type==mod_sprite?-1:1, 0, 0, P_INVALID, 0);
}
#ifdef Q2CLIENT
@ -2302,6 +2334,43 @@ void CLQ2_ParseTEnt (void)
switch (type)
{
case Q2TE_GUNSHOT:
MSG_ReadPos (pos);
MSG_ReadDir (dir);
P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_gunshot");
break;
case Q2TE_BLOOD:
MSG_ReadPos (pos);
MSG_ReadDir (dir);
P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_blood");
break;
case Q2TE_SHOTGUN:
MSG_ReadPos (pos);
MSG_ReadDir (dir);
P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_shotgun");
break;
case Q2TE_BLASTER:
MSG_ReadPos (pos);
MSG_ReadDir (dir);
P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_blaster");
break;
case Q2TE_RAILTRAIL: // railgun effect
MSG_ReadPos (pos);
MSG_ReadPos (pos2);
if (P_ParticleTrail(pos, pos2, rtq2_railtrail, 0, NULL))
P_ParticleTrailIndex(pos, pos2, 0x74, 8, NULL);
Q2S_StartSound (pos, 0, 0, S_PrecacheSound ("weapons/railgf1a.wav"), 1, ATTN_NORM, 0);
break;
default:
goto fixme;
// Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type);
// break;
}
return;
fixme:
switch(type)
{
case Q2TE_BLOOD: // bullet hitting flesh
MSG_ReadPos (pos);
MSG_ReadDir (dir);

View File

@ -909,7 +909,6 @@ extern unsigned int cl_maxstris;
extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], soundlist_name[];
qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
qboolean Q2TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
//
// cl_input
@ -1086,7 +1085,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, int traileffect); /*called from the particlesystem*/
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, vec3_t orientationup, struct model_s *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity, int traileffect, unsigned int renderflags); /*called from the particlesystem*/
//
// cl_ents.c

View File

@ -118,11 +118,6 @@ void CLQ2_ClearState(void)
memset(cl_entities, 0, sizeof(cl_entities));
}
//extern struct model_s *cl_mod_powerscreen;
//PGM
int vidref_val;
//PGM
#include "q2m_flash.c"
void CLQ2_RunMuzzleFlash2 (int ent, int flash_number)
{
@ -130,12 +125,25 @@ void CLQ2_RunMuzzleFlash2 (int ent, int flash_number)
dlight_t *dl;
vec3_t forward, right, up;
char soundname[64];
int ef;
if (flash_number < 0 || flash_number >= sizeof(monster_flash_offset)/sizeof(monster_flash_offset[0]))
return;
// locate the origin
AngleVectors (cl_entities[ent].current.angles, forward, right, up);
origin[0] = cl_entities[ent].current.origin[0] + forward[0] * monster_flash_offset[flash_number][0] + right[0] * monster_flash_offset[flash_number][1];
origin[1] = cl_entities[ent].current.origin[1] + forward[1] * monster_flash_offset[flash_number][0] + right[1] * monster_flash_offset[flash_number][1];
origin[2] = cl_entities[ent].current.origin[2] + forward[2] * monster_flash_offset[flash_number][0] + right[2] * monster_flash_offset[flash_number][1] + monster_flash_offset[flash_number][2];
origin[0] = cl_entities[ent].current.origin[0] + forward[0] * monster_flash_offset[flash_number].offset[0] + right[0] * monster_flash_offset[flash_number].offset[1];
origin[1] = cl_entities[ent].current.origin[1] + forward[1] * monster_flash_offset[flash_number].offset[0] + right[1] * monster_flash_offset[flash_number].offset[1];
origin[2] = cl_entities[ent].current.origin[2] + forward[2] * monster_flash_offset[flash_number].offset[0] + right[2] * monster_flash_offset[flash_number].offset[1] + monster_flash_offset[flash_number].offset[2];
ef = P_FindParticleType(monster_flash_offset[flash_number].name);
if (ef != P_INVALID)
{
P_RunParticleEffectType(origin, NULL, 1, ef);
return;
}
//the rest of the function is legacy code.
dl = CL_AllocDlight (ent);
VectorCopy (origin, dl->origin);
@ -491,9 +499,6 @@ void CLQ2_RunMuzzleFlash2 (int ent, int flash_number)
//hmm... he must take AGES on the loo.... :p
}
dl->color[0] /= 5;
dl->color[1] /= 5;
dl->color[2] /= 5;
}
/*
@ -1310,9 +1315,6 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
ent.model = player->model;
if (!ent.model || ent.model->needload) //we need to do better than this
{
char *pmodel = Info_ValueForKey(player->userinfo, "model");
if (*pmodel)
ent.model = Mod_ForName(va("players/%s/tris.md2", pmodel), MLV_WARN);
if (!ent.model || ent.model->needload)
ent.model = Mod_ForName("players/male/tris.md2", MLV_SILENT);
}

View File

@ -568,7 +568,7 @@ void CLQ3_ParseGameState(void)
switch(c)
{
default:
Host_EndGame("CLQ3_ParseGameState: bad command byte");
Host_EndGame("CLQ3_ParseGameState: bad command byte %i", c);
break;
case svcq3_configstring:
@ -753,7 +753,7 @@ qboolean CLQ3_Netchan_Process(void)
{
c = '.';
}
bitmask ^= c << (i & 1);
bitmask ^= c << ((i-msg_readcount) & 1);
net_message.data[i] ^= bitmask;
}
#endif
@ -1060,8 +1060,14 @@ void CLQ3_SendConnectPacket(netadr_t *to)
msg.maxsize = sizeof(data);
MSG_WriteLong(&msg, -1);
MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", cls.challenge, cls.qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), &net_local_cl_ipadr), cls.userinfo[0]));
#ifdef HUFFNETWORK
Huff_EncryptPacket(&msg, 12);
Huff_PreferedCompressionCRC();
if (!Huff_CompressionCRC(HUFFCRC_QUAKE3))
{
Con_Printf("Huffman compression error\n");
return;
}
#endif
NET_SendPacket (NS_CLIENT, msg.cursize, msg.data, to);
}
#endif

View File

@ -528,7 +528,7 @@ void INS_UpdateGrabs(int fullscreen, int activeapp)
grabmouse = false;
//visiblity
if (grabmouse)
if (grabmouse || (mousecursor_x > 0 && mousecursor_y > 0 && mousecursor_x < vid.pixelwidth && mousecursor_y < vid.pixelheight))
INS_HideMouse();
else
INS_ShowMouse();

View File

@ -1995,7 +1995,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
{
#ifdef VM_UI
#ifdef TEXTEDITOR
if (!Key_Dest_Has(~kdm_game))
if (!Key_Dest_Has(~kdm_game) && !Key_Dest_Has(kdm_console))
#endif
{
if (down && Media_PlayingFullScreen())
@ -2013,9 +2013,8 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
if (Key_Dest_Has(kdm_console))
{
if (cls.state || Key_Dest_Has(~(kdm_console|kdm_game)))
Key_Dest_Remove(kdm_console);
else
Key_Dest_Remove(kdm_console);
if (!cls.state && !Key_Dest_Has(~kdm_game))
M_ToggleMenu_f ();
}
#ifdef TEXTEDITOR

View File

@ -377,6 +377,7 @@ void M_Menu_Keys_f (void)
menu_t *menu;
int mgt;
extern cvar_t cl_splitscreen, cl_forcesplitclient;
vfsfile_t *bindslist;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
@ -428,6 +429,20 @@ void M_Menu_Keys_f (void)
y+=8;
}
bindslist = FS_OpenVFS("bindlist.lst", "rb", FS_GAME);
if (bindslist)
{
char line[1024];
while(VFS_GETS(bindslist, line, sizeof(line)))
{
Cmd_TokenizeString(line, false, false);
MC_AddBind(menu, 16, 170, y, Cmd_Argv(1), Cmd_Argv(0));
y += 8;
}
VFS_CLOSE(bindslist);
return;
}
while (bindnames->name)
{
MC_AddBind(menu, 16, 170, y, bindnames->name, bindnames->command);

View File

@ -178,7 +178,17 @@ typedef struct {
float framerate;
float alpha;
int traileffect;
unsigned int rflags;
#define RF_USEORIENTATION Q2RF_CUSTOMSKIN //private flag
} partmodels_t;
typedef struct {
char name[MAX_QPATH];
float vol;
float atten;
float delay;
float pitch;
float weight;
} partsounds_t;
// TODO: merge in alpha with rgb to gain benefit of vector opts
typedef struct part_type_s {
char name[MAX_QPATH];
@ -188,11 +198,8 @@ typedef struct part_type_s {
int nummodels;
partmodels_t *models;
char soundname[MAX_QPATH];
float soundvol;
float soundattn;
float sounddelay;
float soundpitch;
int numsounds;
partsounds_t *sounds;
vec3_t rgb; //initial colour
float alpha;
@ -208,8 +215,8 @@ typedef struct part_type_s {
float scalerand; //with up to this much extra
float die, randdie; //how long it lasts (plus some rand)
float randomvel, randomvelvert, randomvelvertbias; //random velocity (unaligned=worldspace)
float veladd; //scale the incoming velocity by this much
float orgadd; //spawn the particle this far along its velocity direction
float veladd, randomveladd; //scale the incoming velocity by this much
float orgadd, randomorgadd; //spawn the particle this far along its velocity direction
float spawnvel, spawnvelvert; //spawn the particle with a velocity based upon its spawn type (generally so it flies outwards)
vec3_t orgbias; //static 3d world-coord bias
@ -836,6 +843,8 @@ static void P_ResetToDefaults(part_type_t *ptype)
BZ_Free(ptype->ramp);
if (ptype->models)
BZ_Free(ptype->models);
if (ptype->sounds)
BZ_Free(ptype->sounds);
//reset everything we're too lazy to specifically set
memset(ptype, 0, sizeof(*ptype));
@ -1189,9 +1198,19 @@ static void P_ParticleEffect_f(void)
}
}
else if (!strcmp(var, "veladd"))
{
ptype->veladd = atof(value);
ptype->randomveladd = 0;
if (Cmd_Argc()>2)
ptype->randomveladd = atof(Cmd_Argv(2)) - ptype->veladd;
}
else if (!strcmp(var, "orgadd"))
{
ptype->orgadd = atof(value);
ptype->randomorgadd = 0;
if (Cmd_Argc()>2)
ptype->randomorgadd = atof(Cmd_Argv(2)) - ptype->orgadd;
}
else if (!strcmp(var, "friction"))
{
ptype->friction[2] = ptype->friction[1] = ptype->friction[0] = atof(value);
@ -1225,28 +1244,102 @@ 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;
partmodels_t *mod;
char *e;
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++;
mod = &ptype->models[ptype->nummodels++];
mod->framestart = 0;
mod->frameend = 1;
mod->framerate = 10;
mod->alpha = 1;
mod->traileffect = P_INVALID;
mod->rflags = RF_NOSHADOW;
strtoul(Cmd_Argv(2), &e, 0);
while(*e == ' ' || *e == '\t')
e++;
if (*e)
{
int p;
for(p = 2; p < Cmd_Argc(); p++)
{
e = Cmd_Argv(p);
if (!Q_strncasecmp(e, "framestart=", 11))
mod->framestart = atof(e+11);
else if (!Q_strncasecmp(e, "frameend=", 9))
mod->frameend = atof(e+9);
else if (!Q_strncasecmp(e, "framerate=", 10))
mod->framerate = atof(e+10);
else if (!Q_strncasecmp(e, "alpha=", 6))
mod->alpha = atof(e+6);
else if (!Q_strncasecmp(e, "trail=", 6))
{
mod->traileffect = P_AllocateParticleType(config, e+6);//careful - this can realloc all the particle types
ptype = &part_type[pnum];
}
else if (!Q_strncasecmp(e, "orient", 6))
mod->rflags |= RF_USEORIENTATION; //use the dir to orient the model, instead of always facing up.
else if (!Q_strncasecmp(e, "additive", 8))
mod->rflags |= RF_ADDITIVE; //additive blend
else if (!Q_strncasecmp(e, "transparent", 11))
mod->rflags |= RF_TRANSLUCENT; //force blend
else if (!Q_strncasecmp(e, "fullbright", 10))
mod->rflags |= Q2RF_FULLBRIGHT; //fullbright, woo
else if (!Q_strncasecmp(e, "shadow", 6))
mod->rflags &= ~RF_NOSHADOW; //clear noshadow
else if (!Q_strncasecmp(e, "noshadow", 8))
mod->rflags |= RF_NOSHADOW; //set noshadow (cos... you know...)
else
Con_Printf("Bad named argument: %s\n", e);
}
}
else
{
mod->framestart = atof(Cmd_Argv(2));
mod->frameend = atof(Cmd_Argv(3));
mod->framerate = atof(Cmd_Argv(4));
mod->alpha = atof(Cmd_Argv(5));
if (*Cmd_Argv(6))
{
mod->traileffect = P_AllocateParticleType(config, Cmd_Argv(6));//careful - this can realloc all the particle types
ptype = &part_type[pnum];
}
else
mod->traileffect = P_INVALID;
}
}
else if (!strcmp(var, "sound"))
{
ptype->sounds = BZ_Realloc(ptype->sounds, sizeof(partsounds_t)*(ptype->numsounds+1));
Q_strncpyz(ptype->sounds[ptype->numsounds].name, Cmd_Argv(1), sizeof(ptype->sounds[ptype->numsounds].name));
if (*ptype->sounds[ptype->numsounds].name)
S_PrecacheSound(ptype->sounds[ptype->numsounds].name);
ptype->sounds[ptype->numsounds].vol = atof(Cmd_Argv(2));
if (!ptype->sounds[ptype->numsounds].vol)
ptype->sounds[ptype->numsounds].vol = 1;
ptype->sounds[ptype->numsounds].atten = atof(Cmd_Argv(3));
if (!ptype->sounds[ptype->numsounds].atten)
ptype->sounds[ptype->numsounds].atten = 1;
ptype->sounds[ptype->numsounds].pitch = atof(Cmd_Argv(4));
if (!ptype->sounds[ptype->numsounds].pitch)
ptype->sounds[ptype->numsounds].pitch = 100;
ptype->sounds[ptype->numsounds].delay = atof(Cmd_Argv(5));
if (!ptype->sounds[ptype->numsounds].delay)
ptype->sounds[ptype->numsounds].delay = 0;
ptype->sounds[ptype->numsounds].weight = atof(Cmd_Argv(6));
if (!ptype->sounds[ptype->numsounds].weight)
ptype->sounds[ptype->numsounds].weight = 1;
ptype->numsounds++;
}
else if (!strcmp(var, "colorindex"))
{
if (Cmd_Argc()>2)
ptype->colorrand = atof(Cmd_Argv(2));
ptype->colorindex = atoi(value);
ptype->colorrand = strtoul(Cmd_Argv(2), NULL, 0);
ptype->colorindex = strtoul(value, NULL, 0);
}
else if (!strcmp(var, "colorrand"))
ptype->colorrand = atoi(value); // now obsolete
@ -1624,23 +1717,6 @@ static void P_ParticleEffect_f(void)
else if (!strcmp(var, "nospreadlast"))
ptype->flags |= PT_NOSPREADLAST;
else if (!strcmp(var, "sound"))
{
Q_strncpyz(ptype->soundname, value, sizeof(ptype->soundname));
ptype->soundvol = atof(Cmd_Argv(2));
if (!ptype->soundvol)
ptype->soundvol = 1;
ptype->soundattn = atof(Cmd_Argv(3));
if (!ptype->soundattn)
ptype->soundattn = 1;
ptype->soundpitch = atof(Cmd_Argv(4));
if (!ptype->soundpitch)
ptype->soundpitch = 100;
ptype->sounddelay = atof(Cmd_Argv(5));
if (!ptype->sounddelay)
ptype->sounddelay = 0;
}
else if (!strcmp(var, "lightradius"))
ptype->dl_radius = atof(value);
else if (!strcmp(var, "lightradiusfade"))
@ -1827,7 +1903,11 @@ 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 \"%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);
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->models[i].traileffect==P_INVALID?"":part_type[ptype->models[i].traileffect].name), outstrlen);
}
for (i = 0; i < ptype->numsounds; i++)
{
Q_strncatz(outstr, va("sound \"%s\" %g %g %g %g %g\n", ptype->sounds[i].name, ptype->sounds[i].vol, ptype->sounds[i].atten, ptype->sounds[i].pitch, ptype->sounds[i].delay, ptype->sounds[i].weight), outstrlen);
}
if (*ptype->texname)
@ -1910,10 +1990,10 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
if (ptype->areaspread || ptype->areaspreadvert)
Q_strncatz(outstr, va("spawnorg %g %g\n", ptype->areaspread, ptype->areaspreadvert), outstrlen);
if (ptype->veladd)
Q_strncatz(outstr, va("veladd %g\n", ptype->veladd), outstrlen);
if (ptype->orgadd)
Q_strncatz(outstr, va("orgadd %g\n", ptype->orgadd), outstrlen);
if (ptype->veladd || ptype->randomveladd)
Q_strncatz(outstr, va(ptype->randomveladd?"veladd %g %g\n":"veladd %g\n", ptype->veladd, ptype->veladd+ptype->randomveladd), outstrlen);
if (ptype->orgadd || ptype->randomorgadd)
Q_strncatz(outstr, va(ptype->randomorgadd?"orgadd %g %g\n":"orgadd %g\n", ptype->orgadd, ptype->orgadd+ptype->randomorgadd), outstrlen);
if (ptype->randomvel || ptype->randomvelvert || ptype->randomvelvertbias)
Q_strncatz(outstr, va("randomvel %g %g %g\n", ptype->randomvel, ptype->randomvelvertbias - ptype->randomvelvert, ptype->randomvelvertbias + ptype->randomvelvert), outstrlen);
@ -1923,9 +2003,6 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int 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);
if (ptype->soundvol)
Q_strncatz(outstr, va("sound \"%s\" %g %g %g %g\n", ptype->soundname, ptype->soundvol, ptype->soundattn, ptype->soundpitch, ptype->sounddelay), outstrlen);
if (ptype->dl_radius)
{
Q_strncatz(outstr, va("lightradius %g\n", ptype->dl_radius), outstrlen);
@ -2688,6 +2765,8 @@ static void PScript_Shutdown (void)
numparticletypes--;
if (part_type[numparticletypes].models)
BZ_Free(part_type[numparticletypes].models);
if (part_type[numparticletypes].sounds)
BZ_Free(part_type[numparticletypes].sounds);
if (part_type[numparticletypes].ramp)
BZ_Free(part_type[numparticletypes].ramp);
}
@ -3447,24 +3526,27 @@ static void PScript_ApplyOrgVel(vec3_t oorg, vec3_t ovel, vec3_t eforg, vec3_t e
oorg[1] = eforg[1] + arsvec[1];
oorg[2] = eforg[2] + arsvec[2];
k = ptype->orgadd + frandom()*ptype->randomorgadd;
l = ptype->veladd + frandom()*ptype->randomveladd;
// apply arsvec+ofsvec
if (efdir)
{
ovel[0] += efdir[0]*ptype->veladd+ofsvec[0]*ptype->spawnvel;
ovel[1] += efdir[1]*ptype->veladd+ofsvec[1]*ptype->spawnvel;
ovel[2] += efdir[2]*ptype->veladd+ofsvec[2]*ptype->spawnvelvert;
ovel[0] += efdir[0]*l+ofsvec[0]*ptype->spawnvel;
ovel[1] += efdir[1]*l+ofsvec[1]*ptype->spawnvel;
ovel[2] += efdir[2]*l+ofsvec[2]*ptype->spawnvelvert;
oorg[0] += efdir[0]*ptype->orgadd;
oorg[1] += efdir[1]*ptype->orgadd;
oorg[2] += efdir[2]*ptype->orgadd;
oorg[0] += efdir[0]*k;
oorg[1] += efdir[1]*k;
oorg[2] += efdir[2]*k;
}
else
{//efdir is effectively up - '0 0 -1'
ovel[0] += ofsvec[0]*ptype->spawnvel;
ovel[1] += ofsvec[1]*ptype->spawnvel;
ovel[2] += ofsvec[2]*ptype->spawnvelvert - ptype->veladd;
ovel[2] += ofsvec[2]*ptype->spawnvelvert - l;
oorg[2] -= ptype->orgadd;
oorg[2] -= k;
}
VectorAdd(oorg, ptype->orgbias, oorg);
}
@ -3487,7 +3569,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, mod->alpha?mod->alpha:1, ptype->rotationmin*180/M_PI, ptype->gravity, mod->traileffect);
CL_SpawnSpriteEffect(morg, mdir, (mod->rflags&RF_USEORIENTATION)?dir:NULL, 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, mod->rflags & ~RF_USEORIENTATION);
}
}
}
@ -3510,9 +3592,24 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, in
if (ptype->dl_cubemapnum)
snprintf(dl->cubemapname, sizeof(dl->cubemapname), "cubemaps/%i", ptype->dl_cubemapnum);
}
if (*ptype->soundname)
if (ptype->numsounds)
{
S_StartSound(0, 0, S_PrecacheSound(ptype->soundname), org, ptype->soundvol, ptype->soundattn, ptype->sounddelay, ptype->soundpitch);
int i;
float w,tw;
for (i = 0, tw = 0; i < ptype->numsounds; i++)
tw += ptype->sounds[i].weight;
w = frandom() * tw; //select the sound by weight
//and figure out which one that weight corresponds to
for (i = 0, tw = 0; i < ptype->numsounds; i++)
{
tw += ptype->sounds[i].weight;
if (w <= tw)
{
if (*ptype->sounds[i].name && ptype->sounds[i].vol > 0)
S_StartSound(0, 0, S_PrecacheSound(ptype->sounds[i].name), org, ptype->sounds[i].vol, ptype->sounds[i].atten, ptype->sounds[i].delay, ptype->sounds[i].pitch);
break;
}
}
}
if (ptype->stain_radius)
Surf_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius);
@ -3523,7 +3620,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
{
part_type_t *ptype = &part_type[typenum];
int i, j, k, l, spawnspc;
float m, pcount;
float m, pcount, orgadd, veladd;
particle_t *p;
beamseg_t *b, *bfirst;
vec3_t ofsvec, arsvec; // offsetspread vec, areaspread vec
@ -4036,23 +4133,25 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
p->org[2] = org[2] + arsvec[2];
// apply arsvec+ofsvec
orgadd = ptype->orgadd + frandom()*ptype->randomorgadd;
veladd = ptype->veladd + frandom()*ptype->randomveladd;
if (dir)
{
p->vel[0] += dir[0]*ptype->veladd+ofsvec[0]*ptype->spawnvel;
p->vel[1] += dir[1]*ptype->veladd+ofsvec[1]*ptype->spawnvel;
p->vel[2] += dir[2]*ptype->veladd+ofsvec[2]*ptype->spawnvelvert;
p->vel[0] += dir[0]*veladd+ofsvec[0]*ptype->spawnvel;
p->vel[1] += dir[1]*veladd+ofsvec[1]*ptype->spawnvel;
p->vel[2] += dir[2]*veladd+ofsvec[2]*ptype->spawnvelvert;
p->org[0] += dir[0]*ptype->orgadd;
p->org[1] += dir[1]*ptype->orgadd;
p->org[2] += dir[2]*ptype->orgadd;
p->org[0] += dir[0]*orgadd;
p->org[1] += dir[1]*orgadd;
p->org[2] += dir[2]*orgadd;
}
else
{
p->vel[0] += ofsvec[0]*ptype->spawnvel;
p->vel[1] += ofsvec[1]*ptype->spawnvel;
p->vel[2] += ofsvec[2]*ptype->spawnvelvert - ptype->veladd;
p->vel[2] += ofsvec[2]*ptype->spawnvelvert - veladd;
p->org[2] -= ptype->orgadd;
p->org[2] -= orgadd;
}
VectorAdd(p->org, ptype->orgbias, p->org);
@ -5607,12 +5706,7 @@ static void PScript_DrawParticleTypes (void)
VectorScale (vup, 1.5, pup);
VectorScale (vright, 1.5, pright);
#ifdef Q2BSPS
if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
tr = Q2TraceLineN;
else
#endif
tr = TraceLineN;
tr = TraceLineN;
kill_list = kill_first = NULL;

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, mdl->type==mod_sprite?-1:1, 0, 0, P_INVALID);
CL_SpawnSpriteEffect(org, NULL, NULL, mdl, startframe, endframe, framerate, mdl->type==mod_sprite?-1:1, 0, 0, P_INVALID, 0);
else
Con_Printf("PF_cl_effect: Couldn't load model %s\n", name);
}
@ -5658,12 +5658,12 @@ void CSQC_Breakpoint_f(void)
else
Con_Printf("Breakpoint has been cleared\n");
Cvar_Set(Cvar_FindVar("debugger"), "1");
Cvar_Set(Cvar_FindVar("pr_debugger"), "1");
}
static void CSQC_Poke_f(void)
{
if (!csqc_singlecheats)
if (!csqc_singlecheats && cls.state)
Con_Printf("%s is a cheat command\n", Cmd_Argv(0));
else if (csqcprogs)
Con_Printf("Result: %s\n", csqcprogs->EvaluateDebugString(csqcprogs, Cmd_Args()));

View File

@ -2109,7 +2109,7 @@ void MP_Breakpoint_f(void)
else
Con_Printf("Breakpoint has been cleared\n");
Cvar_Set(Cvar_FindVar("debugger"), "1");
Cvar_Set(Cvar_FindVar("pr_debugger"), "1");
}
void MP_RegisterCvarsAndCmds(void)

View File

@ -23,307 +23,308 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// this file is included in both the game dll and quake2,
// the game needs it to source shot locations, the client
// needs it to position muzzle flashes
vec3_t monster_flash_offset [] =
struct {
const char *name;
vec3_t offset;
} monster_flash_offset [] =
{
// flash 0 is not used
{ 0.0, 0.0, 0.0 },
// MZ2_TANK_BLASTER_1 1
{ 20.7, -18.5, 28.7 },
// MZ2_TANK_BLASTER_2 2
{ 16.6, -21.5, 30.1 },
{"MZ2_INVALID", {0.0, 0.0, 0.0}},
// MZ2_TANK_BLASTER_1
{"MZ2_TANK_BLASTER", {20.7, -18.5, 28.7}},
// MZ2_TANK_BLASTER_2
{"MZ2_TANK_BLASTER", {16.6, -21.5, 30.1}},
// MZ2_TANK_BLASTER_3 3
{ 11.8, -23.9, 32.1 },
{"MZ2_TANK_BLASTER", {11.8, -23.9, 32.1}},
// MZ2_TANK_MACHINEGUN_1 4
{ 22.9, -0.7, 25.3 },
{"MZ2_TANK_MACHINEGUN", {22.9, -0.7, 25.3}},
// MZ2_TANK_MACHINEGUN_2 5
{ 22.2, 6.2, 22.3 },
{"MZ2_TANK_MACHINEGUN", {22.2, 6.2, 22.3}},
// MZ2_TANK_MACHINEGUN_3 6
{ 19.4, 13.1, 18.6 },
{"MZ2_TANK_MACHINEGUN", {19.4, 13.1, 18.6}},
// MZ2_TANK_MACHINEGUN_4 7
{ 19.4, 18.8, 18.6 },
{"MZ2_TANK_MACHINEGUN", {19.4, 18.8, 18.6}},
// MZ2_TANK_MACHINEGUN_5 8
{ 17.9, 25.0, 18.6 },
{"MZ2_TANK_MACHINEGUN", {17.9, 25.0, 18.6}},
// MZ2_TANK_MACHINEGUN_6 9
{ 14.1, 30.5, 20.6 },
{"MZ2_TANK_MACHINEGUN", {14.1, 30.5, 20.6}},
// MZ2_TANK_MACHINEGUN_7 10
{ 9.3, 35.3, 22.1 },
{"MZ2_TANK_MACHINEGUN", {9.3, 35.3, 22.1}},
// MZ2_TANK_MACHINEGUN_8 11
{ 4.7, 38.4, 22.1 },
{"MZ2_TANK_MACHINEGUN", {4.7, 38.4, 22.1}},
// MZ2_TANK_MACHINEGUN_9 12
{ -1.1, 40.4, 24.1 },
{"MZ2_TANK_MACHINEGUN", {-1.1, 40.4, 24.1}},
// MZ2_TANK_MACHINEGUN_10 13
{ -6.5, 41.2, 24.1 },
{"MZ2_TANK_MACHINEGUN", {-6.5, 41.2, 24.1}},
// MZ2_TANK_MACHINEGUN_11 14
{ 3.2, 40.1, 24.7 },
{"MZ2_TANK_MACHINEGUN", {3.2, 40.1, 24.7}},
// MZ2_TANK_MACHINEGUN_12 15
{ 11.7, 36.7, 26.0 },
{"MZ2_TANK_MACHINEGUN", {11.7, 36.7, 26.0}},
// MZ2_TANK_MACHINEGUN_13 16
{ 18.9, 31.3, 26.0 },
{"MZ2_TANK_MACHINEGUN", {18.9, 31.3, 26.0}},
// MZ2_TANK_MACHINEGUN_14 17
{ 24.4, 24.4, 26.4 },
{"MZ2_TANK_MACHINEGUN", {24.4, 24.4, 26.4}},
// MZ2_TANK_MACHINEGUN_15 18
{ 27.1, 17.1, 27.2 },
{"MZ2_TANK_MACHINEGUN", {27.1, 17.1, 27.2}},
// MZ2_TANK_MACHINEGUN_16 19
{ 28.5, 9.1, 28.0 },
{"MZ2_TANK_MACHINEGUN", {28.5, 9.1, 28.0}},
// MZ2_TANK_MACHINEGUN_17 20
{ 27.1, 2.2, 28.0 },
{"MZ2_TANK_MACHINEGUN", {27.1, 2.2, 28.0}},
// MZ2_TANK_MACHINEGUN_18 21
{ 24.9, -2.8, 28.0 },
{"MZ2_TANK_MACHINEGUN", {24.9, -2.8, 28.0}},
// MZ2_TANK_MACHINEGUN_19 22
{ 21.6, -7.0, 26.4 },
{"MZ2_TANK_MACHINEGUN", {21.6, -7.0, 26.4}},
// MZ2_TANK_ROCKET_1 23
{ 6.2, 29.1, 49.1 },
{"MZ2_TANK_ROCKET", {6.2, 29.1, 49.1}},
// MZ2_TANK_ROCKET_2 24
{ 6.9, 23.8, 49.1 },
{"MZ2_TANK_ROCKET", {6.9, 23.8, 49.1}},
// MZ2_TANK_ROCKET_3 25
{ 8.3, 17.8, 49.5 },
{"MZ2_TANK_ROCKET", {8.3, 17.8, 49.5}},
// MZ2_INFANTRY_MACHINEGUN_1 26
{ 26.6, 7.1, 13.1 },
{"MZ2_INFANTRY_MACHINEGUN", {26.6, 7.1, 13.1}},
// MZ2_INFANTRY_MACHINEGUN_2 27
{ 18.2, 7.5, 15.4 },
{"MZ2_INFANTRY_MACHINEGUN", {18.2, 7.5, 15.4}},
// MZ2_INFANTRY_MACHINEGUN_3 28
{ 17.2, 10.3, 17.9 },
{"MZ2_INFANTRY_MACHINEGUN", {17.2, 10.3, 17.9}},
// MZ2_INFANTRY_MACHINEGUN_4 29
{ 17.0, 12.8, 20.1 },
{"MZ2_INFANTRY_MACHINEGUN", {17.0, 12.8, 20.1}},
// MZ2_INFANTRY_MACHINEGUN_5 30
{ 15.1, 14.1, 21.8 },
{"MZ2_INFANTRY_MACHINEGUN", {15.1, 14.1, 21.8}},
// MZ2_INFANTRY_MACHINEGUN_6 31
{ 11.8, 17.2, 23.1 },
{"MZ2_INFANTRY_MACHINEGUN", {11.8, 17.2, 23.1}},
// MZ2_INFANTRY_MACHINEGUN_7 32
{ 11.4, 20.2, 21.0 },
{"MZ2_INFANTRY_MACHINEGUN", {11.4, 20.2, 21.0}},
// MZ2_INFANTRY_MACHINEGUN_8 33
{ 9.0, 23.0, 18.9 },
{"MZ2_INFANTRY_MACHINEGUN", {9.0, 23.0, 18.9}},
// MZ2_INFANTRY_MACHINEGUN_9 34
{ 13.9, 18.6, 17.7 },
{"MZ2_INFANTRY_MACHINEGUN", {13.9, 18.6, 17.7}},
// MZ2_INFANTRY_MACHINEGUN_10 35
{ 15.4, 15.6, 15.8 },
{"MZ2_INFANTRY_MACHINEGUN", {15.4, 15.6, 15.8}},
// MZ2_INFANTRY_MACHINEGUN_11 36
{ 10.2, 15.2, 25.1 },
{"MZ2_INFANTRY_MACHINEGUN", {10.2, 15.2, 25.1}},
// MZ2_INFANTRY_MACHINEGUN_12 37
{ -1.9, 15.1, 28.2 },
{"MZ2_INFANTRY_MACHINEGUN", {-1.9, 15.1, 28.2}},
// MZ2_INFANTRY_MACHINEGUN_13 38
{ -12.4, 13.0, 20.2 },
{"MZ2_INFANTRY_MACHINEGUN", {-12.4, 13.0, 20.2}},
// MZ2_SOLDIER_BLASTER_1 39
{ 10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2}},
// MZ2_SOLDIER_BLASTER_2 40
{ 21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_1 41
{ 10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_2 42
{ 21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_1 43
{ 10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_2 44
{ 21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2}},
// MZ2_GUNNER_MACHINEGUN_1 45
{ 30.1 * 1.15, 3.9 * 1.15, 19.6 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {30.1 * 1.15, 3.9 * 1.15, 19.6 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_2 46
{ 29.1 * 1.15, 2.5 * 1.15, 20.7 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {29.1 * 1.15, 2.5 * 1.15, 20.7 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_3 47
{ 28.2 * 1.15, 2.5 * 1.15, 22.2 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {28.2 * 1.15, 2.5 * 1.15, 22.2 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_4 48
{ 28.2 * 1.15, 3.6 * 1.15, 22.0 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {28.2 * 1.15, 3.6 * 1.15, 22.0 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_5 49
{ 26.9 * 1.15, 2.0 * 1.15, 23.4 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {26.9 * 1.15, 2.0 * 1.15, 23.4 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_6 50
{ 26.5 * 1.15, 0.6 * 1.15, 20.8 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {26.5 * 1.15, 0.6 * 1.15, 20.8 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_7 51
{ 26.9 * 1.15, 0.5 * 1.15, 21.5 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {26.9 * 1.15, 0.5 * 1.15, 21.5 * 1.15}},
// MZ2_GUNNER_MACHINEGUN_8 52
{ 29.0 * 1.15, 2.4 * 1.15, 19.5 * 1.15 },
{"MZ2_GUNNER_MACHINEGUN", {29.0 * 1.15, 2.4 * 1.15, 19.5 * 1.15}},
// MZ2_GUNNER_GRENADE_1 53
{ 4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15 },
{"MZ2_GUNNER_GRENADE", {4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15}},
// MZ2_GUNNER_GRENADE_2 54
{ 4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15 },
{"MZ2_GUNNER_GRENADE", {4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15}},
// MZ2_GUNNER_GRENADE_3 55
{ 4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15 },
{"MZ2_GUNNER_GRENADE", {4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15}},
// MZ2_GUNNER_GRENADE_4 56
{ 4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15 },
{"MZ2_GUNNER_GRENADE", {4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15}},
// MZ2_CHICK_ROCKET_1 57
// -24.8, -9.0, 39.0,
{ 24.8, -9.0, 39.0 }, // PGM - this was incorrect in Q2
{"MZ2_CHICK_ROCKET", {24.8, -9.0, 39.0}}, // PGM - this was incorrect in Q2
// MZ2_FLYER_BLASTER_1 58
{ 12.1, 13.4, -14.5 },
{"MZ2_FLYER_BLASTER", {12.1, 13.4, -14.5}},
// MZ2_FLYER_BLASTER_2 59
{ 12.1, -7.4, -14.5 },
{"MZ2_FLYER_BLASTER", {12.1, -7.4, -14.5}},
// MZ2_MEDIC_BLASTER_1 60
{ 12.1, 5.4, 16.5 },
{"MZ2_MEDIC_BLASTER", {12.1, 5.4, 16.5}},
// MZ2_GLADIATOR_RAILGUN_1 61
{ 30.0, 18.0, 28.0 },
{"MZ2_GLADIATOR_RAILGUN", {30.0, 18.0, 28.0}},
// MZ2_HOVER_BLASTER_1 62
{ 32.5, -0.8, 10.0 },
{"MZ2_HOVER_BLASTER", {32.5, -0.8, 10.0}},
// MZ2_ACTOR_MACHINEGUN_1 63
{ 18.4, 7.4, 9.6 },
{"MZ2_ACTOR_MACHINEGUN", {18.4, 7.4, 9.6}},
// MZ2_SUPERTANK_MACHINEGUN_1 64
{ 30.0, 30.0, 88.5 },
{"MZ2_SUPERTANK_MACHINEGUN", {30.0, 30.0, 88.5}},
// MZ2_SUPERTANK_MACHINEGUN_2 65
{ 30.0, 30.0, 88.5 },
{"MZ2_SUPERTANK_MACHINEGUN", {30.0, 30.0, 88.5}},
// MZ2_SUPERTANK_MACHINEGUN_3 66
{ 30.0, 30.0, 88.5 },
{"MZ2_SUPERTANK_MACHINEGUN", {30.0, 30.0, 88.5}},
// MZ2_SUPERTANK_MACHINEGUN_4 67
{ 30.0, 30.0, 88.5 },
{"MZ2_SUPERTANK_MACHINEGUN", {30.0, 30.0, 88.5}},
// MZ2_SUPERTANK_MACHINEGUN_5 68
{ 30.0, 30.0, 88.5 },
{"MZ2_SUPERTANK_MACHINEGUN", {30.0, 30.0, 88.5}},
// MZ2_SUPERTANK_MACHINEGUN_6 69
{ 30.0, 30.0, 88.5 },
{"MZ2_SUPERTANK_MACHINEGUN", {30.0, 30.0, 88.5}},
// MZ2_SUPERTANK_ROCKET_1 70
{ 16.0, -22.5, 91.2 },
{"MZ2_SUPERTANK_ROCKET", {16.0, -22.5, 91.2}},
// MZ2_SUPERTANK_ROCKET_2 71
{ 16.0, -33.4, 86.7 },
{"MZ2_SUPERTANK_ROCKET", {16.0, -33.4, 86.7}},
// MZ2_SUPERTANK_ROCKET_3 72
{ 16.0, -42.8, 83.3 },
{"MZ2_SUPERTANK_ROCKET", {16.0, -42.8, 83.3}},
// --- Start Xian Stuff ---
// MZ2_BOSS2_MACHINEGUN_L1 73
{ 32, -40, 70 },
{"MZ2_BOSS2_MACHINEGUN_L", {32, -40, 70}},
// MZ2_BOSS2_MACHINEGUN_L2 74
{ 32, -40, 70 },
{"MZ2_BOSS2_MACHINEGUN_L", {32, -40, 70}},
// MZ2_BOSS2_MACHINEGUN_L3 75
{ 32, -40, 70 },
{"MZ2_BOSS2_MACHINEGUN_L", {32, -40, 70}},
// MZ2_BOSS2_MACHINEGUN_L4 76
{ 32, -40, 70 },
{"MZ2_BOSS2_MACHINEGUN_L", {32, -40, 70}},
// MZ2_BOSS2_MACHINEGUN_L5 77
{ 32, -40, 70 },
{"MZ2_BOSS2_MACHINEGUN_L", {32, -40, 70}},
// --- End Xian Stuff
// MZ2_BOSS2_ROCKET_1 78
{ 22.0, 16.0, 10.0 },
{"MZ2_BOSS2_ROCKET", {22.0, 16.0, 10.0}},
// MZ2_BOSS2_ROCKET_2 79
{ 22.0, 8.0, 10.0 },
{"MZ2_BOSS2_ROCKET", {22.0, 8.0, 10.0}},
// MZ2_BOSS2_ROCKET_3 80
{ 22.0, -8.0, 10.0 },
{"MZ2_BOSS2_ROCKET", {22.0, -8.0, 10.0}},
// MZ2_BOSS2_ROCKET_4 81
{ 22.0, -16.0, 10.0 },
{"MZ2_BOSS2_ROCKET", {22.0, -16.0, 10.0}},
// MZ2_FLOAT_BLASTER_1 82
{ 32.5, -0.8, 10 },
{"MZ2_FLOAT_BLASTER", {32.5, -0.8, 10}},
// MZ2_SOLDIER_BLASTER_3 83
{ 20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_3 84
{ 20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_3 85
{ 20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2}},
// MZ2_SOLDIER_BLASTER_4 86
{ 7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_4 87
{ 7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_4 88
{ 7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2}},
// MZ2_SOLDIER_BLASTER_5 89
{ 30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_5 90
{ 30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2 },
// MZ2_SOLDIER_MACHINEGUN_5 91
{ 30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN 91
{"MZ2_SOLDIER_MACHINEGUN", {30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2}},
// MZ2_SOLDIER_BLASTER_6 92
{ 27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_6 93
{ 27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_6 94
{ 27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2}},
// MZ2_SOLDIER_BLASTER_7 95
{ 28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_7 96
{ 28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_7 97
{ 28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2}},
// MZ2_SOLDIER_BLASTER_8 98
// 34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2,
{ 31.5 * 1.2, 9.6 * 1.2, 10.1 * 1.2 },
{"MZ2_SOLDIER_BLASTER", {31.5 * 1.2, 9.6 * 1.2, 10.1 * 1.2}},
// MZ2_SOLDIER_SHOTGUN_8 99
{ 34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2 },
{"MZ2_SOLDIER_SHOTGUN", {34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2}},
// MZ2_SOLDIER_MACHINEGUN_8 100
{ 34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2 },
{"MZ2_SOLDIER_MACHINEGUN", {34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2}},
// --- Xian shit below ---
// MZ2_MAKRON_BFG 101
{ 17, -19.5, 62.9 },
{"MZ2_MAKRON_BFG", {17, -19.5, 62.9}},
// MZ2_MAKRON_BLASTER_1 102
{ -3.6, -24.1, 59.5 },
{"MZ2_MAKRON_BLASTER", {-3.6, -24.1, 59.5}},
// MZ2_MAKRON_BLASTER_2 103
{ -1.6, -19.3, 59.5 },
{"MZ2_MAKRON_BLASTER", {-1.6, -19.3, 59.5}},
// MZ2_MAKRON_BLASTER_3 104
{ -0.1, -14.4, 59.5, },
{"MZ2_MAKRON_BLASTER", {-0.1, -14.4, 59.5, }},
// MZ2_MAKRON_BLASTER_4 105
{ 2.0, -7.6, 59.5, },
{"MZ2_MAKRON_BLASTER", {2.0, -7.6, 59.5, }},
// MZ2_MAKRON_BLASTER_5 106
{ 3.4, 1.3, 59.5 },
{"MZ2_MAKRON_BLASTER", {3.4, 1.3, 59.5}},
// MZ2_MAKRON_BLASTER_6 107
{ 3.7, 11.1, 59.5, },
{"MZ2_MAKRON_BLASTER", {3.7, 11.1, 59.5, }},
// MZ2_MAKRON_BLASTER_7 108
{ -0.3, 22.3, 59.5 },
{"MZ2_MAKRON_BLASTER", {-0.3, 22.3, 59.5}},
// MZ2_MAKRON_BLASTER_8 109
{ -6, 33, 59.5 },
{"MZ2_MAKRON_BLASTER", {-6, 33, 59.5}},
// MZ2_MAKRON_BLASTER_9 110
{ -9.3, 36.4, 59.5 },
{"MZ2_MAKRON_BLASTER", {-9.3, 36.4, 59.5}},
// MZ2_MAKRON_BLASTER_10 111
{ -7, 35, 59.5 },
{"MZ2_MAKRON_BLASTER", {-7, 35, 59.5}},
// MZ2_MAKRON_BLASTER_11 112
{ -2.1, 29, 59.5 },
{"MZ2_MAKRON_BLASTER", {-2.1, 29, 59.5}},
// MZ2_MAKRON_BLASTER_12 113
{ 3.9, 17.3, 59.5 },
{"MZ2_MAKRON_BLASTER", {3.9, 17.3, 59.5}},
// MZ2_MAKRON_BLASTER_13 114
{ 6.1, 5.8, 59.5 },
{"MZ2_MAKRON_BLASTER", {6.1, 5.8, 59.5}},
// MZ2_MAKRON_BLASTER_14 115
{ 5.9, -4.4, 59.5 },
{"MZ2_MAKRON_BLASTER", {5.9, -4.4, 59.5}},
// MZ2_MAKRON_BLASTER_15 116
{ 4.2, -14.1, 59.5, },
{"MZ2_MAKRON_BLASTER", {4.2, -14.1, 59.5, }},
// MZ2_MAKRON_BLASTER_16 117
{ 2.4, -18.8, 59.5 },
{"MZ2_MAKRON_BLASTER", {2.4, -18.8, 59.5}},
// MZ2_MAKRON_BLASTER_17 118
{ -1.8, -25.5, 59.5 },
{"MZ2_MAKRON_BLASTER", {-1.8, -25.5, 59.5}},
// MZ2_MAKRON_RAILGUN_1 119
{ -17.3, 7.8, 72.4 },
{"MZ2_MAKRON_RAILGUN", {-17.3, 7.8, 72.4}},
// MZ2_JORG_MACHINEGUN_L1 120
{ 78.5, -47.1, 96, },
{"MZ2_JORG_MACHINEGUN_L", {78.5, -47.1, 96, }},
// MZ2_JORG_MACHINEGUN_L2 121
{ 78.5, -47.1, 96, },
{"MZ2_JORG_MACHINEGUN_L", {78.5, -47.1, 96, }},
// MZ2_JORG_MACHINEGUN_L3 122
{ 78.5, -47.1, 96, },
{"MZ2_JORG_MACHINEGUN_L", {78.5, -47.1, 96, }},
// MZ2_JORG_MACHINEGUN_L4 123
{ 78.5, -47.1, 96, },
{"MZ2_JORG_MACHINEGUN_L", {78.5, -47.1, 96, }},
// MZ2_JORG_MACHINEGUN_L5 124
{ 78.5, -47.1, 96, },
{"MZ2_JORG_MACHINEGUN_L", {78.5, -47.1, 96, }},
// MZ2_JORG_MACHINEGUN_L6 125
{ 78.5, -47.1, 96, },
{"MZ2_JORG_MACHINEGUN_L", {78.5, -47.1, 96, }},
// MZ2_JORG_MACHINEGUN_R1 126
{ 78.5, 46.7, 96, },
{"MZ2_JORG_MACHINEGUN_R", {78.5, 46.7, 96, }},
// MZ2_JORG_MACHINEGUN_R2 127
{ 78.5, 46.7, 96, },
{"MZ2_JORG_MACHINEGUN_R", {78.5, 46.7, 96, }},
// MZ2_JORG_MACHINEGUN_R3 128
{ 78.5, 46.7, 96, },
{"MZ2_JORG_MACHINEGUN_R", {78.5, 46.7, 96, }},
// MZ2_JORG_MACHINEGUN_R4 129
{ 78.5, 46.7, 96, },
{"MZ2_JORG_MACHINEGUN_R", {78.5, 46.7, 96, }},
// MZ2_JORG_MACHINEGUN_R5 130
{ 78.5, 46.7, 96, },
{"MZ2_JORG_MACHINEGUN_R", {78.5, 46.7, 96, }},
// MZ2_JORG_MACHINEGUN_R6 131
{ 78.5, 46.7, 96, },
{"MZ2_JORG_MACHINEGUN_R", {78.5, 46.7, 96, }},
// MZ2_JORG_BFG_1 132
{ 6.3, -9, 111.2 },
{"MZ2_JORG_BFG_1", {6.3, -9, 111.2}},
// MZ2_BOSS2_MACHINEGUN_R1 73
{ 32, 40, 70 },
{"MZ2_BOSS2_MACHINEGUN_R", {32, 40, 70}},
// MZ2_BOSS2_MACHINEGUN_R2 74
{ 32, 40, 70 },
{"MZ2_BOSS2_MACHINEGUN_R", {32, 40, 70}},
// MZ2_BOSS2_MACHINEGUN_R3 75
{ 32, 40, 70 },
{"MZ2_BOSS2_MACHINEGUN_R", {32, 40, 70}},
// MZ2_BOSS2_MACHINEGUN_R4 76
{ 32, 40, 70 },
{"MZ2_BOSS2_MACHINEGUN_R", {32, 40, 70}},
// MZ2_BOSS2_MACHINEGUN_R5 77
{ 32, 40, 70 },
{"MZ2_BOSS2_MACHINEGUN_R", {32, 40, 70}},
// --- End Xian Shit ---
@ -331,157 +332,154 @@ vec3_t monster_flash_offset [] =
// note that the above really ends at 137
// carrier machineguns
// MZ2_CARRIER_MACHINEGUN_L1
{ 56, -32, 32 },
{"MZ2_CARRIER_MACHINEGUN_L", {56, -32, 32}},
// MZ2_CARRIER_MACHINEGUN_R1
{ 56, 32, 32 },
{"MZ2_CARRIER_MACHINEGUN_R", {56, 32, 32}},
// MZ2_CARRIER_GRENADE
{ 42, 24, 50 },
{"MZ2_CARRIER_GRENADE", {42, 24, 50}},
// MZ2_TURRET_MACHINEGUN 141
{ 16, 0, 0 },
{"MZ2_TURRET_MACHINEGUN", {16, 0, 0}},
// MZ2_TURRET_ROCKET 142
{ 16, 0, 0 },
{"MZ2_TURRET_ROCKET", {16, 0, 0}},
// MZ2_TURRET_BLASTER 143
{ 16, 0, 0 },
{"MZ2_TURRET_BLASTER", {16, 0, 0}},
// MZ2_STALKER_BLASTER 144
{ 24, 0, 6 },
{"MZ2_STALKER_BLASTER", {24, 0, 6}},
// MZ2_DAEDALUS_BLASTER 145
{ 32.5, -0.8, 10.0 },
{"MZ2_DAEDALUS_BLASTER", {32.5, -0.8, 10.0}},
// MZ2_MEDIC_BLASTER_2 146
{ 12.1, 5.4, 16.5 },
{"MZ2_MEDIC_BLASTER", {12.1, 5.4, 16.5}},
// MZ2_CARRIER_RAILGUN 147
{ 32, 0, 6, },
{"MZ2_CARRIER_RAILGUN", {32, 0, 6, }},
// MZ2_WIDOW_DISRUPTOR 148
{ 57.72, 14.50, 88.81 },
{"MZ2_WIDOW_DISRUPTOR", {57.72, 14.50, 88.81}},
// MZ2_WIDOW_BLASTER 149
{ 56, 32, 32 },
{"MZ2_WIDOW_BLASTER", {56, 32, 32}},
// MZ2_WIDOW_RAIL 150
{ 62, -20, 84, },
{"MZ2_WIDOW_RAIL", {62, -20, 84, }},
// MZ2_WIDOW_PLASMABEAM 151 // PMM - not used!
{ 32, 0, 6, },
{"MZ2_WIDOW_PLASMABEAM", {32, 0, 6, }},
// MZ2_CARRIER_MACHINEGUN_L2 152
{ 61, -32, 12 },
{"MZ2_CARRIER_MACHINEGUN_L", {61, -32, 12}},
// MZ2_CARRIER_MACHINEGUN_R2 153
{ 61, 32, 12 },
{"MZ2_CARRIER_MACHINEGUN_R", {61, 32, 12}},
// MZ2_WIDOW_RAIL_LEFT 154
{ 17, -62, 91, },
{"MZ2_WIDOW_RAIL_LEFT", {17, -62, 91, }},
// MZ2_WIDOW_RAIL_RIGHT 155
{ 68, 12, 86, },
{"MZ2_WIDOW_RAIL_RIGHT", {68, 12, 86, }},
// MZ2_WIDOW_BLASTER_SWEEP1 156 pmm - the sweeps need to be in sequential order
{ 47.5, 56, 89 },
{"MZ2_WIDOW_BLASTER_SWEEP", {47.5, 56, 89}},
// MZ2_WIDOW_BLASTER_SWEEP2 157
{ 54, 52, 91 },
{"MZ2_WIDOW_BLASTER_SWEEP", {54, 52, 91}},
// MZ2_WIDOW_BLASTER_SWEEP3 158
{ 58, 40, 91 },
{"MZ2_WIDOW_BLASTER_SWEEP", {58, 40, 91}},
// MZ2_WIDOW_BLASTER_SWEEP4 159
{ 68, 30, 88 },
{"MZ2_WIDOW_BLASTER_SWEEP", {68, 30, 88}},
// MZ2_WIDOW_BLASTER_SWEEP5 160
{ 74, 20, 88 },
{"MZ2_WIDOW_BLASTER_SWEEP", {74, 20, 88}},
// MZ2_WIDOW_BLASTER_SWEEP6 161
{ 73, 11, 87 },
{"MZ2_WIDOW_BLASTER_SWEEP", {73, 11, 87}},
// MZ2_WIDOW_BLASTER_SWEEP7 162
{ 73, 3, 87 },
{"MZ2_WIDOW_BLASTER_SWEEP", {73, 3, 87}},
// MZ2_WIDOW_BLASTER_SWEEP8 163
{ 70, -12, 87 },
{"MZ2_WIDOW_BLASTER_SWEEP", {70, -12, 87}},
// MZ2_WIDOW_BLASTER_SWEEP9 164
{ 67, -20, 90 },
{"MZ2_WIDOW_BLASTER_SWEEP", {67, -20, 90}},
// MZ2_WIDOW_BLASTER_100 165
{ -20, 76, 90 },
{"MZ2_WIDOW_BLASTER", {-20, 76, 90}},
// MZ2_WIDOW_BLASTER_90 166
{ -8, 74, 90 },
{"MZ2_WIDOW_BLASTER", {-8, 74, 90}},
// MZ2_WIDOW_BLASTER_80 167
{ 0, 72, 90 },
{"MZ2_WIDOW_BLASTER", {0, 72, 90}},
// MZ2_WIDOW_BLASTER_70 168 d06
{ 10, 71, 89 },
{"MZ2_WIDOW_BLASTER", {10, 71, 89}},
// MZ2_WIDOW_BLASTER_60 169 d07
{ 23, 70, 87 },
{"MZ2_WIDOW_BLASTER", {23, 70, 87}},
// MZ2_WIDOW_BLASTER_50 170 d08
{ 32, 64, 85 },
{"MZ2_WIDOW_BLASTER", {32, 64, 85}},
// MZ2_WIDOW_BLASTER_40 171
{ 40, 58, 84 },
{"MZ2_WIDOW_BLASTER", {40, 58, 84}},
// MZ2_WIDOW_BLASTER_30 172 d10
{ 48, 50, 83 },
{"MZ2_WIDOW_BLASTER", {48, 50, 83}},
// MZ2_WIDOW_BLASTER_20 173
{ 54, 42, 82 },
{"MZ2_WIDOW_BLASTER", {54, 42, 82}},
// MZ2_WIDOW_BLASTER_10 174 d12
{ 56, 34, 82 },
{"MZ2_WIDOW_BLASTER", {56, 34, 82}},
// MZ2_WIDOW_BLASTER_0 175
{ 58, 26, 82 },
{"MZ2_WIDOW_BLASTER", {58, 26, 82}},
// MZ2_WIDOW_BLASTER_10L 176 d14
{ 60, 16, 82 },
{"MZ2_WIDOW_BLASTER", {60, 16, 82}},
// MZ2_WIDOW_BLASTER_20L 177
{ 59, 6, 81 },
{"MZ2_WIDOW_BLASTER", {59, 6, 81}},
// MZ2_WIDOW_BLASTER_30L 178 d16
{ 58, -2, 80 },
{"MZ2_WIDOW_BLASTER", {58, -2, 80}},
// MZ2_WIDOW_BLASTER_40L 179
{ 57, -10, 79 },
{"MZ2_WIDOW_BLASTER", {57, -10, 79}},
// MZ2_WIDOW_BLASTER_50L 180 d18
{ 54, -18, 78 },
{"MZ2_WIDOW_BLASTER", {54, -18, 78}},
// MZ2_WIDOW_BLASTER_60L 181
{ 42, -32, 80 },
{"MZ2_WIDOW_BLASTER", {42, -32, 80}},
// MZ2_WIDOW_BLASTER_70L 182 d20
{ 36, -40, 78 },
{"MZ2_WIDOW_BLASTER", {36, -40, 78}},
// MZ2_WIDOW_RUN_1 183
{ 68.4, 10.88, 82.08 },
{"MZ2_WIDOW_RUN", {68.4, 10.88, 82.08}},
// MZ2_WIDOW_RUN_2 184
{ 68.51, 8.64, 85.14 },
{"MZ2_WIDOW_RUN_2", {68.51, 8.64, 85.14}},
// MZ2_WIDOW_RUN_3 185
{ 68.66, 6.38, 88.78 },
{"MZ2_WIDOW_RUN", {68.66, 6.38, 88.78}},
// MZ2_WIDOW_RUN_4 186
{ 68.73, 5.1, 84.47 },
{"MZ2_WIDOW_RUN", {68.73, 5.1, 84.47}},
// MZ2_WIDOW_RUN_5 187
{ 68.82, 4.79, 80.52 },
{"MZ2_WIDOW_RUN", {68.82, 4.79, 80.52}},
// MZ2_WIDOW_RUN_6 188
{ 68.77, 6.11, 85.37 },
{"MZ2_WIDOW_RUN", {68.77, 6.11, 85.37}},
// MZ2_WIDOW_RUN_7 189
{ 68.67, 7.99, 90.24 },
{"MZ2_WIDOW_RUN", {68.67, 7.99, 90.24}},
// MZ2_WIDOW_RUN_8 190
{ 68.55, 9.54, 87.36 },
{"MZ2_WIDOW_RUN", {68.55, 9.54, 87.36}},
// MZ2_CARRIER_ROCKET_1 191
{ 0, 0, -5 },
{"MZ2_CARRIER_ROCKET", {0, 0, -5}},
// MZ2_CARRIER_ROCKET_2 192
{ 0, 0, -5 },
{"MZ2_CARRIER_ROCKET", {0, 0, -5}},
// MZ2_CARRIER_ROCKET_3 193
{ 0, 0, -5 },
{"MZ2_CARRIER_ROCKET", {0, 0, -5}},
// MZ2_CARRIER_ROCKET_4 194
{ 0, 0, -5 },
{"MZ2_CARRIER_ROCKET", {0, 0, -5}},
// MZ2_WIDOW2_BEAMER_1 195
// 72.13, -17.63, 93.77,
{ 69.00, -17.63, 93.77 },
{"MZ2_WIDOW2_BEAMER", {69.00, -17.63, 93.77}},
// MZ2_WIDOW2_BEAMER_2 196
// 71.46, -17.08, 89.82,
{ 69.00, -17.08, 89.82 },
{"MZ2_WIDOW2_BEAMER", {69.00, -17.08, 89.82}},
// MZ2_WIDOW2_BEAMER_3 197
// 71.47, -18.40, 90.70,
{ 69.00, -18.40, 90.70 },
{"MZ2_WIDOW2_BEAMER", {69.00, -18.40, 90.70}},
// MZ2_WIDOW2_BEAMER_4 198
// 71.96, -18.34, 94.32,
{ 69.00, -18.34, 94.32 },
{"MZ2_WIDOW2_BEAMER", {69.00, -18.34, 94.32}},
// MZ2_WIDOW2_BEAMER_5 199
// 72.25, -18.30, 97.98,
{ 69.00, -18.30, 97.98 },
{"MZ2_WIDOW2_BEAMER", {69.00, -18.30, 97.98}},
// MZ2_WIDOW2_BEAM_SWEEP_1 200
{ 45.04, -59.02, 92.24 },
{"MZ2_WIDOW2_BEAM_SWEEP", {45.04, -59.02, 92.24}},
// MZ2_WIDOW2_BEAM_SWEEP_2 201
{ 50.68, -54.70, 91.96 },
{"MZ2_WIDOW2_BEAM_SWEEP", {50.68, -54.70, 91.96}},
// MZ2_WIDOW2_BEAM_SWEEP_3 202
{ 56.57, -47.72, 91.65 },
{"MZ2_WIDOW2_BEAM_SWEEP", {56.57, -47.72, 91.65}},
// MZ2_WIDOW2_BEAM_SWEEP_4 203
{ 61.75, -38.75, 91.38 },
{"MZ2_WIDOW2_BEAM_SWEEP", {61.75, -38.75, 91.38}},
// MZ2_WIDOW2_BEAM_SWEEP_5 204
{ 65.55, -28.76, 91.24 },
{"MZ2_WIDOW2_BEAM_SWEEP", {65.55, -28.76, 91.24}},
// MZ2_WIDOW2_BEAM_SWEEP_6 205
{ 67.79, -18.90, 91.22 },
{"MZ2_WIDOW2_BEAM_SWEEP", {67.79, -18.90, 91.22}},
// MZ2_WIDOW2_BEAM_SWEEP_7 206
{ 68.60, -9.52, 91.23 },
{"MZ2_WIDOW2_BEAM_SWEEP", {68.60, -9.52, 91.23}},
// MZ2_WIDOW2_BEAM_SWEEP_8 207
{ 68.08, 0.18, 91.32 },
{"MZ2_WIDOW2_BEAM_SWEEP", {68.08, 0.18, 91.32}},
// MZ2_WIDOW2_BEAM_SWEEP_9 208
{ 66.14, 9.79, 91.44 },
{"MZ2_WIDOW2_BEAM_SWEEP", {66.14, 9.79, 91.44}},
// MZ2_WIDOW2_BEAM_SWEEP_10 209
{ 62.77, 18.91, 91.65 },
{"MZ2_WIDOW2_BEAM_SWEEP", {62.77, 18.91, 91.65}},
// MZ2_WIDOW2_BEAM_SWEEP_11 210
{ 58.29, 27.11, 92.00 },
// end of table
{ 0.0, 0.0, 0.0 },
{"MZ2_WIDOW2_BEAM_SWEEP", {58.29, 27.11, 92.00}}
};

View File

@ -210,6 +210,8 @@ void R2D_Init(void)
draw_backtile->defaulttextures.base = R_LoadHiResTexture("gfx/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP);
if (!TEXVALID(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("gfx/menu/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP);
if (!TEXVALID(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("pics/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP);
shader_draw_fill = R_RegisterShader("fill_opaque", SUF_NONE,
"{\n"

View File

@ -195,22 +195,6 @@ void P_Shutdown(void)
pe = NULL;
}
#ifdef Q2BSPS
qboolean Q2TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
{
vec3_t nul = {0,0,0};
trace_t trace = CM_BoxTrace(pmove.physents[0].model, start, end, nul, nul, MASK_WORLDSOLID);
if (trace.fraction < 1)
{
VectorCopy (trace.plane.normal, normal);
VectorCopy (trace.endpos, impact);
return true;
}
return false;
}
#endif
qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
{
trace_t trace;

View File

@ -1491,6 +1491,34 @@ char *particle_set_high =
"assoc gunshotsmoke\n"
"}\n"
"r_part te_superspike\n"
"{\n"
"type sparkfan\n"
"count 20\n"
"scale 1\n"
"scalefactor 1\n"
"alpha 0.5\n"
"die 0.2\n"
"rgb 255 128 0\n"
"blend add\n"
"spawnmode ball\n"
"spawnorg 12\n"
"spawnvel 300\n"
"}\n"
"r_part +te_superspike\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 97 95 191 256\n"
"count 1\n"
"scale 1\n"
"scalefactor 1\n"
"scaledelta 190\n"
"die 0.1\n"
"alpha 0.6\n"
"rgb 255 128 0\n"
"blend add\n"
"assoc gunshotsmoke\n"
"}\n"
////////////////////////////////////////////////
//explosion
@ -1559,9 +1587,10 @@ char *particle_set_high =
//hide lights in explosions.
//r_explosionlight 0
//hide the explosion sprite in nq+qw - WARNING: some mods use this sprite as a flame thrower.
//hide the explosion sprite in qw
"cl_expsprite 0\n"
"r_effect \"progs/s_explod.spr\" hidden 1\n"
//hide it in nq - WARNING: some mods use this sprite as a flame thrower.
//r_effect "progs/s_explod.spr" hidden 1
//////////////////////////////////////////
//r_part te_tarexplosion
@ -1574,6 +1603,7 @@ char *particle_set_high =
//}
//////////////////////////////////////////
//FIXME: what if we don't have glsl support?
"r_part te_teleport\n"
"{\n"
"scale 250\n"
@ -1651,6 +1681,22 @@ char *particle_set_high =
"lightrgb 0.75 0.37 0.18\n"
"}\n"
"r_part te_knightspike\n"
"{\n"
"type sparkfan\n"
"count 200\n"
"scale 3\n"
"scalefactor 1\n"
"alpha 0.5\n"
"die 0.5\n"
"rgb 192 96 48\n"
"blend add\n"
"spawnmode ball\n"
"spawnorg 12\n"
"spawnvel 100\n"
"stretchfactor 10\n"
"}\n"
/////////////////////////////////////////
//vore missiles
"r_part tr_vorespike\n"
@ -1705,13 +1751,13 @@ char *particle_set_high =
"r_trail \"progs/laser.mdl\" tr_enforcerlaser\n"
/////////////////////////////////////////
//scrag missiles. just use the default trail cos we're lazy
//scrag missiles.
"r_part tr_wizspike\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 97 95 191 256\n"
"scale 15\n"
"step 1\n"
"step 4\n"
"alpha 0.6\n"
"die 0.2\n"
"rgb 25 200 25\n"
@ -1722,12 +1768,54 @@ char *particle_set_high =
"spawnmode spiral\n"
"spawnvel 25\n"
"blend add\n"
"lighttime 0\n"
"lighttime 2\n"
"lightradiusfade 75\n"
"lightshadows 0\n"
"lightradius 150\n"
"lightrgb 0.1 0.7 0.1\n"
"}\n"
"r_part tr_wizspike2\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 97 95 191 256\n"
"scale 4\n"
"step 1\n"
"alpha 0.6\n"
"die 0.2\n"
"rgb 25 200 25\n"
"veladd 64\n"
"randomvel 64\n"
"friction 4\n"
"scalefactor 0.825\n"
"spawnmode spiral\n"
"spawnvel 25\n"
"blend add\n"
"}\n"
//scrag impact
"r_part te_wizspike\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 97 95 191 256\n"
"scale 15\n"
"alpha 0.6\n"
"rgb 25 200 25\n"
"friction 0\n"
"scalefactor 0.825\n"
"blend add\n"
"count 5\n"
"veladd -256\n"
"randomvel 256\n"
"die 1\n"
"diesubrand 0.5\n"
"gravity 800\n"
"emit tr_wizspike2\n"
"emitinterval -1\n"
"bounce 1.5\n"
"}\n"
/////////////////////////////////////////
//shambler stuff
"r_part shambercharging\n"
"{\n"
"spawnmode ball\n"
@ -1753,7 +1841,8 @@ char *particle_set_high =
"}\n"
"r_effect progs/s_light.mdl shambercharging 0\n"
/////////////////////////////////////////
//blood effects
"r_part te_blood\n"
"{\n"
"texture fte_bloodparticle\n"
@ -3118,6 +3207,172 @@ char *particle_set_h2part =
//////////////////////////////////////////////////////
char *particle_set_q2part =
"r_part pe_default\n"
"{\n"
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"count 1\n"
"scale 1\n"
"alpha 1\n"
"die 0.3 0.8\n"
"randomvel 20\n"
"orgadd 0 31\n"
"spawnorg 4\n"
"gravity 40\n"
"scalefactor 0.8\n"
"}\n"
"r_part q2_smoke\n"
"{\n"
"count 0 0 1\n"
"model \"models/objects/smoke/tris.md2\" framestart=0 frameend=4 framerate=10 alpha=1\n"
"}\n"
"r_part q2_smokeandflash\n"
"{\n"
"count 0 0 1\n"
"model \"models/objects/flash/tris.md2\" framestart=0 frameend=2 framerate=10 alpha=-1 fullbright\n"
"assoc q2_smoke\n"
"}\n"
"r_part teq2_gunshot /*machinegun*/\n"
"{\n"
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"count 40\n"
"scale 1\n"
"alpha 1\n"
"die 0.3 0.8\n"
"randomvel 20\n"
"orgadd 0 31\n"
"spawnorg 4\n"
"gravity 40\n"
"scalefactor 0.8\n"
"colorindex 0 7\n"
/*smoke puff models*/
"assoc q2_smokeandflash\n"
/*low chance of various sounds*/
"sound world/ric1.wav 1 1 0 0 1\n"
"sound world/ric2.wav 1 1 0 0 1\n"
"sound world/ric3.wav 1 1 0 0 1\n"
"sound \"\" 1 1 0 0 12\n"
"}\n"
"r_part teq2_shotgun /*shotgun... duh*/\n"
"{\n"
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"count 20\n"
"scale 1\n"
"alpha 1\n"
"die 0.3 0.8\n"
"randomvel 20\n"
"orgadd 0 31\n"
"spawnorg 4\n"
"gravity 40\n"
"scalefactor 0.8\n"
"colorindex 0 7\n"
/*smoke puff models*/
"assoc q2_smokeandflash\n"
"}\n"
"r_part teq2_blood\n"
"{\n"
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"count 60\n"
"scale 1\n"
"alpha 1\n"
"die 0.3 0.8\n"
"randomvel 20\n"
"orgadd 0 31\n"
"spawnorg 4\n"
"gravity 40\n"
"scalefactor 0.8\n"
"colorindex 232 7\n"
"}\n"
"r_part q2_blasterpuff\n"
"{\n"
"count 0 0 1\n"
"model \"models/objects/explode/tris.md2\" framestart=0 frameend=4 framerate=10 alpha=1 orient additive fullbright noshadow\n"
"}\n"
"r_part teq2_blaster\n"
"{\n"
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"count 60\n"
"scale 1\n"
"alpha 1\n"
"die 0.3 0.8\n"
"randomvel 40\n"
"orgadd 0 15\n"
"veladd 30\n"
"spawnorg 4\n"
"gravity 40\n"
"scalefactor 0.8\n"
"colorindex 0xe0 7\n"
"assoc q2_blasterpuff /*the model*/\n"
"lightradius 150\n"
"lightradiusfade 400\n"
"lightrgb 1 1 0\n"
"lightshadows 0\n"
"sound \"weapons/lashit.wav\" 1 1 0 0\n"
"}\n"
"r_part TR_BLASTERTRAIL\n"
"{\n"
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"scale 0.5\n"
"alpha 1\n"
"scalefactor 0.8\n"
"step 5\n"
"spawnorg 1\n"
"randomvel 5\n"
"die 0.3 0.5\n"
"colorindex 0xe0\n"
"}\n"
"r_part TR_RAILTRAIL\n"
"{\n"
/*blue spiral*/
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"scale 0.5\n"
"alpha 1\n"
"scalefactor 0.8\n"
"step 1\n"
"spawnmode spiral 64\n"
"spawnorg 3\n"
"spawnvel 6\n"
"die 1 1.2\n"
"colorindex 116 7\n"
"sound \"weapons/railgf1a.wav\" 1 1 0 0\n"
"}\n"
"r_part +TR_RAILTRAIL\n"
"{\n"
/*grey filler*/
"texture \"classicparticle\"\n"
"tcoords 0 0 16 16 32\n"
"scale 0.5\n"
"alpha 1\n"
"scalefactor 0.8\n"
"step 0.75\n"
"spawnorg 3\n"
"spawnvel 3\n"
"die 0.6 0.8\n"
"colorindex 0 15\n"
"}\n"
;
//////////////////////////////////////////////////////

View File

@ -4,5 +4,6 @@ extern char *particle_set_highfps;
extern char *particle_set_high;
extern char *particle_set_minimal;
extern char *particle_set_h2part;
extern char *particle_set_q2part;
extern char *particle_set_tsshaft;
#define R_PARTSET_BUILTINS {"spikeset", &particle_set_spikeset},{"faithful", &particle_set_faithful},{"highfps", &particle_set_highfps},{"high", &particle_set_high},{"minimal", &particle_set_minimal},{"h2part", &particle_set_h2part},{"tsshaft", &particle_set_tsshaft},
#define R_PARTSET_BUILTINS {"spikeset", &particle_set_spikeset},{"faithful", &particle_set_faithful},{"highfps", &particle_set_highfps},{"high", &particle_set_high},{"minimal", &particle_set_minimal},{"h2part", &particle_set_h2part},{"q2part", &particle_set_q2part},{"tsshaft", &particle_set_tsshaft},

View File

@ -209,7 +209,7 @@ void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius)
parms[6] = blue;
cl.worldmodel->funcs.StainNode(cl.worldmodel->nodes+cl.worldmodel->hulls[0].firstclipnode, parms);
cl.worldmodel->funcs.StainNode(cl.worldmodel->rootnode, parms);
//now stain bsp models other than world.
@ -233,7 +233,7 @@ void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius)
}
pe->model->funcs.StainNode(pe->model->nodes+pe->model->hulls[0].firstclipnode, parms);
pe->model->funcs.StainNode(pe->model->rootnode, parms);
}
}
}
@ -2173,8 +2173,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
if (!(cl_dlights[k].flags & LFLAG_LIGHTMAP))
continue;
model->funcs.MarkLights (&cl_dlights[k], 1<<k,
model->nodes + model->hulls[0].firstclipnode);
model->funcs.MarkLights (&cl_dlights[k], 1<<k, model->rootnode);
}
}

View File

@ -2475,7 +2475,7 @@ void R_InitParticleTexture (void)
}
}
particlecqtexture = R_LoadTexture32("", 32, 32, data, IF_NOMIPMAP|IF_NOPICMIP);
particlecqtexture = R_LoadTexture32("classicparticle", 32, 32, data, IF_NOMIPMAP|IF_NOPICMIP);

View File

@ -388,7 +388,6 @@ void Sbar_ExecuteLayoutString (char *s)
value = atoi(com_token);
if (value >= MAX_CLIENTS || value < 0)
Host_EndGame ("client >= MAX_CLIENTS");
// ci = &cl.clientinfo[value];
s = COM_Parse (s);
score = atoi(com_token);
@ -405,9 +404,10 @@ void Sbar_ExecuteLayoutString (char *s)
Draw_FunString (x+32, y+16, va("Ping: %i", ping));
Draw_FunString (x+32, y+24, va("Time: %i", time));
// if (!ci->icon)
// ci = &cl.baseclientinfo;
// Draw_Pic (x, y, R2D_SafeCachePic(ci->iconname));
p = R2D_SafeCachePic(va("players/%s_i.pcx", cl.players[value].skin->name));
if (!p) //display a default if the icon couldn't be found.
p = R2D_SafeCachePic(va("players/male/grunt_i.pcx", cl.players[value].skin->name));
R2D_ScalePic (x, y, 32, 32, p);
continue;
}
@ -427,7 +427,6 @@ void Sbar_ExecuteLayoutString (char *s)
value = atoi(com_token);
if (value >= MAX_CLIENTS || value < 0)
Host_EndGame ("client >= MAX_CLIENTS");
// ci = &cl.clientinfo[value];
s = COM_Parse (s);
score = atoi(com_token);
@ -437,7 +436,7 @@ void Sbar_ExecuteLayoutString (char *s)
if (ping > 999)
ping = 999;
sprintf(block, "%3d %3d %-12.12s", score, ping, "Player"/*ci->name*/);
sprintf(block, "%3d %3d %-12.12s", score, ping, cl.players[value].name);
// if (value == cl.playernum)
// Draw_Alt_String (x, y, block);

View File

@ -121,36 +121,21 @@ void Skin_Find (player_info_t *sc)
{
skin_t *skin;
int i;
char name[128], *s, *mn;
char name[128], *s;
model_t *model;
mn = Info_ValueForKey (sc->userinfo, "model");
while((s = strchr(mn, '/')))
*mn = '\0';
if (allskins[0])
s = allskins;
else
s = Info_ValueForKey (sc->userinfo, "skin");
if (strstr (mn, "..") || *mn == '.')
mn = "";
if (!*s)
s = baseskin.string;
if (!*s)
s = "default";
if (*mn)
{
mn = va("%s/%s", mn, s);
COM_StripExtension (mn, name, sizeof(name));
}
else
{
s = Skin_FindName(sc);
COM_StripExtension (s, name, sizeof(name));
}
s = Skin_FindName(sc);
COM_StripExtension (s, name, sizeof(name));
s = strchr(name, '/');
if (s)

View File

@ -31,7 +31,7 @@ F11 will step through.
static cvar_t editstripcr = CVARD("edit_stripcr", "1", "remove \\r from eols (on load)");
static cvar_t editaddcr = CVARD("edit_addcr", editaddcr_default, "make sure that each line ends with a \\r (on save)");
static cvar_t edittabspacing = CVARD("edit_tabsize", "4", "How wide tab alignment is");
cvar_t debugger = CVARD("debugger", debugger_default, "When enabled, QC errors and debug events will enable step-by-step tracing.");
cvar_t pr_debugger = CVARAD("pr_debugger", debugger_default, "debugger", "When enabled, QC errors and debug events will enable step-by-step tracing.");
extern cvar_t pr_sourcedir;
static pubprogfuncs_t *editprogfuncs;
@ -1199,7 +1199,7 @@ void Editor_Draw(void)
int QCLibEditor(pubprogfuncs_t *prfncs, char *filename, int line, int statement, int nump, char **parms)
{
char *f1, *f2;
if (editormodal || (line < 0 && !statement) || !debugger.ival)
if (editormodal || (line < 0 && !statement) || !pr_debugger.ival)
return line; //whoops
if (qrenderer == QR_NONE)
@ -1360,6 +1360,6 @@ void Editor_Init(void)
Cvar_Register(&editstripcr, "Text editor");
Cvar_Register(&editaddcr, "Text editor");
Cvar_Register(&edittabspacing, "Text editor");
Cvar_Register(&debugger, "Text editor");
Cvar_Register(&pr_debugger, "Text editor");
}
#endif

View File

@ -171,6 +171,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef USE_MADLIB //no internal mp3 playing
#define NOMEDIA //NO playing of avis/cins/roqs
#define SPRMODELS //quake1 sprite models
#define MD3MODELS //we DO want to use quake3 alias models. This might be a minimal build, but we still want this.
#define PLUGINS
@ -194,6 +195,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define SIDEVIEWS 4 //enable secondary/reverse views.
#define DSPMODELS //doom sprites (only needs DOOMWADS to generate the right wad file names)
#define SPRMODELS //quake1 sprite models
#define SP2MODELS //quake2 sprite models
#define MD2MODELS //quake2 alias models
#define MD3MODELS //quake3 alias models
@ -378,6 +381,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef WEBCLIENT
#undef TEXTEDITOR
#undef RUNTIMELIGHTING
#undef DSPMODELS
#undef SPRMODELS
#undef SP2MODELS
#undef PSET_SCRIPT
#undef PSET_CLASSIC

View File

@ -1876,28 +1876,29 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
/*
static float PlaneNearest(vec3_t normal, vec3_t mins, vec3_t maxs)
{
float result;
return 128;
#if 1
#if 0
result = fabs(normal[0] * maxs[0]);
result += fabs(normal[1] * maxs[1]);
result += fabs(normal[2] * maxs[2]);
#elif 0
result = normal[0] * ((normal[0] > 0)?-16:16);
result += normal[1] * ((normal[1] > 0)?-16:16);
result += normal[2] * ((normal[2] > 0)?-24:32);
#else
result = normal[0] * ((normal[0] < 0)?mins[0]:maxs[0]);
result += normal[1] * ((normal[1] < 0)?mins[1]:maxs[1]);
result += normal[2] * ((normal[2] < 0)?mins[2]:maxs[2]);
result = normal[0] * ((normal[0] > 0)?mins[0]:maxs[0]);
result += normal[1] * ((normal[1] > 0)?mins[1]:maxs[1]);
result += normal[2] * ((normal[2] > 0)?mins[2]:maxs[2]);
#endif
return result;
}
*/
static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
qboolean impacted = false;
int i;
int i, j;
float *p1, *p2, *p3;
vec3_t edge1, edge2, edge3;
@ -1906,10 +1907,10 @@ static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numind
float planedist;
float diststart, distend;
// float expand;
float mn,mx;
float extend;
float frac;
// float temp;
vec3_t impactpoint;
@ -1922,47 +1923,107 @@ static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numind
VectorSubtract(p1, p2, edge1);
VectorSubtract(p3, p2, edge2);
CrossProduct(edge1, edge2, normal);
VectorNormalize(normal);
// expand = PlaneNearest(normal, mins, maxs);
planedist = DotProduct(p1, normal);
diststart = DotProduct(start, normal);
if (diststart <= planedist)
continue; //start on back side.
distend = DotProduct(end, normal);
if (distend >= planedist)
continue; //end on front side (as must start - doesn't cross).
frac = (diststart - planedist - 1) / (diststart-distend);
if (frac < 0)
frac = 0;
if (frac >= trace->fraction) //already found one closer.
//degenerate triangle
if (!normal[0] && !normal[1] && !normal[2])
continue;
impactpoint[0] = start[0] + frac*(end[0] - start[0]);
impactpoint[1] = start[1] + frac*(end[1] - start[1]);
impactpoint[2] = start[2] + frac*(end[2] - start[2]);
//debugging
// if (normal[2] != 1)
// continue;
// temp = DotProduct(impactpoint, normal)-planedist;
#define DIST_EPSILON (0.03125)
#define DIST_SOLID (3/8.0) //the plane must be at least this thick, or player prediction will try jittering through it to correct the player's origin
extend = PlaneNearest(normal, mins, maxs);
planedist = DotProduct(p1, normal)-extend;
diststart = DotProduct(start, normal);
if (diststart/*+extend+DIST_SOLID*/ < planedist)
continue; //start on back side (or slightly inside).
distend = DotProduct(end, normal);
if (distend > planedist)
continue; //end on front side.
//figure out the precise frac
if (diststart > planedist)
{
//if we're not stuck inside it
if (distend >= diststart)
continue; //trace moves away from or along the surface. don't block the trace if we're sliding along the front of it.
}
frac = (diststart - planedist) / (diststart-distend);
if (frac >= trace->truefraction) //already found one closer.
continue;
//an impact outside of the surface's bounding box (expanded by the trace bbox) is not a valid impact.
//this solves extrusion issues.
for (j = 0; j < 3; j++)
{
impactpoint[j] = start[j] + frac*(end[j] - start[j]);
//make sure the impact point is within the triangle's bbox.
//primarily, this serves to prevent the edge extruding off to infinity or so
mx = mn = p1[j];
if (mn > p2[j])
mn = p2[j];
if (mx < p2[j])
mx = p2[j];
if (mn > p3[j])
mn = p3[j];
if (mx < p3[j])
mx = p3[j];
mx-=mins[j]-DIST_EPSILON;
mn-=maxs[j]+DIST_EPSILON;
if (impactpoint[j] > mx)
break;
if (impactpoint[j] < mn)
break;
}
if (j < 3)
continue;
//make sure the impact point is actually within the triangle
CrossProduct(edge1, normal, edgenormal);
// temp = DotProduct(impactpoint, edgenormal)-DotProduct(p2, edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p2, edgenormal))
VectorNormalize(edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p2, edgenormal)-PlaneNearest(edgenormal, mins, maxs)+DIST_EPSILON)
continue;
CrossProduct(normal, edge2, edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p3, edgenormal))
VectorNormalize(edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p3, edgenormal)-PlaneNearest(edgenormal, mins, maxs)+DIST_EPSILON)
continue;
VectorSubtract(p1, p3, edge3);
CrossProduct(normal, edge3, edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p1, edgenormal))
VectorNormalize(edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p1, edgenormal)-PlaneNearest(edgenormal, mins, maxs)+DIST_EPSILON)
continue;
trace->fraction = frac;
VectorCopy(impactpoint, trace->endpos);
//okay, its a valid impact
trace->truefraction = frac;
//move back from the impact point. this should keep the point slightly outside of the solid triangle.
frac = (diststart - (planedist+DIST_EPSILON)) / (diststart-distend);
if (frac < 0)
{ //we're inside, apparently
trace->startsolid = trace->allsolid = (diststart < planedist);
trace->fraction = 0;
VectorCopy(start, trace->endpos);
}
else
{
//we made progress
trace->fraction = frac;
trace->endpos[0] = start[0] + frac*(end[0] - start[0]);
trace->endpos[1] = start[1] + frac*(end[1] - start[1]);
trace->endpos[2] = start[2] + frac*(end[2] - start[2]);
}
VectorCopy(normal, trace->plane.normal);
trace->plane.dist = planedist;
impacted = true;
// if (fabs(normal[0]) != 1 && fabs(normal[1]) != 1 && fabs(normal[2]) != 1)
// Con_Printf("Non-axial impact\n");
}
return impacted;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -502,14 +502,15 @@ float Q_rsqrt(float number)
float QDECL VectorNormalize (vec3_t v)
{
float length, ilength;
float length;
float ilength;
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
length = sqrt (length); // FIXME
if (length)
{
ilength = 1/length;
ilength = 1.0/length;
v[0] *= ilength;
v[1] *= ilength;
v[2] *= ilength;

View File

@ -182,7 +182,7 @@ typedef struct
// time and size data to calculate bandwidth
int outgoing_size[MAX_LATENT];
double outgoing_time[MAX_LATENT];
qboolean compress;
struct huffman_s *compresstable;
//nq servers must recieve truncated packets.
int in_fragment_length;
@ -210,12 +210,15 @@ nqprot_t NQNetChan_Process(netchan_t *chan);
#endif
#ifdef HUFFNETWORK
#define HUFFCRC_QUAKE3 0x286f2e8d
typedef struct huffman_s huffman_t;
int Huff_PreferedCompressionCRC (void);
void Huff_EncryptPacket(sizebuf_t *msg, int offset);
void Huff_DecryptPacket(sizebuf_t *msg, int offset);
qboolean Huff_CompressionCRC(int crc);
void Huff_CompressPacket(sizebuf_t *msg, int offset);
void Huff_DecompressPacket(sizebuf_t *msg, int offset);
huffman_t *Huff_CompressionCRC(int crc);
void Huff_CompressPacket(huffman_t *huff, sizebuf_t *msg, int offset);
void Huff_DecompressPacket(huffman_t *huff, sizebuf_t *msg, int offset);
int Huff_GetByte(qbyte *buffer, int *count);
void Huff_EmitByte(int ch, qbyte *buffer, int *count);
#endif

View File

@ -723,10 +723,10 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
chan->outgoing_time[i] = realtime;
#ifdef HUFFNETWORK
if (chan->compress)
if (chan->compresstable)
{
//int oldsize = send.cursize;
Huff_CompressPacket(&send, 8 + ((chan->sock == NS_CLIENT)?2:0) + (chan->fragmentsize?2:0));
Huff_CompressPacket(chan->compresstable, &send, 8 + ((chan->sock == NS_CLIENT)?2:0) + (chan->fragmentsize?2:0));
// Con_Printf("%i becomes %i\n", oldsize, send.cursize);
// Huff_DecompressPacket(&send, (chan->sock == NS_CLIENT)?10:8);
}
@ -739,7 +739,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
{
int hsz = 10 + ((chan->sock == NS_CLIENT)?2:0); /*header size, if fragmentation is in use*/
if (!chan->fragmentsize || send.cursize < chan->fragmentsize - hsz)
if ((!chan->fragmentsize) || send.cursize-hsz < ((chan->fragmentsize - hsz)&~7))
NET_SendPacket (chan->sock, send.cursize, send.data, &chan->remote_address);
else
{
@ -1003,10 +1003,10 @@ qboolean Netchan_Process (netchan_t *chan)
chan->last_received = realtime;
#ifdef HUFFNETWORK
if (chan->compress)
if (chan->compresstable)
{
// Huff_CompressPacket(&net_message, (chan->sock == NS_SERVER)?10:8);
Huff_DecompressPacket(&net_message, msg_readcount);
Huff_DecompressPacket(chan->compresstable, &net_message, msg_readcount);
}
#endif

View File

@ -873,7 +873,7 @@ void PM_CategorizePosition (void)
VectorMA (pmove.origin, 24, flatforward, fwd1);
t = CM_BoxTrace(pmove.physents[0].model, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, MASK_PLAYERSOLID);
pmove.physents[0].model->funcs.NativeTrace(pmove.physents[0].model, 0, 0, NULL, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, MASK_PLAYERSOLID, &t);
if (t.surface->flags & Q3SURF_LADDER)
{
pmove.onladder = true;

View File

@ -2556,7 +2556,7 @@ void QCBUILTIN PF_dupstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *buf;
int len = 0;
size_t len = 0;
const char *s[8];
int l[8];
int i;
@ -2568,13 +2568,16 @@ void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
}
len++; /*for the null*/
((int *)pr_globals)[OFS_RETURN] = prinst->AllocTempString(prinst, &buf, len);
len = 0;
for (i = 0; i < prinst->callargc; i++)
if (buf)
{
memcpy(buf, s[i], l[i]);
buf += l[i];
len = 0;
for (i = 0; i < prinst->callargc; i++)
{
memcpy(buf, s[i], l[i]);
buf += l[i];
}
*buf = '\0';
}
*buf = '\0';
}
//returns a section of a string as a tempstring

View File

@ -412,11 +412,9 @@ static void MSG_WriteRawBits( sizebuf_t *msg, int value, int bits )
MSG_WriteHuffBits
============
*/
#ifdef HUFFNETWORK
static void MSG_WriteHuffBits( sizebuf_t *msg, int value, int bits )
{
#ifdef MSG_PROFILING
int startbits = msg->currentbit;
#endif
int remaining;
int i;
@ -445,11 +443,8 @@ static void MSG_WriteHuffBits( sizebuf_t *msg, int value, int bits )
}
msg->cursize = (msg->currentbit >> 3) + 1;
#ifdef MSG_PROFILING
msg_bitsEmitted += msg->currentbit - startbits;
#endif // MSG_PROFILING
}
#endif
/*
============
@ -514,9 +509,11 @@ void MSG_WriteBits(sizebuf_t *msg, int value, int bits)
case SZ_RAWBITS:
MSG_WriteRawBits( msg, value, bits );
break;
#ifdef HUFFNETWORK
case SZ_HUFFMAN:
MSG_WriteHuffBits( msg, value, bits );
break;
#endif
}
}

View File

@ -61,7 +61,7 @@ typedef struct trace_s
//q2 game dll code will memcpy the lot from trace_t to q2trace_t.
qboolean allsolid; // if true, plane is not valid
qboolean startsolid; // if true, the initial point was in a solid area
float fraction; // time completed, 1.0 = didn't hit anything
float fraction; // time completed, 1.0 = didn't hit anything (nudged closer to the start point to cover precision issues)
vec3_t endpos; // final position
cplane_t plane; // surface normal at impact
q2csurface_t *surface; // q2-compat surface hit
@ -71,6 +71,7 @@ typedef struct trace_s
int entnum;
qboolean inopen, inwater;
float truefraction; //can be negative, also has floating point precision issues, etc.
} trace_t;
typedef struct q2trace_s

View File

@ -16845,6 +16845,7 @@
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
@ -21357,7 +21358,6 @@
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"

View File

@ -1187,8 +1187,8 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
if (shadelight[i] > 192)
shadelight[i] = 192;
if (shadelight[i] > 255)
shadelight[i] = 255;
}
//MORE HUGE HACKS! WHEN WILL THEY CEASE!
@ -1279,9 +1279,9 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
if (e->flags & Q2RF_GLOW)
{
shadelight[0] += sin(cl.time)*0.25;
shadelight[1] += sin(cl.time)*0.25;
shadelight[2] += sin(cl.time)*0.25;
float scale = 1 + 0.2 * sin(cl.time*7);
VectorScale(ambientlight, scale, ambientlight);
VectorScale(shadelight, scale, shadelight);
}
VectorMA(ambientlight, 0.5, shadelight, e->light_avg);

View File

@ -4208,7 +4208,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
continue;
if (batch->shader->flags & SHADER_SKY)
{
if (shaderstate.mode == BEM_STANDARD || shaderstate.mode == BEM_DEPTHDARK || shaderstate.mode == BEM_WIREFRAME)
if (shaderstate.mode == BEM_STANDARD || shaderstate.mode == BEM_DEPTHDARK)// || shaderstate.mode == BEM_WIREFRAME)
{
if (!batch->shader->prog)
{

View File

@ -112,7 +112,7 @@ typedef struct
int reserved2;
int reserved1;
//char modelname[1+];
} dsmesh_t;
} dsmesh_v1_t;
typedef struct
{
@ -184,6 +184,8 @@ typedef struct
struct hmwater_s *water;
size_t traceseq;
#ifndef SERVERONLY
pvscache_t pvscache;
vec4_t colours[SECTHEIGHTSIZE*SECTHEIGHTSIZE]; //FIXME: make bytes
@ -196,12 +198,11 @@ typedef struct
mesh_t mesh;
mesh_t *amesh;
int numents;
int maxents;
entity_t *ents;
hmpolyset_t *polys;
#endif
int numents;
int maxents;
struct hmentity_s **ents;
} hmsection_t;
typedef struct
{
@ -210,7 +211,10 @@ typedef struct
typedef struct heightmap_s
{
char path[MAX_QPATH];
char watershadername[MAX_QPATH]; //typically the name of the ocean or whatever.
char defaultwatershader[MAX_QPATH]; //typically the name of the ocean or whatever.
float defaultwaterheight;
float defaultgroundheight;
char defaultgroundtexture[MAX_QPATH];
int firstsegx, firstsegy;
int maxsegx, maxsegy; //tex/cull sections
float sectionsize; //each section is this big, in world coords
@ -220,7 +224,15 @@ typedef struct heightmap_s
mesh_t skymesh;
mesh_t *askymesh;
unsigned int exteriorcontents;
qboolean beinglazy; //only load one section per frame, if its the renderer doing the loading. this helps avoid stalls, in theory.
qboolean beinglazy; //only load one section per frame, if its the renderer doing the loading. this helps avoid nasty stalls, in theory.
size_t traceseq;
size_t drawnframe;
enum
{
DGT_SOLID, //invalid/new areas should be completely solid until painted.
DGT_HOLES, //invalid/new sections should be non-solid+invisible
DGT_FLAT //invalid/new sections should be filled with ground by default
} defaultgroundtype;
enum
{
HMM_TERRAIN,
@ -233,6 +245,16 @@ typedef struct heightmap_s
link_t recycle; //section list in lru order
// link_t collected; //memory that may be reused, to avoid excess reallocs.
struct hmentity_s
{
size_t drawnframe; //don't add it to the scene multiple times.
size_t traceseq; //don't trace through this entity multiple times if its in different sections.
int refs; //entity is free/reusable when its no longer referenced by any sections
entity_t ent;
struct hmentity_s *next; //used for freeing/allocating an entity
} *entities;
#ifndef SERVERONLY
unsigned int numusedlmsects; //to track leaks and stats
unsigned int numunusedlmsects;
@ -548,6 +570,7 @@ static hmsection_t *Terr_GenerateSection(heightmap_t *hm, int sx, int sy)
return s;
}
//generates some water
static void *Terr_GenerateWater(hmsection_t *s, float maxheight)
{
int i;
@ -557,7 +580,7 @@ static void *Terr_GenerateWater(hmsection_t *s, float maxheight)
s->water = w;
#ifndef SERVERONLY
if (!isDedicated)
w->shader = R_RegisterCustom (s->hmmod->watershadername, SUF_NONE, Shader_DefaultWaterShader, NULL);
w->shader = R_RegisterCustom (s->hmmod->defaultwatershader, SUF_NONE, Shader_DefaultWaterShader, NULL);
#endif
w->simple = true;
w->contentmask = FTECONTENTS_WATER;
@ -570,10 +593,121 @@ static void *Terr_GenerateWater(hmsection_t *s, float maxheight)
return w;
}
//embeds a mesh
static void Terr_AddMesh(heightmap_t *hm, int loadflags, model_t *mod, vec3_t epos, vec3_t axis[3], float scale)
{
struct hmentity_s *e, *f = NULL;
hmsection_t *s;
int min[2], max[2], coord[2];
int i;
if (!mod)
return;
if (!scale)
scale = 1;
if (axis[0][0] != 1 || axis[0][1] != 0 || axis[0][2] != 0 ||
axis[1][0] != 0 || axis[1][1] != 1 || axis[1][2] != 0 ||
axis[2][0] != 0 || axis[2][1] != 0 || axis[2][2] != 1)
{
min[0] = floor((epos[0]-mod->radius*scale) / hm->sectionsize) + CHUNKBIAS;
min[1] = floor((epos[1]-mod->radius*scale) / hm->sectionsize) + CHUNKBIAS;
min[0] = bound(hm->firstsegx, min[0], hm->maxsegx-1);
min[1] = bound(hm->firstsegy, min[1], hm->maxsegy-1);
max[0] = floor((epos[0]+mod->radius*scale) / hm->sectionsize) + CHUNKBIAS;
max[1] = floor((epos[1]+mod->radius*scale) / hm->sectionsize) + CHUNKBIAS;
max[0] = bound(hm->firstsegx, max[0], hm->maxsegx-1);
max[1] = bound(hm->firstsegy, max[1], hm->maxsegy-1);
}
else
{
min[0] = floor((epos[0]+mod->mins[0]*scale) / hm->sectionsize) + CHUNKBIAS;
min[1] = floor((epos[1]+mod->mins[1]*scale) / hm->sectionsize) + CHUNKBIAS;
min[0] = bound(hm->firstsegx, min[0], hm->maxsegx-1);
min[1] = bound(hm->firstsegy, min[1], hm->maxsegy-1);
max[0] = floor((epos[0]+mod->maxs[0]*scale) / hm->sectionsize) + CHUNKBIAS;
max[1] = floor((epos[1]+mod->maxs[1]*scale) / hm->sectionsize) + CHUNKBIAS;
max[0] = bound(hm->firstsegx, max[0], hm->maxsegx-1);
max[1] = bound(hm->firstsegy, max[1], hm->maxsegy-1);
}
//try to find the ent if it already exists (don't do dupes)
for (e = hm->entities; e; e = e->next)
{
if (!e->refs)
f = e;
else
{
if (e->ent.origin[0] != epos[0] || e->ent.origin[1] != epos[1] || e->ent.origin[2] != epos[2])
continue;
if (e->ent.model != mod || e->ent.scale != scale)
continue;
if (memcmp(axis, e->ent.axis, sizeof(axis)))
continue;
break; //looks like a match.
}
}
//allocate it if needed
if (!e)
{
if (f)
e = f; //can reuse a released one
else
{ //allocate one
e = Z_Malloc(sizeof(*e));
e->next = hm->entities;
hm->entities = e;
}
e->ent.drawflags = SCALE_ORIGIN_ORIGIN;
e->ent.scale = scale;
e->ent.playerindex = -1;
e->ent.shaderRGBAf[0] = 1;
e->ent.shaderRGBAf[1] = 1;
e->ent.shaderRGBAf[2] = 1;
e->ent.shaderRGBAf[3] = 1;
VectorCopy(epos, e->ent.origin);
memcpy(e->ent.axis, axis, sizeof(e->ent.axis));
e->ent.model = mod;
}
for (coord[0] = min[0]; coord[0] <= max[0]; coord[0]++)
{
for (coord[1] = min[1]; coord[1] <= max[1]; coord[1]++)
{
s = Terr_GetSection(hm, coord[0], coord[1], loadflags);
if (!s)
continue;
//don't add pointless dupes
for (i = 0; i < s->numents; i++)
{
if (s->ents[i] == e)
break;
}
if (i < s->numents)
continue;
s->flags |= TSF_EDITED;
if (s->maxents == s->numents)
{
s->maxents++;
s->ents = realloc(s->ents, sizeof(*s->ents)*(s->maxents));
}
s->ents[s->numents++] = e;
e->refs++;
}
}
}
static void *Terr_ReadV1(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
{
#ifndef SERVERONLY
dsmesh_t *dm;
dsmesh_v1_t *dm;
float *colours;
#endif
dsection_v1_t *ds = ptr;
@ -661,36 +795,13 @@ static void *Terr_ReadV1(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
}
/*load any static ents*/
s->numents = ds->ents_num;
s->maxents = s->numents;
if (s->maxents)
s->ents = Z_Malloc(sizeof(*s->ents) * s->maxents);
else
s->ents = NULL;
if (!s->ents)
s->numents = s->maxents = 0;
for (i = 0, dm = (dsmesh_t*)ptr; i < s->numents; i++, dm = (dsmesh_t*)((qbyte*)dm + dm->size))
for (i = 0, dm = (dsmesh_v1_t*)ptr; i < ds->ents_num; i++, dm = (dsmesh_v1_t*)((qbyte*)dm + dm->size))
{
s->ents[i].model = Mod_ForName((char*)(dm + 1), MLV_WARN);
if (!s->ents[i].model || s->ents[i].model->type == mod_dummy)
{
s->numents--;
i--;
continue;
}
s->ents[i].scale = dm->scale;
s->ents[i].drawflags = SCALE_ORIGIN_ORIGIN;
s->ents[i].playerindex = -1;
VectorCopy(dm->axisorg[0], s->ents[i].axis[0]);
VectorCopy(dm->axisorg[1], s->ents[i].axis[1]);
VectorCopy(dm->axisorg[2], s->ents[i].axis[2]);
VectorCopy(dm->axisorg[3], s->ents[i].origin);
s->ents[i].origin[0] += (s->sx-CHUNKBIAS)*hm->sectionsize;
s->ents[i].origin[1] += (s->sy-CHUNKBIAS)*hm->sectionsize;
s->ents[i].shaderRGBAf[0] = 1;
s->ents[i].shaderRGBAf[1] = 1;
s->ents[i].shaderRGBAf[2] = 1;
s->ents[i].shaderRGBAf[3] = 1;
vec3_t org;
org[0] = dm->axisorg[3][0] + (s->sx-CHUNKBIAS)*hm->sectionsize;
org[1] = dm->axisorg[3][1] + (s->sy-CHUNKBIAS)*hm->sectionsize;
org[2] = dm->axisorg[3][2];
Terr_AddMesh(hm, TGS_NOLOAD, Mod_ForName((char*)(dm + 1), MLV_WARN), org, dm->axisorg, dm->scale);
}
#endif
return ptr;
@ -853,7 +964,7 @@ static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, i
char *shadername = w->shader->name;
int fl = 0;
if (strcmp(shadername, hm->watershadername))
if (strcmp(shadername, hm->defaultwatershader))
fl |= 1;
for (x = 0; x < 8; x++)
if (w->holes[x])
@ -943,27 +1054,27 @@ static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, i
}
mf = 0;
if (s->ents[i].scale != 1)
if (s->ents[i]->ent.scale != 1)
mf |= TMF_SCALE;
Terr_Write_SInt(&strm, mf);
if (s->ents[i].model)
Terr_Write_String(&strm, s->ents[i].model->name);
if (s->ents[i]->ent.model)
Terr_Write_String(&strm, s->ents[i]->ent.model->name);
else
Terr_Write_String(&strm, "*invalid");
Terr_Write_Float(&strm, s->ents[i].origin[0]+(CHUNKBIAS-sx)*hm->sectionsize);
Terr_Write_Float(&strm, s->ents[i].origin[1]+(CHUNKBIAS-sy)*hm->sectionsize);
Terr_Write_Float(&strm, s->ents[i].origin[2]);
Terr_Write_Float(&strm, s->ents[i].axis[0][0]);
Terr_Write_Float(&strm, s->ents[i].axis[0][1]);
Terr_Write_Float(&strm, s->ents[i].axis[0][2]);
Terr_Write_Float(&strm, s->ents[i].axis[1][0]);
Terr_Write_Float(&strm, s->ents[i].axis[1][1]);
Terr_Write_Float(&strm, s->ents[i].axis[1][2]);
Terr_Write_Float(&strm, s->ents[i].axis[2][0]);
Terr_Write_Float(&strm, s->ents[i].axis[2][1]);
Terr_Write_Float(&strm, s->ents[i].axis[2][2]);
Terr_Write_Float(&strm, s->ents[i]->ent.origin[0]+(CHUNKBIAS-sx)*hm->sectionsize);
Terr_Write_Float(&strm, s->ents[i]->ent.origin[1]+(CHUNKBIAS-sy)*hm->sectionsize);
Terr_Write_Float(&strm, s->ents[i]->ent.origin[2]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[0][0]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[0][1]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[0][2]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[1][0]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[1][1]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[1][2]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[2][0]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[2][1]);
Terr_Write_Float(&strm, s->ents[i]->ent.axis[2][2]);
if (mf & TMF_SCALE)
Terr_Write_Float(&strm, s->ents[i].scale);
Terr_Write_Float(&strm, s->ents[i]->ent.scale);
}
//reset it in case the buffer is getting a little full
@ -1023,7 +1134,7 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
if (fl & 1)
Terr_Read_String(&strm, shadername, sizeof(shadername));
else
Q_strncpyz(shadername, hm->watershadername, sizeof(hm->watershadername));
Q_strncpyz(shadername, hm->defaultwatershader, sizeof(shadername));
#ifndef SERVERONLY
// CL_CheckOrEnqueDownloadFile(shadername, NULL, 0);
w->shader = R_RegisterCustom (shadername, SUF_NONE, Shader_DefaultWaterShader, NULL);
@ -1122,50 +1233,35 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
}
/*load any static ents*/
s->numents = Terr_Read_SInt(&strm);
if (s->maxents)
BZ_Free(s->ents);
s->maxents = s->numents;
if (s->maxents)
s->ents = BZ_Malloc(sizeof(*s->ents) * s->maxents);
else
s->ents = NULL;
if (!s->ents)
s->numents = s->maxents = 0;
for (i = 0; i < s->numents; i++)
j = Terr_Read_SInt(&strm);
for (i = 0; i < j; i++)
{
vec3_t axis[3];
vec3_t org;
unsigned int mf;
model_t *mod;
float scale;
mf = Terr_Read_SInt(&strm);
memset(&s->ents[i], 0, sizeof(s->ents[i]));
s->ents[i].model = Mod_FindName(Terr_Read_String(&strm, modelname, sizeof(modelname)));
s->ents[i].origin[0] = Terr_Read_Float(&strm);
s->ents[i].origin[1] = Terr_Read_Float(&strm);
s->ents[i].origin[2] = Terr_Read_Float(&strm);
s->ents[i].axis[0][0] = Terr_Read_Float(&strm);
s->ents[i].axis[0][1] = Terr_Read_Float(&strm);
s->ents[i].axis[0][2] = Terr_Read_Float(&strm);
s->ents[i].axis[1][0] = Terr_Read_Float(&strm);
s->ents[i].axis[1][1] = Terr_Read_Float(&strm);
s->ents[i].axis[1][2] = Terr_Read_Float(&strm);
s->ents[i].axis[2][0] = Terr_Read_Float(&strm);
s->ents[i].axis[2][1] = Terr_Read_Float(&strm);
s->ents[i].axis[2][2] = Terr_Read_Float(&strm);
s->ents[i].scale = (mf&TMF_SCALE)?Terr_Read_Float(&strm):1;
s->ents[i].drawflags = SCALE_ORIGIN_ORIGIN;
s->ents[i].playerindex = -1;
s->ents[i].origin[0] += (s->sx-CHUNKBIAS)*hm->sectionsize;
s->ents[i].origin[1] += (s->sy-CHUNKBIAS)*hm->sectionsize;
s->ents[i].shaderRGBAf[0] = 1;
s->ents[i].shaderRGBAf[1] = 1;
s->ents[i].shaderRGBAf[2] = 1;
s->ents[i].shaderRGBAf[3] = 1;
mod = Mod_FindName(Terr_Read_String(&strm, modelname, sizeof(modelname)));
org[0] = Terr_Read_Float(&strm);
org[1] = Terr_Read_Float(&strm);
org[2] = Terr_Read_Float(&strm);
axis[0][0] = Terr_Read_Float(&strm);
axis[0][1] = Terr_Read_Float(&strm);
axis[0][2] = Terr_Read_Float(&strm);
axis[1][0] = Terr_Read_Float(&strm);
axis[1][1] = Terr_Read_Float(&strm);
axis[1][2] = Terr_Read_Float(&strm);
axis[2][0] = Terr_Read_Float(&strm);
axis[2][1] = Terr_Read_Float(&strm);
axis[2][2] = Terr_Read_Float(&strm);
scale = (mf&TMF_SCALE)?Terr_Read_Float(&strm):1;
if (!s->ents[i].model)
{
s->numents--;
i--;
}
org[0] += (s->sx-CHUNKBIAS)*hm->sectionsize;
org[1] += (s->sy-CHUNKBIAS)*hm->sectionsize;
Terr_AddMesh(hm, TGS_NOLOAD, mod, org, axis, scale);
}
#endif
return ptr;
@ -1175,9 +1271,7 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
{
#ifndef SERVERONLY
int i;
#endif
s->flags |= TSF_FAILEDLOAD;
memset(s->holes, 0, sizeof(s->holes));
@ -1186,7 +1280,7 @@ static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
Q_strncpyz(s->texname[0], "", sizeof(s->texname[0]));
Q_strncpyz(s->texname[1], "", sizeof(s->texname[1]));
Q_strncpyz(s->texname[2], "", sizeof(s->texname[2]));
Q_strncpyz(s->texname[3], "", sizeof(s->texname[3]));
Q_strncpyz(s->texname[3], hm->defaultgroundtexture, sizeof(s->texname[3]));
if (s->lightmap >= 0)
{
@ -1222,6 +1316,12 @@ static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
s->mesh.colors4f_array[0] = s->colours;
#endif
for (i = 0; i < SECTHEIGHTSIZE*SECTHEIGHTSIZE; i++)
s->heights[i] = hm->defaultgroundheight;
if (hm->defaultwaterheight > hm->defaultgroundheight)
Terr_GenerateWater(s, hm->defaultwaterheight);
#if 0//def DEBUG
void *f;
if (lightmap_bytes == 4 && lightmap_bgra && FS_LoadFile(va("maps/%s/splatt.png", hm->path), &f) != (qofs_t)-1)
@ -1475,7 +1575,7 @@ static void Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, un
static void Terr_SaveV1(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, int sy)
{
int i;
dsmesh_t dm;
dsmesh_v1_t dm;
qbyte *lm;
dsection_v1_t ds;
vec4_t dcolours[SECTHEIGHTSIZE*SECTHEIGHTSIZE];
@ -1555,21 +1655,21 @@ static void Terr_SaveV1(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, i
for (i = 0; i < s->numents; i++)
{
int pad;
dm.scale = s->ents[i].scale;
VectorCopy(s->ents[i].axis[0], dm.axisorg[0]);
VectorCopy(s->ents[i].axis[1], dm.axisorg[1]);
VectorCopy(s->ents[i].axis[2], dm.axisorg[2]);
VectorCopy(s->ents[i].origin, dm.axisorg[3]);
dm.scale = s->ents[i]->ent.scale;
VectorCopy(s->ents[i]->ent.axis[0], dm.axisorg[0]);
VectorCopy(s->ents[i]->ent.axis[1], dm.axisorg[1]);
VectorCopy(s->ents[i]->ent.axis[2], dm.axisorg[2]);
VectorCopy(s->ents[i]->ent.origin, dm.axisorg[3]);
dm.axisorg[3][0] += (CHUNKBIAS-sx)*hm->sectionsize;
dm.axisorg[3][1] += (CHUNKBIAS-sy)*hm->sectionsize;
dm.size = sizeof(dm) + strlen(s->ents[i].model->name) + 1;
dm.size = sizeof(dm) + strlen(s->ents[i]->ent.model->name) + 1;
if (dm.size & 3)
pad = 4 - (dm.size&3);
else
pad = 0;
dm.size += pad;
VFS_WRITE(f, &dm, sizeof(dm));
VFS_WRITE(f, s->ents[i].model->name, strlen(s->ents[i].model->name)+1);
VFS_WRITE(f, s->ents[i]->ent.model->name, strlen(s->ents[i]->ent.model->name)+1);
if (pad)
VFS_WRITE(f, &nothing, pad);
}
@ -1812,7 +1912,13 @@ qboolean Terrain_LocateSection(char *name, flocation_t *loc)
void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusable)
{
int i;
RemoveLink(&s->recycle);
for (i = 0; i < s->numents; i++)
s->ents[i]->refs-=1;
s->numents = 0;
#ifndef SERVERONLY
if (s->lightmap >= 0)
{
@ -2601,7 +2707,13 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h)
{
vec3_t dist;
float a;
model_t *model = s->ents[i].model;
model_t *model;
//skip the entity if its already been added to some batch this frame.
if (s->ents[i]->drawnframe == hm->drawnframe)
continue;
s->ents[i]->drawnframe = hm->drawnframe;
model = s->ents[i]->ent.model;
if (!model)
continue;
@ -2615,7 +2727,7 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h)
if (model->needload)
continue;
VectorSubtract(s->ents[i].origin, r_origin, dist);
VectorSubtract(s->ents[i]->ent.origin, r_origin, dist);
a = VectorLength(dist);
a = 1024 - a + model->radius*16;
a /= model->radius;
@ -2624,18 +2736,18 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h)
if (a >= 1)
{
a = 1;
s->ents[i].flags &= ~RF_TRANSLUCENT;
s->ents[i]->ent.flags &= ~RF_TRANSLUCENT;
}
else
s->ents[i].flags |= RF_TRANSLUCENT;
s->ents[i].shaderRGBAf[3] = a;
s->ents[i]->ent.flags |= RF_TRANSLUCENT;
s->ents[i]->ent.shaderRGBAf[3] = a;
switch(model->type)
{
case mod_alias:
R_GAlias_GenerateBatches(&s->ents[i], ctx->batches);
R_GAlias_GenerateBatches(&s->ents[i]->ent, ctx->batches);
break;
case mod_brush:
Surf_GenBrushBatches(ctx->batches, &s->ents[i]);
Surf_GenBrushBatches(ctx->batches, &s->ents[i]->ent);
break;
default: //FIXME: no sprites! oh noes!
break;
@ -2802,6 +2914,7 @@ void Terr_DrawTerrainModel (batch_t **batches, entity_t *e)
bounds[3] = hm->maxsegy;
}
hm->drawnframe+=1;
tdibctx.hm = hm;
tdibctx.batches = batches;
tdibctx.ent = e;
@ -3073,6 +3186,7 @@ typedef struct {
heightmap_t *hm;
int contents;
int hitcontentsmask;
trace_t *result;
} hmtrace_t;
static void Heightmap_Trace_Brush(hmtrace_t *tr, vec4_t *planes, int numplanes)
@ -3157,7 +3271,7 @@ static void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
vec3_t p[4];
vec4_t n[5];
int t;
// int i;
int i;
#ifndef STRICTEDGES
float d1, d2;
@ -3187,26 +3301,47 @@ static void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
Heightmap_Trace_Brush(tr, n, 4);
return;
}
/*
for (i = 0; i < s->numents; i++)
{
vec3_t start_l, end_l;
trace_t etr;
model_t *model = s->ents[i].model;
int frame = s->ents[i].framestate.g[FS_REG].frame[0];
if (!model || model->needload || !model->funcs.NativeTrace)
continue;
VectorSubtract (tr->start, s->ents[i].origin, start_l);
VectorSubtract (tr->end, s->ents[i].origin, end_l);
start_l[2] -= tr->mins[2];
end_l[2] -= tr->mins[2];
VectorScale(start_l, s->ents[i].scale, start_l);
VectorScale(end_l, s->ents[i].scale, end_l);
memset(&etr, 0, sizeof(etr));
etr.fraction = 1;
if (model->funcs.NativeTrace (model, 0, frame, s->ents[i].axis, start_l, end_l, tr->mins, tr->maxs, tr->hitcontentsmask, &etr))
if (s->traceseq != tr->hm->traceseq)
{
s->traceseq = tr->hm->traceseq;
for (i = 0; i < s->numents; i++)
{
vec3_t start_l, end_l;
trace_t etr;
model_t *model;
int frame;
if (s->ents[i]->traceseq == tr->hm->traceseq)
continue;
s->ents[i]->traceseq = tr->hm->traceseq;
model = s->ents[i]->ent.model;
frame = s->ents[i]->ent.framestate.g[FS_REG].frame[0];
if (!model || model->needload || !model->funcs.NativeTrace)
continue;
//figure out where on the submodel the trace is.
VectorSubtract (tr->start, s->ents[i]->ent.origin, start_l);
VectorSubtract (tr->end, s->ents[i]->ent.origin, end_l);
start_l[2] -= tr->mins[2];
end_l[2] -= tr->mins[2];
VectorScale(start_l, s->ents[i]->ent.scale, start_l);
VectorScale(end_l, s->ents[i]->ent.scale, end_l);
//skip if the local trace points are outside the model's bounds
/* for (j = 0; j < 3; j++)
{
if (start_l[j]+tr->mins[j] > model->maxs[j] && end_l[j]+tr->mins[j] > model->maxs[j])
continue;
if (start_l[j]+tr->maxs[j] < model->mins[j] && end_l[j]+tr->maxs[j] < model->mins[j])
continue;
}
*/
//do the trace
memset(&etr, 0, sizeof(etr));
etr.fraction = 1;
model->funcs.NativeTrace (model, 0, frame, s->ents[i]->ent.axis, start_l, end_l, tr->mins, tr->maxs, tr->hitcontentsmask, &etr);
tr->result->startsolid |= etr.startsolid;
tr->result->allsolid |= etr.allsolid;
if (etr.fraction < tr->frac)
{
tr->contents = etr.contents;
@ -3218,7 +3353,7 @@ static void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
}
}
}
*/
sx = tx - CHUNKBIAS*(SECTHEIGHTSIZE-1);
sy = ty - CHUNKBIAS*(SECTHEIGHTSIZE-1);
@ -3388,6 +3523,7 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
float wbias;
hmtrace_t hmtrace;
hmtrace.hm = model->terrain;
hmtrace.hm->traceseq++;
hmtrace.htilesize = hmtrace.hm->sectionsize / (SECTHEIGHTSIZE-1);
hmtrace.frac = 1;
hmtrace.contents = 0;
@ -3399,6 +3535,7 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
memset(trace, 0, sizeof(*trace));
trace->fraction = 1;
hmtrace.result = trace;
//to tile space
hmtrace.start[0] = (start[0]);
@ -4064,7 +4201,7 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
hmsection_t *s;
x = pos[0]*4 / hm->sectionsize;
y = pos[1]*4 / hm->sectionsize;
x = bound(hm->firstsegx*4, x, hm->maxsegy*4-1);
x = bound(hm->firstsegx*4, x, hm->maxsegx*4-1);
y = bound(hm->firstsegy*4, y, hm->maxsegy*4-1);
s = Terr_GetSection(hm, x/4, y/4, TGS_FORCELOAD);
@ -4142,7 +4279,7 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
hmsection_t *s;
x = pos[0] / hm->sectionsize;
y = pos[1] / hm->sectionsize;
x = bound(hm->firstsegx, x, hm->maxsegy-1);
x = bound(hm->firstsegx, x, hm->maxsegx-1);
y = bound(hm->firstsegy, y, hm->maxsegy-1);
s = Terr_GetSection(hm, x, y, TGS_LOAD);
@ -4157,7 +4294,7 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
int x, y;
x = pos[0] / hm->sectionsize;
y = pos[1] / hm->sectionsize;
x = bound(hm->firstsegx, x, hm->maxsegy-1);
x = bound(hm->firstsegx, x, hm->maxsegx-1);
y = bound(hm->firstsegy, y, hm->maxsegy-1);
ted_texkill(Terr_GetSection(hm, x, y, TGS_FORCELOAD), PR_GetStringOfs(prinst, OFS_PARM4));
@ -4165,59 +4302,36 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
break;
case ter_mesh_add:
{
entity_t *e;
float *epos;
int x, y;
hmsection_t *s;
epos = ((wedict_t *)G_EDICT(prinst, OFS_PARM1))->v->origin;
x = (epos[0] / hm->sectionsize) + CHUNKBIAS;
y = (epos[1] / hm->sectionsize) + CHUNKBIAS;
x = bound(hm->firstsegx, x, hm->maxsegy-1);
y = bound(hm->firstsegy, y, hm->maxsegy-1);
s = Terr_GetSection(hm, x, y, TGS_FORCELOAD);
if (!s)
return;
s->flags |= TSF_EDITED;
if (s->maxents == s->numents)
{
s->maxents++;
s->ents = realloc(s->ents, sizeof(*s->ents)*(s->maxents));
}
e = &s->ents[s->numents++];
memset(e, 0, sizeof(*e));
e->scale = ((wedict_t *)G_EDICT(prinst, OFS_PARM1))->xv->scale;
e->playerindex = -1;
e->shaderRGBAf[0] = 1;
e->shaderRGBAf[1] = 1;
e->shaderRGBAf[2] = 1;
e->shaderRGBAf[3] = 1;
VectorCopy(epos, e->origin);
AngleVectorsFLU(((wedict_t *)G_EDICT(prinst, OFS_PARM1))->v->angles, e->axis[0], e->axis[1], e->axis[2]);
e->model = vmw->Get_CModel(vmw, ((wedict_t *)G_EDICT(prinst, OFS_PARM1))->v->modelindex);
vec3_t axis[3];
wedict_t *ed = G_WEDICT(prinst, OFS_PARM1);
//FIXME: modeltype pitch inversion
AngleVectorsFLU(ed->v->angles, axis[0], axis[1], axis[2]);
Terr_AddMesh(hm, TGS_FORCELOAD, vmw->Get_CModel(vmw, ed->v->modelindex), ed->v->origin, axis, ed->xv->scale);
}
break;
case ter_mesh_kill:
{
// int i;
int i;
// entity_t *e;
int x, y;
// float r;
hmsection_t *s;
x = pos[0] / hm->sectionsize;
y = pos[1] / hm->sectionsize;
x = bound(hm->firstsegx, x, hm->maxsegy-1);
x = bound(hm->firstsegx, x, hm->maxsegx-1);
y = bound(hm->firstsegy, y, hm->maxsegy-1);
s = Terr_GetSection(hm, x, y, TGS_FORCELOAD);
if (!s)
return;
s->numents = 0;
s->flags |= TSF_EDITED;
if (s->numents)
{
for (i = 0; i < s->numents; i++)
s->ents[i]->refs -= 1;
s->flags |= TSF_EDITED;
s->numents = 0;
}
/*for (i = 0; i < s->numents; i++)
{
@ -4241,6 +4355,11 @@ void Terr_ParseEntityLump(char *data, heightmap_t *heightmap)
heightmap->sectionsize = 1024;
heightmap->mode = HMM_TERRAIN;
heightmap->defaultgroundheight = 0;
heightmap->defaultwaterheight = 0;
Q_strncpyz(heightmap->defaultwatershader, va("water/%s", heightmap->path), sizeof(heightmap->defaultwatershader));
Q_strncpyz(heightmap->defaultgroundtexture, "", sizeof(heightmap->defaultgroundtexture));
if (data)
if ((data=COM_Parse(data))) //read the map info.
if (com_token[0] == '{')
@ -4251,7 +4370,7 @@ void Terr_ParseEntityLump(char *data, heightmap_t *heightmap)
if (com_token[0] == '}')
break; // end of worldspawn
if (com_token[0] == '_')
strcpy(key, com_token + 1); //_ vars are for comments/utility stuff that arn't visible to progs. Ignore them.
strcpy(key, com_token + 1); //_ vars are for comments/utility stuff that arn't visible to progs and for compat. We want to support these stealth things.
else
strcpy(key, com_token);
if (!((data=COM_Parse(data))))
@ -4266,6 +4385,14 @@ void Terr_ParseEntityLump(char *data, heightmap_t *heightmap)
heightmap->maxsegx = atoi(com_token);
else if (!strcmp("maxysegment", key))
heightmap->maxsegy = atoi(com_token);
else if (!strcmp("defaultwaterheight", key))
heightmap->defaultwaterheight = atof(com_token);
else if (!strcmp("defaultgroundheight", key))
heightmap->defaultgroundheight = atof(com_token);
else if (!strcmp("defaultgroundtexture", key))
Q_strncpyz(heightmap->defaultgroundtexture, key, sizeof(heightmap->defaultgroundtexture));
else if (!strcmp("defaultwatertexture", key))
Q_strncpyz(heightmap->defaultwatershader, key, sizeof(heightmap->defaultwatershader));
else if (!strcmp("tiles", key))
{
char *d;
@ -4302,7 +4429,6 @@ void Terr_FinishTerrain(heightmap_t *hm, char *shadername, char *skyname)
#ifndef SERVERONLY
if (qrenderer != QR_NONE)
{
Q_strncpyz(hm->watershadername, va("water/%s", hm->path), sizeof(hm->watershadername));
if (skyname)
hm->skyshader = R_RegisterCustom(va("skybox_%s", skyname), SUF_NONE, Shader_DefaultSkybox, NULL);
else
@ -4433,7 +4559,7 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
mod->mins[0] = (hm->firstsegx - CHUNKBIAS) * hm->sectionsize;
mod->mins[1] = (hm->firstsegy - CHUNKBIAS) * hm->sectionsize;
mod->mins[2] = -999999999999999999999999.f;
mod->maxs[0] = (hm->maxsegy - CHUNKBIAS) * hm->sectionsize;
mod->maxs[0] = (hm->maxsegx - CHUNKBIAS) * hm->sectionsize;
mod->maxs[1] = (hm->maxsegy - CHUNKBIAS) * hm->sectionsize;
mod->maxs[2] = 999999999999999999999999.f;
@ -4525,6 +4651,10 @@ void Mod_Terrain_Create_f(void)
"_minysegment -2048\n"
"_maxxsegment 2048\n"
"_maxysegment 2048\n"
"//_defaultgroundtexture city4_2\n"
"//_defaultwatertexture *water2\n"
"//_defaultgroundheight -1024\n"
"//_defaultwaterheight 0\n" //hurrah, sea level.
// "_tiles 64 64 8 8\n"
"}\n"
"{\n"
@ -4533,6 +4663,8 @@ void Mod_Terrain_Create_f(void)
"}\n"
, Cmd_Argv(2));
COM_WriteFile(mname, mdata, strlen(mdata));
//FIXME: create 4 sections around the origin
}
//reads in the terrain a tile at a time, and writes it out again.
//the new version will match our current format version.

View File

@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#ifndef SERVERONLY //FIXME
#if 1//ndef SERVERONLY //FIXME
#include "glquake.h"
#include "com_mesh.h"
@ -33,6 +33,14 @@ extern cvar_t r_shadow_bumpscale_basetexture;
extern cvar_t r_replacemodels;
extern cvar_t gl_lightmap_average;
#ifdef SERVERONLY
cvar_t gl_overbright, gl_specular, gl_load24bit, r_replacemodels, gl_miptexLevel, r_fb_bmodels; //all of these can/should default to 0
cvar_t r_noframegrouplerp = CVARF ("r_noframegrouplerp", "0", CVAR_ARCHIVE);
cvar_t dpcompat_psa_ungroup = CVAR ("dpcompat_psa_ungroup", "0");
texture_t r_notexture_mip_real;
texture_t *r_notexture_mip = &r_notexture_mip_real;
#endif
qboolean isnotmap = true; //used to not warp ammo models.
model_t *loadmodel;
@ -53,7 +61,7 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose);
qboolean Mod_LoadDoomLevel(model_t *mod);
#endif
#ifdef DOOMWADS
#ifdef DSPMODELS
void Mod_LoadDoomSprite (model_t *mod);
#endif
@ -95,8 +103,8 @@ void Mod_UpdateLightmap(int snum)
}
#endif
void Mod_MemList_f(void)
#ifndef SERVERONLY
static void Mod_MemList_f(void)
{
int m;
model_t *mod;
@ -110,7 +118,7 @@ void Mod_MemList_f(void)
Con_Printf("Total: %i bytes\n", total);
}
void Mod_BatchList_f(void)
static void Mod_BatchList_f(void)
{
int m, i;
model_t *mod;
@ -147,7 +155,7 @@ void Mod_BatchList_f(void)
}
}
void Mod_TextureList_f(void)
static void Mod_TextureList_f(void)
{
int m, i;
texture_t *tx;
@ -190,7 +198,7 @@ void Mod_TextureList_f(void)
Con_Printf("%u\n", count);
}
void Mod_BlockTextureColour_f (void)
static void Mod_BlockTextureColour_f (void)
{
char texname[64];
model_t *mod;
@ -236,7 +244,7 @@ void Mod_BlockTextureColour_f (void)
}
}
}
#endif
#if defined(RUNTIMELIGHTING) && defined(MULTITHREAD)
@ -476,7 +484,9 @@ void Mod_Purge(enum mod_purge_e ptype)
//brush models cannot be safely flushed.
if (!unused && ptype != MP_RESET)
continue;
#ifndef SERVERONLY
Surf_Clear(mod);
#endif
}
#ifdef TERRAIN
@ -511,17 +521,21 @@ void Mod_Init (qboolean initial)
mod_numknown = 0;
Q1BSP_Init();
#ifndef SERVERONLY
Cmd_AddCommand("mod_memlist", Mod_MemList_f);
Cmd_AddCommand("mod_batchlist", Mod_BatchList_f);
Cmd_AddCommand("mod_texturelist", Mod_TextureList_f);
Cmd_AddCommand("mod_usetexture", Mod_BlockTextureColour_f);
#endif
}
if (initial)
{
Alias_Register();
#ifdef SPRMODELS
Mod_RegisterModelFormatMagic(NULL, "Quake1 Sprite (spr)", IDSPRITEHEADER, Mod_LoadSpriteModel);
#endif
#ifdef SP2MODELS
Mod_RegisterModelFormatMagic(NULL, "Quake2 Sprite (sp2)", IDSPRITE2HEADER, Mod_LoadSprite2Model);
#endif
@ -837,7 +851,9 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
mod->maxs[2] = 16;
mod->needload = false;
mod->engineflags = 0;
#ifndef SERVERONLY
P_LoadedModel(mod);
#endif
return mod;
}
@ -927,7 +943,7 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf));
if (!buf)
{
#ifdef DOOMWADS
#ifdef DSPMODELS
if (doomsprite) // special case needed for doom sprites
{
mod->needload = false;
@ -962,8 +978,10 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
{
if (!modelloaders[i].load(mod, buf, com_filesize))
continue;
#ifndef SERVERONLY
if (mod->type == mod_brush)
Surf_BuildModelLightmaps(mod);
#endif
}
else
{
@ -997,8 +1015,10 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
#endif
*/
#ifndef SERVERONLY
P_LoadedModel(mod);
Validation_IncludeFile(mod->name, (char *)buf, com_filesize);
#endif
TRACE(("Mod_LoadModel: Loaded\n"));
@ -1045,7 +1065,9 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
mod->maxs[2] = 16;
mod->needload = 2;
mod->engineflags = 0;
#ifndef SERVERONLY
P_LoadedModel(mod);
#endif
return mod;
}
@ -1264,6 +1286,7 @@ void Mod_LoadAdvancedTexture(char *name, int *base, int *norm, int *luma, int *g
void Mod_FinishTexture(texture_t *tx, texnums_t tn)
{
#ifndef SERVERONLY
extern cvar_t gl_shadeq1_name;
char altname[MAX_QPATH];
char *star;
@ -1285,14 +1308,16 @@ void Mod_FinishTexture(texture_t *tx, texnums_t tn)
}
R_BuildDefaultTexnums(&tn, tx->shader);
#endif
}
#define LMT_DIFFUSE 1
#define LMT_FULLBRIGHT 2
#define LMT_BUMP 4
#define LMT_SPEC 8
void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps)
static void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps)
{
#ifndef SERVERONLY
char altname[256];
qbyte *base;
qboolean alphaed;
@ -1414,6 +1439,7 @@ void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps)
}
}
}
#endif
}
/*
@ -1627,6 +1653,7 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
void Mod_NowLoadExternal(void)
{
#ifndef SERVERONLY
int i, width, height;
qboolean alphaed;
texture_t *tx;
@ -1693,6 +1720,7 @@ void Mod_NowLoadExternal(void)
}
Mod_FinishTexture(tx, tn);
}
#endif
}
qbyte lmgamma[256];
@ -1768,6 +1796,7 @@ void Mod_LoadLighting (lump_t *l)
if (!samples)
return;
#ifndef SERVERONLY
if (!luxdata && r_loadlits.ival && r_deluxemapping.ival)
{ //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous.
char luxname[MAX_QPATH];
@ -1927,6 +1956,7 @@ void Mod_LoadLighting (lump_t *l)
// else
//failed to find
}
#endif
#ifdef RUNTIMELIGHTING
if (r_loadlits.value == 2 && !lightmodel && (!litdata || (!luxdata && r_deluxemapping.ival)))
@ -2007,8 +2037,10 @@ void Mod_LoadLighting (lump_t *l)
*out++ = lmgamma[*litdata++];
}
#ifndef SERVERONLY
if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && r_lightmap_saturation.value != 1.0f)
SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value);
#endif
}
/*
@ -2485,6 +2517,7 @@ qboolean Mod_LoadFaces (lump_t *l, qboolean lm, mesh_t **meshlist)
return true;
}
#ifndef SERVERONLY
void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, void *cookie)
{
int i, lindex;
@ -3115,7 +3148,7 @@ void Mod_Batches_Build(mesh_t *meshlist, model_t *mod, void (*build)(model_t *mo
if (BE_GenBrushModelVBO)
BE_GenBrushModelVBO(mod);
}
#endif
/*
=================
@ -3985,27 +4018,7 @@ qboolean Mod_LoadPlanes (lump_t *l)
return true;
}
/*
=================
RadiusFromBounds
=================
*/
float RadiusFromBounds (vec3_t mins, vec3_t maxs);
/*
{
int i;
vec3_t corner;
for (i=0 ; i<3 ; i++)
{
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
}
return Length (corner);
}
*/
#ifndef SERVERONLY
//combination of R_AddDynamicLights and R_MarkLights
static void Q1BSP_StainNode (mnode_t *node, float *parms)
{
@ -4043,6 +4056,7 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms)
Q1BSP_StainNode (node->children[0], parms);
Q1BSP_StainNode (node->children[1], parms);
}
#endif
void Mod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent)
{
@ -4073,7 +4087,8 @@ void Mod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent)
}
}
void Mod_FixupMinsMaxs(void)
static void Mod_FixupMinsMaxs(void)
{
//q1 bsps are capped to +/- 32767 by the nodes/leafs
//verts arn't though
@ -4125,17 +4140,17 @@ void Mod_FixupMinsMaxs(void)
lnumverts = surf->numedges;
for (en=0 ; en<lnumverts ; en++)
{
lindex = currentmodel->surfedges[surf->firstedge + en];
lindex = loadmodel->surfedges[surf->firstedge + en];
if (lindex > 0)
{
e = &pedges[lindex];
v = currentmodel->vertexes[e->v[0]].position;
v = loadmodel->vertexes[e->v[0]].position;
}
else
{
e = &pedges[-lindex];
v = currentmodel->vertexes[e->v[1]].position;
v = loadmodel->vertexes[e->v[1]].position;
}
if (pleaf->minmaxs[0] > v[0])
@ -4184,6 +4199,9 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
header = (dheader_t *)buffer;
#ifdef SERVERONLY
isnotmap = !!sv.world.worldmodel;
#else
if ((!cl.worldmodel && cls.state>=ca_connected)
#ifndef CLIENTONLY
|| (!sv.world.worldmodel && sv.active)
@ -4192,6 +4210,7 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
isnotmap = false;
else
isnotmap = true;
#endif
i = LittleLong (header->version);
@ -4267,18 +4286,10 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
crouchhullfile = NULL;
TRACE(("Loading info\n"));
#ifndef CLIENTONLY
if (sv.state) //if the server is running
{
if (!strcmp(loadmodel->name, va("maps/%s.bsp", sv.name)))
Mod_ParseInfoFromEntityLump(loadmodel, mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
}
else
#ifndef SERVERONLY
if (!isnotmap)
Mod_ParseInfoFromEntityLump(loadmodel, mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
#endif
{
if (!cl.model_precache[1]) //not copied across yet
Mod_ParseInfoFromEntityLump(loadmodel, mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
}
// load into heap
if (!isDedicated || ode)
@ -4357,9 +4368,11 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
TRACE(("LoadBrushModel %i\n", __LINE__));
Q1BSP_SetModelFuncs(mod);
TRACE(("LoadBrushModel %i\n", __LINE__));
#ifndef SERVERONLY
mod->funcs.LightPointValues = GLQ1BSP_LightPointValues;
mod->funcs.StainNode = Q1BSP_StainNode;
mod->funcs.MarkLights = Q1BSP_MarkLights;
mod->funcs.StainNode = Q1BSP_StainNode;
#endif
mod->numframes = 2; // regular and alternate animation
@ -4371,6 +4384,7 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
{
bm = &mod->submodels[i];
mod->rootnode = mod->nodes + bm->headnode[0];
mod->hulls[0].firstclipnode = bm->headnode[0];
mod->hulls[0].available = true;
Q1BSP_CheckHullNodes(&mod->hulls[0]);
@ -4404,7 +4418,9 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
TRACE(("LoadBrushModel %i\n", __LINE__));
if (meshlist)
{
#ifndef SERVERONLY
Mod_Batches_Build(meshlist, mod, NULL, NULL);
#endif
}
TRACE(("LoadBrushModel %i\n", __LINE__));
@ -4447,6 +4463,7 @@ ALIAS MODELS
//=========================================================
#ifdef SPRMODELS
/*
=================
Mod_LoadSpriteFrame
@ -4755,6 +4772,7 @@ qboolean QDECL Mod_LoadSpriteModel (model_t *mod, void *buffer, size_t fsize)
return true;
}
#endif
#ifdef SP2MODELS
qboolean QDECL Mod_LoadSprite2Model (model_t *mod, void *buffer, size_t fsize)
@ -4843,7 +4861,7 @@ qboolean QDECL Mod_LoadSprite2Model (model_t *mod, void *buffer, size_t fsize)
}
#endif
#ifdef DOOMWADS
#ifdef DSPMODELS
typedef struct {
short width;

View File

@ -373,11 +373,13 @@ typedef struct msurface_s
mtexinfo_t *texinfo;
int visframe; // should be drawn when node is crossed
int shadowframe;
int clipcount;
// lighting info
// legacy lighting info
int dlightframe;
int dlightbits;
//static lighting
int lightmaptexturenums[MAXRLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps
qbyte styles[MAXQ1LIGHTMAPS];
qbyte vlstyles[MAXRLIGHTMAPS];
@ -455,8 +457,8 @@ typedef struct mleaf_s
int area;
unsigned int firstleafbrush;
unsigned int numleafbrushes;
unsigned int firstleafface;
unsigned int numleaffaces;
unsigned int firstleafcmesh;
unsigned int numleafcmeshes;
unsigned int firstleafpatch;
unsigned int numleafpatches;
#endif
@ -884,6 +886,7 @@ typedef struct model_s
int numnodes;
mnode_t *nodes;
void *cnodes;
mnode_t *rootnode;
int numtexinfo;
mtexinfo_t *texinfo;
@ -1014,7 +1017,6 @@ qbyte *CM_ClusterPHS (struct model_s *mod, int cluster);
int CM_BoxLeafnums (struct model_s *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
int CM_PointContents (struct model_s *mod, vec3_t p);
int CM_TransformedPointContents (struct model_s *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles);
struct trace_s CM_BoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask);
int CM_HeadnodeForBox (struct model_s *mod, vec3_t mins, vec3_t maxs);
struct trace_s CM_TransformedBoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask, vec3_t origin, vec3_t angles);
struct model_s *CM_TempBoxModel(vec3_t mins, vec3_t maxs);

View File

@ -1010,6 +1010,13 @@ void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_a
res_ambient[0] = 255; //out of the map
res_ambient[1] = 255;
res_ambient[2] = 255;
if (res_diffuse)
{
res_diffuse[0] = 255;
res_diffuse[1] = 255;
res_diffuse[2] = 255;
}
return;
}
}
@ -1209,7 +1216,7 @@ int R_LightPoint (vec3_t p)
end[1] = p[1];
end[2] = p[2] - 2048;
r = GLRecursiveLightPoint (cl.worldmodel->nodes, p, end);
r = GLRecursiveLightPoint (cl.worldmodel->rootnode, p, end);
if (r == -1)
r = 0;
@ -1234,7 +1241,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
int i;
mtexinfo_t *tex;
qbyte *lightmap, *deluxmap;
float scale;
float scale, overbright;
int maps;
if (cl.worldmodel->fromgame == fg_quake2)
@ -1309,6 +1316,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[3]=0;l[4]=0;l[5]=0;
if (lightmap)
{
overbright = 1/255.0f;
if (cl.worldmodel->deluxdata)
{
if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING)
@ -1320,7 +1328,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += lightmap[0] * scale;
@ -1349,7 +1357,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += *lightmap * scale;
@ -1378,7 +1386,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += lightmap[0] * scale;
@ -1398,7 +1406,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
if (cl_lightstyle[surf->styles[maps]].colour & 1)
l[0] += *lightmap * scale;
@ -1450,7 +1458,7 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse,
end[1] = point[1];
end[2] = point[2] - 2048;
r = GLRecursiveLightPoint3C(model->nodes, point, end);
r = GLRecursiveLightPoint3C(model->rootnode, point, end);
if (r == NULL)
{
res_diffuse[0] = 0;
@ -1467,14 +1475,14 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse,
}
else
{
res_diffuse[0] = r[0];
res_diffuse[1] = r[1];
res_diffuse[2] = r[2];
res_diffuse[0] = r[0]*2;
res_diffuse[1] = r[1]*2;
res_diffuse[2] = r[2]*2;
/*bright on one side, dark on the other, but not too dark*/
res_ambient[0] = r[0]/3;
res_ambient[1] = r[1]/3;
res_ambient[2] = r[2]/3;
res_ambient[0] = r[0]/2;
res_ambient[1] = r[1]/2;
res_ambient[2] = r[2]/2;
res_dir[0] = r[3];
res_dir[1] = r[4];

View File

@ -4607,10 +4607,17 @@ void Shader_DefaultSkinShell(const char *shortname, shader_t *s, const void *arg
Shader_DefaultScript(shortname, s,
"{\n"
"sort blend\n"
"deformvertexes normal 1 1\n"
"sort seethrough\n" //before blend, but after other stuff. should fix most issues with shotgun etc effects obscuring it.
// "deformvertexes normal 1 1\n"
//draw it with depth but no colours at all
"{\n"
"map $diffuse\n"
"map $whiteimage\n"
"maskcolor\n"
"depthwrite\n"
"}\n"
//now draw it again, depthfunc = equal should fill only the near-side, avoiding any excess-brightness issues with overlapping triangles
"{\n"
"map $whiteimage\n"
"rgbgen entity\n"
"alphagen entity\n"
"blendfunc blend\n"

View File

@ -70,32 +70,33 @@ BINDTEXFUNCPTR qglBindTexture;
/*glslang - arb_shader_objects
gl core uses different names/distinctions from the extension
*/
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB;
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv;
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv;
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB;
FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
FTEPFNGLUNIFORM4FVARBPROC qglUniform2fvARB;
FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB;
FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
FTEPFNGLUNIFORM4FVARBPROC qglUniform2fvARB;
FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
FTEPFNGLGETSHADERSOURCEARBPROC qglGetShaderSource;
#endif
//standard 1.1 opengl calls
void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref);
@ -803,6 +804,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglUniform2fvARB = NULL;
qglUniform1iARB = NULL;
qglUniform1fARB = NULL;
qglGetShaderSource = NULL;
}
// glslang
//the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects.
@ -852,6 +854,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglGetVertexAttribPointerv = (void *)getglext("glGetVertexAttribPointerv");
qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArray");
qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArray");
qglGetShaderSource = (void *)getglext("glGetShaderSource");
Con_DPrintf("GLSL available\n");
}
else if (GL_CheckExtension("GL_ARB_fragment_shader")
@ -890,6 +893,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglUniform2fvARB = (void *)getglext("glUniform2fvARB");
qglUniform1iARB = (void *)getglext("glUniform1iARB");
qglUniform1fARB = (void *)getglext("glUniform1fARB");
qglGetShaderSource = (void *)getglext("glGetShaderSourceARB");
Con_DPrintf("GLSL available\n");
}
@ -1365,12 +1369,11 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
// glslang helper api function definitions
// type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB
GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char **precompilerconstants, const char *shadersource, GLenum shadertype, qboolean silent)
//doesn't check to see if it was okay. use FinishShader for that.
static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char **precompilerconstants, const char *shadersource, GLenum shadertype, qboolean silent)
{
GLhandleARB shader;
GLint compiled;
char str[1024];
int loglen, i;
int i;
const GLchar *prstrings[64+16];
GLint length[sizeof(prstrings)/sizeof(prstrings[0])];
int strings = 0;
@ -1511,9 +1514,24 @@ GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char **precom
qglShaderSourceARB(shader, strings, prstrings, length);
qglCompileShaderARB(shader);
return shader;
}
//called after CreateShader. Checks for success.
//Splitting creation allows for both vertex+fragment shaders to be processed simultaneously if the driver threads glCompileShaderARB.
static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GLenum shadertype, qboolean silent)
{
GLint compiled;
int loglen;
if (!shader) //if there's no shader, then there was nothing to finish...
return shader;
qglGetShaderParameteriv_(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
if(!compiled)
{
char str[8192];
qglGetShaderInfoLog_(shader, sizeof(str), NULL, str);
qglDeleteShaderObject_(shader);
if (!silent)
@ -1530,19 +1548,11 @@ GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char **precom
Con_Printf("Shader_CreateShader: This shouldn't happen ever\n");
break;
}
Con_DPrintf("Shader \"%s\" source:\n", name);
for (i = 0; i < strings; i++)
if (developer.ival)
{
int j;
if (length[i] < 0)
Con_DPrintf("%s", prstrings[i]);
else
{
for (j = 0; j < length[i]; j++)
Con_DPrintf("%c", prstrings[i][j]);
}
qglGetShaderSource(shader, sizeof(str), NULL, str);
Con_Printf("Shader \"%s\" source:\n%s", name, str);
}
Con_DPrintf("%s\n", str);
}
return 0;
}
@ -1552,13 +1562,14 @@ GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char **precom
qglGetShaderParameteriv_(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &loglen);
if (loglen)
{
char str[8192];
qglGetShaderInfoLog_(shader, sizeof(str), NULL, str);
if (strstr(str, "WARNING"))
{
Con_Printf("Shader source:\n");
for (i = 0; i < strings; i++)
Con_Printf("%s", prstrings[i]);
Con_Printf("%s\n", str);
Con_Printf("Shader \"%s\" log:\n%s", name, str);
qglGetShaderSource(shader, sizeof(str), NULL, str);
Con_Printf("Shader \"%s\" source:\n%s", name, str);
}
}
}
@ -1568,9 +1579,9 @@ GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char **precom
GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLhandleARB frag, qboolean silent)
{
GLhandleARB program;
GLint linked;
char str[2048];
GLhandleARB program;
GLint linked;
char str[2048];
program = qglCreateProgramObjectARB();
qglAttachObjectARB(program, vert);
@ -1629,8 +1640,11 @@ GLhandleARB GLSlang_CreateProgram(const char *name, int ver, const char **precom
if (!precompilerconstants)
precompilerconstants = &nullconstants;
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_SHADER_ARB, silent);
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB, silent);
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_SHADER_ARB, silent);
fs = GLSlang_FinishShader(fs, name, GL_FRAGMENT_SHADER_ARB, silent);
vs = GLSlang_FinishShader(vs, name, GL_VERTEX_SHADER_ARB, silent);
if (!vs || !fs)
handle = 0;
@ -1653,7 +1667,7 @@ GLhandleARB GLSlang_CreateProgram(const char *name, int ver, const char **precom
len = ui;
blobdata = BZ_Malloc(len);
qglGetProgramBinary(handle, len, NULL, &e, blobdata);
qglGetProgramBinary(handle, len, NULL, &e, blobdata);
fmt = e;
VFS_WRITE(blobfile, &fmt, sizeof(fmt));

View File

@ -47,6 +47,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void D3D9_Set2D (void);
float RadiusFromBounds (vec3_t mins, vec3_t maxs);
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
void ClearBounds (vec3_t mins, vec3_t maxs);
@ -180,6 +181,7 @@ typedef void (APIENTRYP FTEPFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei c
typedef void (APIENTRYP FTEPFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (APIENTRYP FTEPFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
typedef void (APIENTRYP FTEPFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
typedef void (APIENTRYP FTEPFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
typedef void (APIENTRY * FTEPFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
typedef void (APIENTRY * FTEPFNGLUNLOCKARRAYSEXTPROC) (void);

View File

@ -9,6 +9,7 @@ char effects[][64] =
"high.cfg",
"minimal.cfg",
"h2part.cfg",
"q2part.cfg",
"tsshaft.cfg",
""
};

158
engine/partcfgs/q2part.cfg Normal file
View File

@ -0,0 +1,158 @@
r_part pe_default
{
texture "classicparticle"
tcoords 0 0 16 16 32
count 1
scale 1
alpha 1
die 0.3 0.8
randomvel 20
orgadd 0 31
spawnorg 4
gravity 40
scalefactor 0.8
}
r_part q2_smoke
{
count 0 0 1
model "models/objects/smoke/tris.md2" framestart=0 frameend=4 framerate=10 alpha=1
}
r_part q2_smokeandflash
{
count 0 0 1
model "models/objects/flash/tris.md2" framestart=0 frameend=2 framerate=10 alpha=-1 fullbright
assoc q2_smoke
}
r_part teq2_gunshot /*machinegun*/
{
texture "classicparticle"
tcoords 0 0 16 16 32
count 40
scale 1
alpha 1
die 0.3 0.8
randomvel 20
orgadd 0 31
spawnorg 4
gravity 40
scalefactor 0.8
colorindex 0 7
/*smoke puff models*/
assoc q2_smokeandflash
/*low chance of various sounds*/
sound world/ric1.wav 1 1 0 0 1
sound world/ric2.wav 1 1 0 0 1
sound world/ric3.wav 1 1 0 0 1
sound "" 1 1 0 0 12
}
r_part teq2_shotgun /*shotgun... duh*/
{
texture "classicparticle"
tcoords 0 0 16 16 32
count 20
scale 1
alpha 1
die 0.3 0.8
randomvel 20
orgadd 0 31
spawnorg 4
gravity 40
scalefactor 0.8
colorindex 0 7
/*smoke puff models*/
assoc q2_smokeandflash
}
r_part teq2_blood
{
texture "classicparticle"
tcoords 0 0 16 16 32
count 60
scale 1
alpha 1
die 0.3 0.8
randomvel 20
orgadd 0 31
spawnorg 4
gravity 40
scalefactor 0.8
colorindex 232 7
}
r_part q2_blasterpuff
{
count 0 0 1
model "models/objects/explode/tris.md2" framestart=0 frameend=4 framerate=10 alpha=1 orient additive fullbright noshadow
}
r_part teq2_blaster
{
texture "classicparticle"
tcoords 0 0 16 16 32
count 60
scale 1
alpha 1
die 0.3 0.8
randomvel 40
orgadd 0 15
veladd 30
spawnorg 4
gravity 40
scalefactor 0.8
colorindex 0xe0 7
assoc q2_blasterpuff /*the model*/
lightradius 150
lightradiusfade 400
lightrgb 1 1 0
lightshadows 0
sound "weapons/lashit.wav" 1 1 0 0
}
r_part TR_BLASTERTRAIL
{
texture "classicparticle"
tcoords 0 0 16 16 32
scale 0.5
alpha 1
scalefactor 0.8
step 5
spawnorg 1
randomvel 5
die 0.3 0.5
colorindex 0xe0
}
r_part TR_RAILTRAIL
{
/*blue spiral*/
texture "classicparticle"
tcoords 0 0 16 16 32
scale 0.5
alpha 1
scalefactor 0.8
step 1
spawnmode spiral 64
spawnorg 3
spawnvel 6
die 1 1.2
colorindex 116 7
sound "weapons/railgf1a.wav" 1 1 0 0
}
r_part +TR_RAILTRAIL
{
/*grey filler*/
texture "classicparticle"
tcoords 0 0 16 16 32
scale 0.5
alpha 1
scalefactor 0.8
step 0.75
spawnorg 3
spawnvel 3
die 0.6 0.8
colorindex 0 15
}

View File

@ -1329,7 +1329,7 @@ void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
}
else
{
short datas = (int)(in*8);
short datas = (int)(in*8)&0xffff;
datas = LittleShort(datas);
NPP_AddData(&datas, sizeof(short));

View File

@ -9233,7 +9233,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"strcat", PF_strcat, 0, 0, 0, 115, "string(string s1, optional string s2, ...)"}, // (FRIK_FILE)
{"substring", PF_substring, 0, 0, 0, 116, "string(string s, float start, float length)"}, // (FRIK_FILE)
{"stov", PF_stov, 0, 0, 0, 117, "vector(string s)"}, // (FRIK_FILE)
{"strzone", PF_dupstring, 0, 0, 0, 118, "string(string s)"}, // (FRIK_FILE)
{"strzone", PF_dupstring, 0, 0, 0, 118, "string(string s, ...)"}, // (FRIK_FILE)
{"strunzone", PF_forgetstring, 0, 0, 0, 119, "void(string s)"}, // (FRIK_FILE)
//end frikfile

View File

@ -1811,7 +1811,6 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
{
#ifdef Q3SERVER
case SCP_QUAKE3:
Huff_PreferedCompressionCRC();
if (client->frameunion.q3frames)
Z_Free(client->frameunion.q3frames);
client->frameunion.q3frames = Z_Malloc(Q3UPDATE_BACKUP*sizeof(*client->frameunion.q3frames));
@ -2721,7 +2720,12 @@ client_t *SVC_DirectConnect(void)
//this is used by q3 (note, we already decrypted the huffman connection packet in a hack)
if (!sv_listen_q3.value)
{
if (!sv_listen_nq.value)
SV_RejectMessage (SCP_DARKPLACES6, "Server is not accepting quake3 clients at this time.\n", version_string());
Con_TPrintf ("* rejected connect from q3 client\n");
return NULL;
}
numssclients = 1;
protocol = SCP_QUAKE3;
@ -2748,11 +2752,20 @@ client_t *SVC_DirectConnect(void)
s = Info_ValueForKey(userinfo[0], "name");
if (!*s)
Info_SetValueForKey(userinfo[0], "name", "UnnamedQ3", sizeof(userinfo[0]));
#ifdef HUFFNETWORK
huffcrc = HUFFCRC_QUAKE3;
#endif
}
else if (*(Cmd_Argv(0)+7) == '\\')
{ //DP has the userinfo attached directly to the end of the connect command
if (!sv_listen_dp.value)
{
if (!sv_listen_nq.value)
SV_RejectMessage (SCP_DARKPLACES6, "Server is not accepting darkplaces clients at this time.\n", version_string());
Con_TPrintf ("* rejected connect from dp client\n");
return NULL;
}
Q_strncpyz (userinfo[0], net_message.data + 11, sizeof(userinfo[0])-1);
if (strcmp(Info_ValueForKey(userinfo[0], "protocol"), "darkplaces 3"))
@ -2903,6 +2916,7 @@ client_t *SVC_DirectConnect(void)
}
break;
case PROTOCOL_VERSION_HUFFMAN:
#ifdef HUFFNETWORK
huffcrc = Q_atoi(Cmd_Argv(1));
Con_DPrintf("Client supports huffman compression. crc 0x%x\n", huffcrc);
if (!net_compress.ival || !Huff_CompressionCRC(huffcrc))
@ -2911,6 +2925,7 @@ client_t *SVC_DirectConnect(void)
Con_TPrintf ("* rejected - bad compression state\n");
return NULL;
}
#endif
break;
case PROTOCOL_VERSION_FRAGMENT:
mtu = Q_atoi(Cmd_Argv(1)) & ~7;
@ -3265,6 +3280,13 @@ client_t *SVC_DirectConnect(void)
case GT_LUA:
#endif
case GT_PROGS:
if (protocol == SCP_QUAKE2)
{
SV_RejectMessage(protocol, "This is a Quake server.");
Con_DPrintf ("* Rejected q2 client.\n");
return NULL;
}
if (svprogfuncs)
ent = EDICT_NUM(svprogfuncs, edictnum);
else
@ -3279,6 +3301,7 @@ client_t *SVC_DirectConnect(void)
if (reject)
{
SV_RejectMessage(protocol, "%s", reject);
Con_DPrintf ("* Game rejected a connection.\n");
return NULL;
}
}
@ -3287,12 +3310,26 @@ client_t *SVC_DirectConnect(void)
#ifdef Q2SERVER
case GT_QUAKE2:
if (protocol != SCP_QUAKE2)
{
SV_RejectMessage(protocol, "This is a Quake2 server.");
Con_DPrintf ("* Rejected non-q2 client.\n");
return NULL;
}
q2ent = Q2EDICT_NUM(edictnum);
temp.edict = NULL;
temp.q2edict = q2ent;
if (!ge->ClientConnect(q2ent, temp.userinfo))
{
const char *reject = Info_ValueForKey(temp.userinfo, "rejmsg");
if (*reject)
SV_RejectMessage(protocol, "%s\nConnection Refused.", reject);
else
SV_RejectMessage(protocol, "Connection Refused.");
Con_DPrintf ("Game rejected a connection.\n");
return NULL;
}
ge->ClientUserinfoChanged(q2ent, temp.userinfo);
@ -3337,10 +3374,12 @@ client_t *SVC_DirectConnect(void)
Netchan_Setup (NS_SERVER, &newcl->netchan, &adr, qport);
#ifdef HUFFNETWORK
if (huffcrc)
newcl->netchan.compress = true;
newcl->netchan.compresstable = Huff_CompressionCRC(huffcrc);
else
newcl->netchan.compress = false;
#endif
newcl->netchan.compresstable = NULL;
if (mtu >= 64)
{
newcl->netchan.fragmentsize = mtu;
@ -3929,7 +3968,9 @@ qboolean SV_ConnectionlessPacket (void)
if (!strstr(s, "\\name\\"))
{ //if name isn't in the string, assume they're q3
//this isn't quite true though, hence the listen check. but users shouldn't be connecting with an empty name anyway. more fool them.
#ifdef HUFFNETWORK
Huff_DecryptPacket(&net_message, 12);
#endif
MSG_BeginReading(svs.netprim);
MSG_ReadLong();
s = MSG_ReadStringLine();

View File

@ -604,7 +604,7 @@ void SVNQ_New_f (void)
// set view
MSG_WriteByte (&host_client->netchan.message, svc_setview);
MSG_WriteEntity (&host_client->netchan.message, NUM_FOR_EDICT(svprogfuncs, host_client->edict));
MSG_WriteEntity (&host_client->netchan.message, host_client - svs.clients);//NUM_FOR_EDICT(svprogfuncs, host_client->edict));
MSG_WriteByte (&host_client->netchan.message, svc_signonnum);
MSG_WriteByte (&host_client->netchan.message, 1);
@ -4643,7 +4643,10 @@ void SVNQ_Spawn_f (void)
// set up the edict
ent = host_client->edict;
if (host_client->istobeloaded) //minimal setup
if (!ent)
{
}
else if (host_client->istobeloaded) //minimal setup
{
host_client->entgravity = ent->xv->gravity*sv_gravity.value;
host_client->maxspeed = ent->xv->maxspeed;
@ -4669,21 +4672,30 @@ void SVNQ_Spawn_f (void)
memset (host_client->statsf, 0, sizeof(host_client->statsf));
memset (host_client->statss, 0, sizeof(host_client->statss));
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_secrets);
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_monsters);
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_SECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->found_secrets);
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters);
if (pr_global_ptrs->total_secrets)
{
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_secrets);
}
if (pr_global_ptrs->total_monsters)
{
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_monsters);
}
if (pr_global_ptrs->found_secrets)
{
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_SECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->found_secrets);
}
if (pr_global_ptrs->killed_monsters)
{
ClientReliableWrite_Begin (host_client, svcnq_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters);
}
MSG_WriteByte (&host_client->netchan.message, svc_signonnum);
MSG_WriteByte (&host_client->netchan.message, 3);
@ -4847,7 +4859,7 @@ void SVNQ_NQColour_f (void)
playercolor = top*16 + bottom;
if (progstype != PROG_QW)
if (progstype != PROG_QW && host_client->edict)
host_client->edict->v->team = bottom + 1;
Info_SetValueForKey(host_client->userinfo, "topcolor", va("%i", top), sizeof(host_client->userinfo));

View File

@ -825,8 +825,11 @@ qboolean SVQ2_InitGameProgs(void)
return false;
}
//stop q2 from crashing.
if (!deathmatch.value && !coop.value)
maxclients.value = 1;
else
maxclients.value = maxclients.ival;
if (maxclients.value > MAX_CLIENTS)
Cvar_SetValue(&maxclients, MAX_CLIENTS);

View File

@ -2544,7 +2544,7 @@ void SVQ3Q1_SendGamestateConfigstrings(sizebuf_t *msg)
str = refpacknames;//FS_GetPackNames(buffer, sizeof(buffer), true);
Info_SetValueForKey(sysinfo, "sv_referencedPakNames", str, sizeof(sysinfo));
Con_Printf("Sysinfo: %s\n", sysinfo);
//Con_Printf("Sysinfo: %s\n", sysinfo);
str = "0";
Info_SetValueForKey(sysinfo, "sv_pure", str, sizeof(sysinfo));
@ -3223,7 +3223,9 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
if (net_message.cursize < 13)
return;
#ifdef HUFFNETWORK
Huff_DecryptPacket(&net_message, 12);
#endif
Cmd_TokenizeString((char*)net_message.data+4, false, false);
@ -3235,7 +3237,15 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
if (!cl)
cl = SVQ3_FindEmptyPlayerSlot();
if (!cl)
#ifdef HUFFNETWORK
if (!Huff_CompressionCRC(HUFFCRC_QUAKE3))
{
reason = "Could not set up compression.";
userinfo = NULL;
}
else
#endif
if (!cl)
{
reason = "Server is full.";
userinfo = NULL;
@ -3251,10 +3261,6 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
reason = "Invalid challenge";
else
{
#ifndef SERVERONLY
if (net_from.type == NA_LOOPBACK)
cls.challenge = challenge = 500;
#endif
Q_strncpyz(cl->userinfo, userinfo, sizeof(cl->userinfo));
reason = NET_AdrToString(adr, sizeof(adr), &net_from);
Info_SetValueForStarKey(cl->userinfo, "ip", reason, sizeof(cl->userinfo));
@ -3290,8 +3296,6 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
NET_SendPacket (NS_SERVER, 19, "\377\377\377\377connectResponse", &net_from);
Huff_PreferedCompressionCRC();
cl->frameunion.q3frames = BZ_Malloc(Q3UPDATE_BACKUP*sizeof(*cl->frameunion.q3frames));
}