393 lines
8 KiB
C
393 lines
8 KiB
C
|
/*
|
||
|
Copyright (C) 1996-1997 Id Software, Inc.
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
|
||
|
See the GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "quakedef.h"
|
||
|
|
||
|
|
||
|
// Generated from scrach by Tei
|
||
|
|
||
|
#define SFX_EXPLOFIRE 1
|
||
|
#define SFX_FIRE 2
|
||
|
#define SFX_SMOKE 3
|
||
|
#define SFX_EXPLOWAVE 4
|
||
|
#define SFX_ZRINGS 5
|
||
|
#define SFX_LIGHT 6
|
||
|
#define SFX_BLACKSNOKESRC 7
|
||
|
#define SFX_XPLOX 8
|
||
|
#define SFX_XPLOX2 9
|
||
|
#define SFX_SPARK 10
|
||
|
#define SFX_RAY 11
|
||
|
|
||
|
|
||
|
#define LF_FOREVER 1
|
||
|
#define LF_WILLDIE 2
|
||
|
#define LF_SCALE 3
|
||
|
#define LF_SCALEFAST 4
|
||
|
#define LF_ONLYONCE 5
|
||
|
#define LF_LOWDEATH 6
|
||
|
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int type; // entity number
|
||
|
int typelife;
|
||
|
float scale;
|
||
|
float dead;
|
||
|
vec3_t origin;
|
||
|
vec3_t endpos;
|
||
|
qboolean present;
|
||
|
int key;
|
||
|
} prj_t;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef SINGLEPLAYER //Tei much more prj for singleplayer
|
||
|
#define MAX_PRJ 1024
|
||
|
#else
|
||
|
#define MAX_PRJ 340 // Tei.. low becuase is underused
|
||
|
#endif
|
||
|
|
||
|
|
||
|
int cl_prj_num = 0;
|
||
|
prj_t cl_prj[MAX_PRJ];
|
||
|
|
||
|
/////////////
|
||
|
//
|
||
|
// FX
|
||
|
//
|
||
|
|
||
|
void R_FireExplo (vec3_t origin, float scale);
|
||
|
|
||
|
void R_FireExploBlack (vec3_t origin, float scale);
|
||
|
|
||
|
void R_FireFlama (vec3_t origin, float scale);
|
||
|
void R_ExploRing (vec3_t origin, float scale);
|
||
|
void R_ZRing (vec3_t origin, float scale);
|
||
|
void CL_AddLight( vec3_t pos, float scale );
|
||
|
|
||
|
|
||
|
///////////
|
||
|
//
|
||
|
// Parsing the PRJ
|
||
|
//
|
||
|
|
||
|
void CL_ParsePRJ ()
|
||
|
{
|
||
|
vec3_t start, end;
|
||
|
prj_t * ent;
|
||
|
int i;
|
||
|
int type;
|
||
|
int typelife;
|
||
|
float scale;
|
||
|
float dead;
|
||
|
int key;
|
||
|
int proto;
|
||
|
|
||
|
/* Reading the net cfg data */
|
||
|
|
||
|
proto = MSG_ReadByte ();
|
||
|
|
||
|
if (proto != 1 ) // Only support for proto=1
|
||
|
{
|
||
|
Sys_Error ("StaticFX proto unsuported version %d \n", proto);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
start[0] = MSG_ReadCoord (); // Origin
|
||
|
start[1] = MSG_ReadCoord ();
|
||
|
start[2] = MSG_ReadCoord ();
|
||
|
|
||
|
end[0] = MSG_ReadCoord (); // Origin2...
|
||
|
end[1] = MSG_ReadCoord ();
|
||
|
end[2] = MSG_ReadCoord ();
|
||
|
|
||
|
type = MSG_ReadByte (); // Fire, smoke, magic, rays.. etc..
|
||
|
typelife = MSG_ReadByte (); // Temporal, static, etc..
|
||
|
dead = MSG_ReadByte (); // cl.time + deadclock dead (if type need)
|
||
|
scale = MSG_ReadByte () * 0.01; //
|
||
|
key = MSG_ReadByte (); // Key for delete and change
|
||
|
|
||
|
|
||
|
/* Search for a free slot. */
|
||
|
i = 0;
|
||
|
while ( cl_prj[i].present && i<MAX_PRJ )
|
||
|
i++;
|
||
|
|
||
|
if ( cl_prj[i].present || i>=MAX_PRJ)
|
||
|
{
|
||
|
// TODO: write a subst code
|
||
|
Con_Printf ("OVERFLOW: PRJ flood\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Cfg the slot. */
|
||
|
ent = &cl_prj[i];
|
||
|
memset (ent, 0, sizeof(*ent));
|
||
|
|
||
|
ent->origin[0] = start[0];
|
||
|
ent->origin[1] = start[1];
|
||
|
ent->origin[2] = start[2];
|
||
|
|
||
|
ent->endpos[0] = end[0];
|
||
|
ent->endpos[1] = end[1];
|
||
|
ent->endpos[2] = end[2];
|
||
|
|
||
|
ent->scale = scale;
|
||
|
ent->typelife = typelife;
|
||
|
ent->type = type;
|
||
|
ent->key = key;
|
||
|
ent->dead = cl.time + dead;
|
||
|
|
||
|
//Con_Printf ("PRJ %f time, %f dead\n",cl.time, ent->dead);
|
||
|
|
||
|
ent->present = true;
|
||
|
|
||
|
|
||
|
//Con_Printf ("PRJ generated\n");
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void DefPRJ ( vec3_t start,vec3_t end, int type, int typelife, int dead, int scale, int key )
|
||
|
{
|
||
|
prj_t * ent;
|
||
|
int i;
|
||
|
//int type;
|
||
|
//int typelife;
|
||
|
//float scale;
|
||
|
//float dead;
|
||
|
//int key;
|
||
|
// int proto;
|
||
|
|
||
|
/* Reading the net cfg data */
|
||
|
|
||
|
/* Search for a free slot. */
|
||
|
i = 0;
|
||
|
while ( cl_prj[i].present && i<MAX_PRJ )
|
||
|
i++;
|
||
|
|
||
|
if ( cl_prj[i].present || i>=MAX_PRJ)
|
||
|
{
|
||
|
// TODO: write a subst code
|
||
|
Con_Printf ("OVERFLOW: PRJ flood\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Cfg the slot. */
|
||
|
ent = &cl_prj[i];
|
||
|
memset (ent, 0, sizeof(*ent));
|
||
|
|
||
|
ent->origin[0] = start[0];
|
||
|
ent->origin[1] = start[1];
|
||
|
ent->origin[2] = start[2];
|
||
|
|
||
|
ent->endpos[0] = end[0];
|
||
|
ent->endpos[1] = end[1];
|
||
|
ent->endpos[2] = end[2];
|
||
|
|
||
|
ent->scale = scale;
|
||
|
ent->typelife = typelife;
|
||
|
ent->type = type;
|
||
|
ent->key = key;
|
||
|
ent->dead = cl.time + dead;
|
||
|
|
||
|
//Con_Printf ("PRJ %f time, %f dead\n",cl.time, ent->dead);
|
||
|
|
||
|
ent->present = true;
|
||
|
|
||
|
|
||
|
//Con_Printf ("PRJ generated\n");
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
void CL_ClearPRJ()
|
||
|
{
|
||
|
memset (cl_prj, 0, sizeof(cl_prj));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//////////////
|
||
|
//
|
||
|
// Running the prj
|
||
|
//
|
||
|
|
||
|
extern cvar_t r_staticfx;
|
||
|
|
||
|
void R_DrawCorona(vec3_t pos, float radius , int visible );//Tei
|
||
|
void R_WRing (vec3_t origin, float scale);//Tei
|
||
|
void R_ParticleTeExplosion (vec3_t origin);
|
||
|
void R_RayFieldParticles (vec3_t org);
|
||
|
void R_ParticleImpSuperSpike (vec3_t origin);
|
||
|
void XR_BlobExplosion3 (vec3_t org);
|
||
|
void R_BeamZing (vec3_t origin, vec3_t end);
|
||
|
void R_SuperZing (vec3_t start, vec3_t end);
|
||
|
|
||
|
|
||
|
void CL_RunPRJ()
|
||
|
{
|
||
|
int i,k,t;
|
||
|
prj_t *prj;
|
||
|
float deltat, x;
|
||
|
vec3_t downmove;
|
||
|
|
||
|
/* Static FX on/off */
|
||
|
if (!r_staticfx.value)
|
||
|
return;
|
||
|
|
||
|
for (i=0 ; i< MAX_PRJ ; i++)
|
||
|
{
|
||
|
prj = &cl_prj[i];
|
||
|
|
||
|
if ( prj->present )
|
||
|
{
|
||
|
//Con_Printf ("PRJ:%d\n", prj->key);
|
||
|
|
||
|
/* Type work */
|
||
|
|
||
|
switch ( prj->type )
|
||
|
{
|
||
|
case SFX_EXPLOFIRE:
|
||
|
R_FireExplo (prj->origin, prj->scale);
|
||
|
|
||
|
break;
|
||
|
case SFX_FIRE:
|
||
|
R_FireFlama (prj->origin, prj->scale);
|
||
|
|
||
|
break;
|
||
|
case SFX_EXPLOWAVE:
|
||
|
R_ExploRing (prj->origin, prj->scale);
|
||
|
break;
|
||
|
case SFX_ZRINGS:
|
||
|
R_ZRing (prj->origin, prj->scale);
|
||
|
break;
|
||
|
case SFX_LIGHT:
|
||
|
//CL_AddLight( prj->origin, prj->scale );
|
||
|
//R_RailTrail (prj->origin, prj->endpos, prj->endpos);
|
||
|
break;
|
||
|
case SFX_BLACKSNOKESRC:
|
||
|
R_FireExploBlack (prj->origin, prj->scale);
|
||
|
break;
|
||
|
case SFX_XPLOX:
|
||
|
//R_FireExploBlack (prj->origin, prj->scale);
|
||
|
if (rand()&1)
|
||
|
R_ParticleTeExplosion (prj->origin);
|
||
|
break;
|
||
|
case SFX_XPLOX2:
|
||
|
//R_FireExploBlack (prj->origin, prj->scale);
|
||
|
if (lhrandom(1,110)>90)
|
||
|
// R_ParticleImpSuperSpike (prj->origin);
|
||
|
//else
|
||
|
R_RayFieldParticles(prj->origin);
|
||
|
|
||
|
if (lhrandom(1,1000)>990)
|
||
|
R_ParticleImpSuperSpike (prj->origin);
|
||
|
|
||
|
if (teirand(1000)>998)
|
||
|
XR_BlobExplosion3(prj->origin);//Tei QMB!
|
||
|
|
||
|
break;
|
||
|
|
||
|
case SFX_SPARK:
|
||
|
if (lhrandom(1,1000)>980)
|
||
|
R_SparkShower (prj->origin, vec3_origin );
|
||
|
|
||
|
|
||
|
break;
|
||
|
case SFX_RAY:
|
||
|
|
||
|
for (t=0; t<3;t++)
|
||
|
{
|
||
|
|
||
|
VectorCopy(prj->origin,downmove);
|
||
|
k = lhrandom(10,100 * prj->scale);
|
||
|
downmove[0] += lhrandom(-k,k);
|
||
|
downmove[1] += lhrandom(-k,k);
|
||
|
downmove[2] += lhrandom(-k,k);
|
||
|
R_BeamZing(prj->origin, downmove);
|
||
|
if(teirand(100)<2)
|
||
|
R_SuperZing(prj->origin, downmove);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Life work */
|
||
|
|
||
|
switch ( prj->typelife )
|
||
|
{
|
||
|
case LF_WILLDIE:
|
||
|
if (prj->dead < cl.time )
|
||
|
{
|
||
|
//Con_Printf ("PRJ:deleted!\n");
|
||
|
prj->present = false;
|
||
|
}
|
||
|
break;
|
||
|
case LF_LOWDEATH:
|
||
|
deltat = fabs(cl.time - prj->dead);
|
||
|
x = ( prj->scale ) / (deltat + 0.001f);
|
||
|
prj->scale -= x*0.1;
|
||
|
|
||
|
if (prj->scale < 0.1f)
|
||
|
{
|
||
|
prj->present = false;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case LF_SCALE:
|
||
|
deltat = fabs(cl.time - prj->dead);
|
||
|
x = ( prj->scale ) / (deltat + 0.001f);
|
||
|
prj->scale -= x;
|
||
|
|
||
|
if (prj->scale < 0.1f)
|
||
|
{
|
||
|
prj->present = false;
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case LF_SCALEFAST:
|
||
|
prj->scale -= 0.1f;
|
||
|
|
||
|
if (prj->scale < 0.1f)
|
||
|
{
|
||
|
prj->present = false;
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case LF_ONLYONCE:
|
||
|
prj->present = false;
|
||
|
break;
|
||
|
|
||
|
case LF_FOREVER:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Continue */
|
||
|
}
|
||
|
}
|
||
|
}
|