DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
cl_particles.c File Reference
#include "quakedef.h"
#include "cl_collision.h"
#include "image.h"
#include "r_shadow.h"
+ Include dependency graph for cl_particles.c:

Go to the source code of this file.

Data Structures

struct  particleeffectinfo_t
 
struct  particletexture_t
 

Macros

#define checkparms(n)
 
#define PARTICLEEFFECT_DEFINED   2147483648U
 
#define PARTICLEEFFECT_FORCENEAREST   4
 
#define PARTICLEEFFECT_NOTUNDERWATER   2
 
#define PARTICLEEFFECT_UNDERWATER   1
 
#define PARTICLEFONTSIZE   (PARTICLETEXTURESIZE*8)
 
#define PARTICLETEXTURESIZE   64
 
#define readbool(var)
 
#define readfloat(var)
 
#define readfloats(array, n)
 
#define readint(var)
 
#define readints(array, n)
 

Functions

void CL_EntityParticles (const entity_t *ent)
 
static void CL_ImmediateBloodStain (particle_t *part)
 
particle_tCL_NewParticle (const vec3_t sortorigin, unsigned short ptypeindex, int pcolor1, int pcolor2, int ptex, float psize, float psizeincrease, float palpha, float palphafade, float pgravity, float pbounce, float px, float py, float pz, float pvx, float pvy, float pvz, float pairfriction, float pliquidfriction, float originjitter, float velocityjitter, qbool pqualityreduction, float lifetime, float stretch, pblend_t blendmode, porientation_t orientation, int staincolor1, int staincolor2, int staintex, float stainalpha, float stainsize, float angle, float spin, float tint[4])
 Creates a new particle and returns a pointer to it.
 
static void CL_NewParticlesFromEffectinfo (int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, float tintmins[4], float tintmaxs[4], float fade, qbool wanttrail)
 
particle_tCL_NewQuakeParticle (const vec3_t origin, const unsigned short ptypeindex, const int color_1, const int color_2, const float gravity, const float offset_x, const float offset_y, const float offset_z, const float velocity_offset_x, const float velocity_offset_y, const float velocity_offset_z, const float air_friction, const float liquid_friction, const float origin_jitter, const float velocity_jitter, const float lifetime)
 Creates a simple particle, a square like Quake, or a disc like GLQuake.
 
void CL_ParseParticleEffect (void)
 
static void CL_Particle_PixelCoordsForTexnum (int texnum, int *basex, int *basey, int *width, int *height)
 
void CL_ParticleBox (int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, float tintmins[4], float tintmaxs[4], float fade)
 
void CL_ParticleCube (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, vec_t gravity, vec_t randomvel)
 
void CL_ParticleEffect (int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor)
 
static void CL_ParticleEffect_Fallback (int effectnameindex, float count, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, qbool wanttrail)
 
int CL_ParticleEffectIndexForName (const char *name)
 
const char * CL_ParticleEffectNameForIndex (int i)
 
void CL_ParticleExplosion (const vec3_t org)
 
void CL_ParticleExplosion2 (const vec3_t org, int colorStart, int colorLength)
 
void CL_ParticleRain (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, int type)
 
void CL_Particles_Init (void)
 
static void CL_Particles_LoadEffectInfo (const char *customfile)
 
static void CL_Particles_LoadEffectInfo_f (cmd_state_t *cmd)
 
static void CL_Particles_ParseEffectInfo (const char *textstart, const char *textend, const char *filename)
 
void CL_Particles_Shutdown (void)
 
void CL_ParticleTrail (int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, float tintmins[4], float tintmaxs[4], float fade)
 
void CL_ReadPointFile_f (cmd_state_t *cmd)
 
static void CL_Smoke (const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float smokecount)
 
static void CL_Sparks (const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float sparkcount)
 
void CL_SpawnDecalParticleForPoint (const vec3_t org, float maxdist, float size, float alpha, int texnum, int color1, int color2)
 
void CL_SpawnDecalParticleForSurface (int hitent, const vec3_t org, const vec3_t normal, int color1, int color2, int texnum, float size, float alpha)
 
static char * LightCubemapNumToName (char *vabuf, size_t vasize, int lightcubemapnum, int flags)
 
static void particletextureblotch (unsigned char *data, float radius, float red, float green, float blue, float alpha)
 
static void particletextureinvert (unsigned char *data)
 
static void R_DrawParticle_TransparentCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 
void R_DrawParticles (void)
 
static void R_InitBloodTextures (unsigned char *particletexturedata)
 
static void R_InitParticleTexture (void)
 
static void r_part_newmap (void)
 
static void r_part_shutdown (void)
 
static void r_part_start (void)
 
void R_Particles_Init (void)
 
static void setuptex (int texnum, unsigned char *data, unsigned char *particletexturedata)
 
static unsigned char shadebubble (float dx, float dy, vec3_t light)
 

Variables

particleeffectinfo_t baselineparticleeffectinfo
 
cvar_t cl_decals = {CF_CLIENT | CF_ARCHIVE, "cl_decals", "1", "enables decals (bullet holes, blood, etc)"}
 
cvar_t cl_decals_bias = {CF_CLIENT | CF_ARCHIVE, "cl_decals_bias", "0.125", "distance to bias decals from surface to prevent depth fighting"}
 
cvar_t cl_decals_fadetime = {CF_CLIENT | CF_ARCHIVE, "cl_decals_fadetime", "1", "how long decals take to fade away"}
 
cvar_t cl_decals_max = {CF_CLIENT | CF_ARCHIVE, "cl_decals_max", "4096", "maximum number of decals allowed to exist in the world at once"}
 
cvar_t cl_decals_models = {CF_CLIENT | CF_ARCHIVE, "cl_decals_models", "0", "enables decals on animated models"}
 
cvar_t cl_decals_newsystem_bloodsmears = {CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_bloodsmears", "1", "enable use of particle velocity as decal projection direction rather than surface normal"}
 
cvar_t cl_decals_newsystem_immediatebloodstain = {CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_immediatebloodstain", "2", "0: no on-spawn blood stains; 1: on-spawn blood stains for pt_blood; 2: always use on-spawn blood stains"}
 
cvar_t cl_decals_newsystem_intensitymultiplier = {CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_intensitymultiplier", "2", "boosts intensity of decals (because the distance fade can make them hard to see otherwise)"}
 
cvar_t cl_decals_time = {CF_CLIENT | CF_ARCHIVE, "cl_decals_time", "20", "how long before decals start to fade away"}
 
cvar_t cl_particles = {CF_CLIENT | CF_ARCHIVE, "cl_particles", "1", "enables particle effects"}
 
cvar_t cl_particles_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_alpha", "1", "multiplies opacity of particles"}
 
cvar_t cl_particles_blood = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood", "1", "enables blood effects"}
 
cvar_t cl_particles_blood_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_alpha", "1", "opacity of blood, does not affect decals"}
 
cvar_t cl_particles_blood_bloodhack = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_bloodhack", "1", "make certain quake particle() calls create blood effects instead"}
 
cvar_t cl_particles_blood_decal_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_alpha", "1", "opacity of blood decal"}
 
cvar_t cl_particles_blood_decal_scalemax = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_scalemax", "2", "maximal random scale of decal"}
 
cvar_t cl_particles_blood_decal_scalemin = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_scalemin", "1.5", "minimal random scale of decal"}
 
cvar_t cl_particles_bubbles = {CF_CLIENT | CF_ARCHIVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"}
 
cvar_t cl_particles_bulletimpacts = {CF_CLIENT | CF_ARCHIVE, "cl_particles_bulletimpacts", "1", "enables bulletimpact effects"}
 
cvar_t cl_particles_collisions = {CF_CLIENT | CF_ARCHIVE, "cl_particles_collisions", "1", "allow costly collision detection on particles (sparks that bounce, particles not going through walls, blood hitting surfaces, etc)"}
 
cvar_t cl_particles_explosions_shell = {CF_CLIENT | CF_ARCHIVE, "cl_particles_explosions_shell", "0", "enables polygonal shell from explosions"}
 
cvar_t cl_particles_explosions_sparks = {CF_CLIENT | CF_ARCHIVE, "cl_particles_explosions_sparks", "1", "enables sparks from explosions"}
 
cvar_t cl_particles_forcetraileffects = {CF_CLIENT, "cl_particles_forcetraileffects", "0", "force trails to be displayed even if a non-trail draw primitive was used (debug/compat feature)"}
 
cvar_t cl_particles_quake = {CF_CLIENT | CF_ARCHIVE, "cl_particles_quake", "0", "0: Fancy particles; 1: Disc particles like GLQuake; 2: Square particles like software-rendered Quake"}
 
cvar_t cl_particles_quality = {CF_CLIENT | CF_ARCHIVE, "cl_particles_quality", "1", "multiplies number of particles"}
 
cvar_t cl_particles_rain = {CF_CLIENT | CF_ARCHIVE, "cl_particles_rain", "1", "enables rain effects"}
 
cvar_t cl_particles_size = {CF_CLIENT | CF_ARCHIVE, "cl_particles_size", "1", "multiplies particle size"}
 
cvar_t cl_particles_smoke = {CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke", "1", "enables smoke (used by multiple effects)"}
 
cvar_t cl_particles_smoke_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke_alpha", "0.5", "smoke brightness"}
 
cvar_t cl_particles_smoke_alphafade = {CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke_alphafade", "0.55", "brightness fade per second"}
 
cvar_t cl_particles_snow = {CF_CLIENT | CF_ARCHIVE, "cl_particles_snow", "1", "enables snow effects"}
 
cvar_t cl_particles_sparks = {CF_CLIENT | CF_ARCHIVE, "cl_particles_sparks", "1", "enables sparks (used by multiple effects)"}
 
cvar_t cl_particles_visculling = {CF_CLIENT | CF_ARCHIVE, "cl_particles_visculling", "0", "perform a costly check if each particle is visible before drawing"}
 
skinframe_tdecalskinframe
 
int numparticleeffectinfo
 
float particle_color4f [MESHQUEUE_TRANSPARENT_BATCHSIZE *16]
 
unsigned short particle_elements [MESHQUEUE_TRANSPARENT_BATCHSIZE *6]
 
float particle_texcoord2f [MESHQUEUE_TRANSPARENT_BATCHSIZE *8]
 
float particle_vertex3f [MESHQUEUE_TRANSPARENT_BATCHSIZE *12]
 
particleeffectinfo_t particleeffectinfo [MAX_PARTICLEEFFECTINFO]
 
char particleeffectname [MAX_PARTICLEEFFECTNAME][64]
 
int particlefontcellheight
 
int particlefontcellwidth
 
int particlefontcols
 
int particlefontheight
 
int particlefontrows
 
static rtexture_tparticlefonttexture
 
int particlefontwidth
 
static int particlepalette [256]
 
static particletexture_t particletexture [MAX_PARTICLETEXTURES]
 
static rtexturepool_tparticletexturepool
 
particletype_t particletype [pt_total]
 
cvar_t r_drawdecals = {CF_CLIENT, "r_drawdecals", "1", "enables drawing of decals"}
 
static cvar_t r_drawdecals_drawdistance = {CF_CLIENT | CF_ARCHIVE, "r_drawdecals_drawdistance", "500", "decals further than drawdistance*size will not be drawn"}
 
cvar_t r_drawparticles = {CF_CLIENT, "r_drawparticles", "1", "enables drawing of particles"}
 
static cvar_t r_drawparticles_drawdistance = {CF_CLIENT | CF_ARCHIVE, "r_drawparticles_drawdistance", "2000", "particles further than drawdistance*size will not be drawn"}
 
static cvar_t r_drawparticles_nearclip_max = {CF_CLIENT | CF_ARCHIVE, "r_drawparticles_nearclip_max", "4", "particles closer than drawnearclip_min will be faded"}
 
static cvar_t r_drawparticles_nearclip_min = {CF_CLIENT | CF_ARCHIVE, "r_drawparticles_nearclip_min", "4", "particles closer than drawnearclip_min will not be drawn"}
 
int ramp1 [8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}
 
int ramp2 [8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}
 
int ramp3 [8] = {0x6d, 0x6b, 6, 5, 4, 3}
 
static const char * standardeffectnames [EFFECT_TOTAL]
 
static const int tex_beam = 60
 
static const int tex_blooddecal [8] = {16, 17, 18, 19, 20, 21, 22, 23}
 
static const int tex_bloodparticle [8] = {24, 25, 26, 27, 28, 29, 30, 31}
 
static const int tex_bubble = 62
 
static const int tex_bulletdecal [8] = {8, 9, 10, 11, 12, 13, 14, 15}
 
static const int tex_particle = 63
 
static const int tex_raindrop = 61
 
static const int tex_rainsplash = 32
 
static const int tex_smoke [8] = {0, 1, 2, 3, 4, 5, 6, 7}
 
static const int tex_square = 33
 

Macro Definition Documentation

◆ checkparms

#define checkparms ( n)
Value:
if (argc != (n)) {Con_Printf("%s:%i: error while parsing: %s given %i parameters, should be %i parameters\n", filename, linenumber, argv[0], argc, (n));break;}
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define n(x, y)
string argv(float n)

Referenced by CL_Particles_ParseEffectInfo().

◆ PARTICLEEFFECT_DEFINED

#define PARTICLEEFFECT_DEFINED   2147483648U

Definition at line 48 of file cl_particles.c.

Referenced by CL_NewParticlesFromEffectinfo(), and CL_Particles_ParseEffectInfo().

◆ PARTICLEEFFECT_FORCENEAREST

#define PARTICLEEFFECT_FORCENEAREST   4

Definition at line 47 of file cl_particles.c.

Referenced by CL_Particles_ParseEffectInfo(), and LightCubemapNumToName().

◆ PARTICLEEFFECT_NOTUNDERWATER

#define PARTICLEEFFECT_NOTUNDERWATER   2

Definition at line 46 of file cl_particles.c.

Referenced by CL_NewParticlesFromEffectinfo(), and CL_Particles_ParseEffectInfo().

◆ PARTICLEEFFECT_UNDERWATER

#define PARTICLEEFFECT_UNDERWATER   1

Definition at line 45 of file cl_particles.c.

Referenced by CL_NewParticlesFromEffectinfo(), and CL_Particles_ParseEffectInfo().

◆ PARTICLEFONTSIZE

#define PARTICLEFONTSIZE   (PARTICLETEXTURESIZE*8)

Definition at line 2153 of file cl_particles.c.

Referenced by R_InitParticleTexture(), and setuptex().

◆ PARTICLETEXTURESIZE

#define PARTICLETEXTURESIZE   64

◆ readbool

#define readbool ( var)
Value:
checkparms(2);var = strtol(argv[1], NULL, 0) != 0
#define checkparms(n)
#define NULL
Definition qtypes.h:12

Referenced by CL_Particles_ParseEffectInfo().

◆ readfloat

#define readfloat ( var)
Value:
checkparms(2);var = atof(argv[1])

Referenced by CL_Particles_ParseEffectInfo().

◆ readfloats

#define readfloats ( array,
n )
Value:
checkparms(n+1);for (arrayindex = 0;arrayindex < argc - 1;arrayindex++) array[arrayindex] = atof(argv[1+arrayindex])

Referenced by CL_Particles_ParseEffectInfo().

◆ readint

#define readint ( var)
Value:
checkparms(2);var = strtol(argv[1], NULL, 0)

Referenced by CL_Particles_ParseEffectInfo().

◆ readints

#define readints ( array,
n )
Value:
checkparms(n+1);for (arrayindex = 0;arrayindex < argc - 1;arrayindex++) array[arrayindex] = strtol(argv[1+arrayindex], NULL, 0)

Referenced by CL_Particles_ParseEffectInfo().

Function Documentation

◆ CL_EntityParticles()

void CL_EntityParticles ( const entity_t * ent)

Definition at line 1811 of file cl_particles.c.

1812{
1813 int i, j;
1814 vec_t pitch, yaw, dist = 64, beamlength = 16;
1815 vec3_t org, v;
1816 static vec3_t avelocities[NUMVERTEXNORMALS];
1817 if (!cl_particles.integer) return;
1818 if (cl.time <= cl.oldtime) return; // don't spawn new entity particles while paused
1819
1821
1822 if (!avelocities[0][0])
1823 for (i = 0;i < NUMVERTEXNORMALS;i++)
1824 for (j = 0;j < 3;j++)
1825 avelocities[i][j] = lhrandom(0, 2.55);
1826
1827 for (i = 0;i < NUMVERTEXNORMALS;i++)
1828 {
1829 yaw = cl.time * avelocities[i][0];
1830 pitch = cl.time * avelocities[i][1];
1831 v[0] = org[0] + m_bytenormals[i][0] * dist + (cos(pitch)*cos(yaw)) * beamlength;
1832 v[1] = org[1] + m_bytenormals[i][1] * dist + (cos(pitch)*sin(yaw)) * beamlength;
1833 v[2] = org[2] + m_bytenormals[i][2] * dist + (-sin(pitch)) * beamlength;
1834 CL_NewParticle(org, pt_entityparticle, particlepalette[0x6f], particlepalette[0x6f], tex_particle, 1, 0, 255, 0, 0, 0, v[0], v[1], v[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1835 }
1836}
client_state_t cl
Definition cl_main.c:117
static int particlepalette[256]
particle_t * CL_NewParticle(const vec3_t sortorigin, unsigned short ptypeindex, int pcolor1, int pcolor2, int ptex, float psize, float psizeincrease, float palpha, float palphafade, float pgravity, float pbounce, float px, float py, float pz, float pvx, float pvy, float pvz, float pairfriction, float pliquidfriction, float originjitter, float velocityjitter, qbool pqualityreduction, float lifetime, float stretch, pblend_t blendmode, porientation_t orientation, int staincolor1, int staincolor2, int staintex, float stainalpha, float stainsize, float angle, float spin, float tint[4])
Creates a new particle and returns a pointer to it.
cvar_t cl_particles
static const int tex_particle
@ PBLEND_ALPHA
@ pt_entityparticle
@ PARTICLE_BILLBOARD
const GLdouble * v
Definition glquake.h:762
float m_bytenormals[NUMVERTEXNORMALS][3]
Definition mathlib.c:31
#define lhrandom(MIN, MAX)
LadyHavoc: this function never returns exactly MIN or exactly MAX, because of a QuakeC bug in id1 whe...
Definition mathlib.h:48
#define NUMVERTEXNORMALS
Definition mathlib.h:225
void Matrix4x4_OriginFromMatrix(const matrix4x4_t *in, float *out)
Definition matrixlib.c:1792
float cos(float f)
float sin(float f)
int i
float vec_t
Definition qtypes.h:68
vec_t vec3_t[3]
Definition qtypes.h:71
double oldtime
Definition client.h:868
double time
Definition client.h:868
int integer
Definition cvar.h:73
matrix4x4_t matrix
Definition client.h:332
entity_render_t render
Definition client.h:477

References cl, CL_NewParticle(), cl_particles, cos(), i, cvar_t::integer, lhrandom, m_bytenormals, entity_render_t::matrix, Matrix4x4_OriginFromMatrix(), NULL, NUMVERTEXNORMALS, client_state_t::oldtime, PARTICLE_BILLBOARD, particlepalette, PBLEND_ALPHA, pt_entityparticle, entity_t::render, sin(), tex_particle, client_state_t::time, and v.

Referenced by CL_UpdateNetworkEntityTrail().

◆ CL_ImmediateBloodStain()

static void CL_ImmediateBloodStain ( particle_t * part)
static

Definition at line 935 of file cl_particles.c.

936{
937 vec3_t v;
938 int staintex;
939
940 // blood creates a splash at spawn, not just at impact, this makes monsters bloody where they are shot
941 if (part->staintexnum >= 0 && cl_decals.integer)
942 {
943 VectorCopy(part->vel, v);
945 staintex = part->staintexnum;
946 R_DecalSystem_SplatEntities(part->org, v, 1-part->staincolor[0]*(1.0f/255.0f), 1-part->staincolor[1]*(1.0f/255.0f), 1-part->staincolor[2]*(1.0f/255.0f), part->stainalpha*(1.0f/255.0f), particletexture[staintex].s1, particletexture[staintex].t1, particletexture[staintex].s2, particletexture[staintex].t2, part->stainsize);
947 }
948
949 // blood creates a splash at spawn, not just at impact, this makes monsters bloody where they are shot
950 if (part->typeindex == pt_blood && cl_decals.integer)
951 {
952 VectorCopy(part->vel, v);
954 staintex = tex_blooddecal[rand()&7];
955 R_DecalSystem_SplatEntities(part->org, v, part->color[0]*(1.0f/255.0f), part->color[1]*(1.0f/255.0f), part->color[2]*(1.0f/255.0f), part->alpha*(1.0f/255.0f), particletexture[staintex].s1, particletexture[staintex].t1, particletexture[staintex].s2, particletexture[staintex].t2, part->size * 2);
956 }
957}
cvar_t cl_decals
static const int tex_blooddecal[8]
static particletexture_t particletexture[MAX_PARTICLETEXTURES]
@ pt_blood
void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize)
Definition gl_rmain.c:9506
#define VectorNormalize(v)
Definition mathlib.h:104
#define VectorCopy(in, out)
Definition mathlib.h:101
unsigned char staincolor[3]
unsigned char typeindex
float stainsize
vec3_t vel
velocity of particle, or orientation of decal, or end point of beam
float alpha
0-255
signed char staintexnum
unsigned char color[3]
float stainalpha

References particle_t::alpha, cl_decals, particle_t::color, cvar_t::integer, particle_t::org, particletexture, pt_blood, R_DecalSystem_SplatEntities(), particletexture_t::s1, particletexture_t::s2, particle_t::size, particle_t::stainalpha, particle_t::staincolor, particle_t::stainsize, particle_t::staintexnum, particletexture_t::t1, particletexture_t::t2, tex_blooddecal, particle_t::typeindex, v, VectorCopy, VectorNormalize, and particle_t::vel.

Referenced by CL_NewParticlesFromEffectinfo(), and CL_ParticleEffect_Fallback().

◆ CL_NewParticle()

particle_t * CL_NewParticle ( const vec3_t sortorigin,
unsigned short ptypeindex,
int pcolor1,
int pcolor2,
int ptex,
float psize,
float psizeincrease,
float palpha,
float palphafade,
float pgravity,
float pbounce,
float px,
float py,
float pz,
float pvx,
float pvy,
float pvz,
float pairfriction,
float pliquidfriction,
float originjitter,
float velocityjitter,
qbool pqualityreduction,
float lifetime,
float stretch,
pblend_t blendmode,
porientation_t orientation,
int staincolor1,
int staincolor2,
int staintex,
float stainalpha,
float stainsize,
float angle,
float spin,
float tint[4] )

Creates a new particle and returns a pointer to it.

Parameters
[in]sortorigin?
[in]ptypeindexAny of the pt_ enum values (pt_static, pt_blood, etc), see ptype_t near the top of this file
[in]pcolor1,pcolor2Minimum and maximum range of color, randomly interpolated with pcolor2 to decide particle color
[in]ptexAny of the tex_ values such as tex_smoke[rand()&7] or tex_particle
[in]psizeSize of particle (or thickness for PARTICLE_SPARK and PARTICLE_*BEAM)
[in]psizeincrease?
[in]palphaOpacity of particle as 0-255 (can be more than 255)
[in]palphafadeRate of fade per second (so 256 would mean a 256 alpha particle would fade to nothing in 1 second)
[in]pgravityHow much effect gravity has on the particle (0-1)
[in]pbounceHow much bounce the particle has when it hits a surface (0-1), -1 makes a blood splat when it hits a surface, 0 does not even check for collisions
[in]px,py,pzStarting origin of particle
[in]pvx,pvy,pvzStarting velocity of particle
[in]pairfrictionHow much the particle slows down, in air, per second (0-1 typically, can slowdown faster than 1)
[in]pliquidfrictionHow much the particle slows down, in liquids, per second (0-1 typically, can slowdown faster than 1)
[in]originjitter?
[in]velocityjitter?
[in]pqualityreduction?
[in]lifetimeHow long the particle can live (note it is also removed if alpha drops to nothing)
[in]stretch?
[in]blendmodeOne of the PBLEND_ values
[in]orientationOne of the PARTICLE_ values
[in]staincolor1Minimum and maximum ranges of stain color, randomly interpolated to decide stain color (-1 to use none)
[in]staincolor2Minimum and maximum ranges of stain color, randomly interpolated to decide stain color (-1 to use none)
[in]staintexAny of the tex_ values such as tex_smoke[rand()&7] or tex_particle
[in]angleBase rotation of the particle geometry around its center normal
[in]spinRotation speed of the particle geometry around its center normal
[in]tintThe tint
Returns
Pointer to the new particle

Definition at line 668 of file cl_particles.c.

698{
699 int l1, l2, r, g, b;
700 particle_t *part;
701 vec3_t v;
703 return NULL;
706 return NULL;
707 if (!lifetime)
708 lifetime = palpha / min(1, palphafade);
709 part = &cl.particles[cl.free_particle++];
712 memset(part, 0, sizeof(*part));
713 VectorCopy(sortorigin, part->sortorigin);
714 part->typeindex = ptypeindex;
715 part->blendmode = blendmode;
716 if(orientation == PARTICLE_HBEAM || orientation == PARTICLE_VBEAM)
717 {
719 if(tex->t1 == 0 && tex->t2 == 1) // full height of texture?
721 else
723 }
724 else
725 part->orientation = orientation;
726 l2 = (int)lhrandom(0.5, 256.5);
727 l1 = 256 - l2;
728 part->color[0] = ((((pcolor1 >> 16) & 0xFF) * l1 + ((pcolor2 >> 16) & 0xFF) * l2) >> 8) & 0xFF;
729 part->color[1] = ((((pcolor1 >> 8) & 0xFF) * l1 + ((pcolor2 >> 8) & 0xFF) * l2) >> 8) & 0xFF;
730 part->color[2] = ((((pcolor1 >> 0) & 0xFF) * l1 + ((pcolor2 >> 0) & 0xFF) * l2) >> 8) & 0xFF;
731 if (vid.sRGB3D)
732 {
733 part->color[0] = (unsigned char)floor(Image_LinearFloatFromsRGB(part->color[0]) * 255.0f + 0.5f);
734 part->color[1] = (unsigned char)floor(Image_LinearFloatFromsRGB(part->color[1]) * 255.0f + 0.5f);
735 part->color[2] = (unsigned char)floor(Image_LinearFloatFromsRGB(part->color[2]) * 255.0f + 0.5f);
736 }
737 part->alpha = palpha;
738 part->alphafade = palphafade;
739 part->staintexnum = staintex;
740 if(staincolor1 >= 0 && staincolor2 >= 0)
741 {
742 l2 = (int)lhrandom(0.5, 256.5);
743 l1 = 256 - l2;
744 if(blendmode == PBLEND_INVMOD)
745 {
746 r = ((((staincolor1 >> 16) & 0xFF) * l1 + ((staincolor2 >> 16) & 0xFF) * l2) * (255 - part->color[0])) / 0x8000; // staincolor 0x808080 keeps color invariant
747 g = ((((staincolor1 >> 8) & 0xFF) * l1 + ((staincolor2 >> 8) & 0xFF) * l2) * (255 - part->color[1])) / 0x8000;
748 b = ((((staincolor1 >> 0) & 0xFF) * l1 + ((staincolor2 >> 0) & 0xFF) * l2) * (255 - part->color[2])) / 0x8000;
749 }
750 else
751 {
752 r = ((((staincolor1 >> 16) & 0xFF) * l1 + ((staincolor2 >> 16) & 0xFF) * l2) * part->color[0]) / 0x8000; // staincolor 0x808080 keeps color invariant
753 g = ((((staincolor1 >> 8) & 0xFF) * l1 + ((staincolor2 >> 8) & 0xFF) * l2) * part->color[1]) / 0x8000;
754 b = ((((staincolor1 >> 0) & 0xFF) * l1 + ((staincolor2 >> 0) & 0xFF) * l2) * part->color[2]) / 0x8000;
755 }
756 if(r > 0xFF) r = 0xFF;
757 if(g > 0xFF) g = 0xFF;
758 if(b > 0xFF) b = 0xFF;
759 }
760 else
761 {
762 r = part->color[0]; // -1 is shorthand for stain = particle color
763 g = part->color[1];
764 b = part->color[2];
765 }
766 part->staincolor[0] = r;
767 part->staincolor[1] = g;
768 part->staincolor[2] = b;
769 part->stainalpha = palpha * stainalpha;
770 part->stainsize = psize * stainsize;
771 if(tint)
772 {
773 if(blendmode != PBLEND_INVMOD) // invmod is immune to tinting
774 {
775 part->color[0] *= tint[0];
776 part->color[1] *= tint[1];
777 part->color[2] *= tint[2];
778 }
779 part->alpha *= tint[3];
780 part->alphafade *= tint[3];
781 part->stainalpha *= tint[3];
782 }
783 part->texnum = ptex;
784 part->size = psize;
785 part->sizeincrease = psizeincrease;
786 part->gravity = pgravity;
787 part->bounce = pbounce;
788 part->stretch = stretch;
790 part->org[0] = px + originjitter * v[0];
791 part->org[1] = py + originjitter * v[1];
792 part->org[2] = pz + originjitter * v[2];
793 part->vel[0] = pvx + velocityjitter * v[0];
794 part->vel[1] = pvy + velocityjitter * v[1];
795 part->vel[2] = pvz + velocityjitter * v[2];
796 part->airfriction = pairfriction;
797 part->liquidfriction = pliquidfriction;
798 part->die = cl.time + lifetime;
799 part->delayedspawn = cl.time;
800// part->delayedcollisions = 0;
801 part->qualityreduction = pqualityreduction;
802 part->angle = angle;
803 part->spin = spin;
804 // if it is rain or snow, trace ahead and shut off collisions until an actual collision event needs to occur to improve performance
805 if (part->typeindex == pt_rain)
806 {
807 int i;
808 particle_t *part2;
809 vec3_t endvec;
810 trace_t trace;
811 // turn raindrop into simple spark and create delayedspawn splash effect
812 part->typeindex = pt_spark;
813 part->bounce = 0;
814 VectorMA(part->org, lifetime, part->vel, endvec);
815 trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK, 0, 0, collision_extendmovelength.value, true, false, NULL, false, false);
816 part->die = cl.time + lifetime * trace.fraction;
817 part2 = CL_NewParticle(endvec, pt_raindecal, pcolor1, pcolor2, tex_rainsplash, part->size, part->size * 20, part->alpha, part->alpha / 0.4, 0, 0, trace.endpos[0] + trace.plane.normal[0], trace.endpos[1] + trace.plane.normal[1], trace.endpos[2] + trace.plane.normal[2], trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2], 0, 0, 0, 0, pqualityreduction, 0, 1, PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED, -1, -1, -1, 1, 1, 0, 0, NULL);
818 if (part2)
819 {
820 part2->delayedspawn = part->die;
821 part2->die += part->die - cl.time;
822 for (i = rand() & 7;i < 10;i++)
823 {
824 part2 = CL_NewParticle(endvec, pt_spark, pcolor1, pcolor2, tex_particle, 0.25f, 0, part->alpha * 2, part->alpha * 4, 1, 0.1, trace.endpos[0] + trace.plane.normal[0], trace.endpos[1] + trace.plane.normal[1], trace.endpos[2] + trace.plane.normal[2], trace.plane.normal[0] * 16, trace.plane.normal[1] * 16, trace.plane.normal[2] * 16 + cl.movevars_gravity * 0.04, 0, 0, 0, 32, pqualityreduction, 0, 1, PBLEND_ADD, PARTICLE_SPARK, -1, -1, -1, 1, 1, 0, 0, NULL);
825 if (part2)
826 {
827 part2->delayedspawn = part->die;
828 part2->die += part->die - cl.time;
829 }
830 }
831 }
832 }
833 else if (part->typeindex == pt_explode || part->typeindex == pt_explode2)
834 part->time2 = rand()&3; // time2 is used to progress the colour ramp index
835
836#if 0
837 else if (part->bounce != 0 && part->gravity == 0 && part->typeindex != pt_snow)
838 {
839 float lifetime = part->alpha / (part->alphafade ? part->alphafade : 1);
840 vec3_t endvec;
841 trace_t trace;
842 VectorMA(part->org, lifetime, part->vel, endvec);
843 trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, true, false, NULL, false);
844 part->delayedcollisions = cl.time + lifetime * trace.fraction - 0.1;
845 }
846#endif
847
848 return part;
849}
#define SUPERCONTENTS_BODY
Definition bspfile.h:201
#define SUPERCONTENTS_SOLID
Definition bspfile.h:196
#define SUPERCONTENTS_LIQUIDSMASK
Definition bspfile.h:218
trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities, qbool hitsurfaces)
static const int tex_rainsplash
@ PBLEND_ADD
@ PBLEND_INVMOD
@ pt_snow
@ pt_spark
@ pt_explode2
@ pt_raindecal
@ pt_rain
@ pt_explode
@ PARTICLE_SPARK
@ PARTICLE_HBEAM
@ PARTICLE_VBEAM
@ PARTICLE_ORIENTED_DOUBLESIDED
cvar_t collision_extendmovelength
Definition collision.c:14
static int(ZEXPORT *qz_inflate)(z_stream *strm
#define Image_LinearFloatFromsRGB(c)
Definition image.h:69
#define VectorRandom(v)
Definition mathlib.h:119
#define min(A, B)
Definition mathlib.h:37
#define VectorMA(a, scale, b, out)
Definition mathlib.h:114
float floor(float f)
dp_FragColor r
dp_FragColor g
dp_FragColor b
vec2 px
particle_t * particles
Definition client.h:1000
float movevars_gravity
Definition client.h:1059
int free_particle
Definition client.h:1015
int num_particles
Definition client.h:1009
int max_particles
Definition client.h:988
float value
Definition cvar.h:74
float alphafade
how much alpha reduces per second
unsigned char texnum
float stretch
only for sparks
float die
time when this particle should be removed, regardless of alpha
float bounce
how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide,...
float airfriction
how much air friction affects this object (objects with a low mass/size ratio tend to get more air fr...
unsigned char orientation
float gravity
how much gravity affects this particle (1.0 = normal gravity, 0.0 = none)
vec3_t sortorigin
sort by this group origin, not particle org
unsigned char qualityreduction
enables skipping of this particle according to r_refdef.view.qualityreduction
float sizeincrease
rate of size change per second
float liquidfriction
how much liquid friction affects this object (objects with a low mass/size ratio tend to get more liq...
unsigned char blendmode
float delayedspawn
time that particle appears and begins moving
float time2
used for snow fluttering, decal fade, explosion colour ramp
short spin
geometry rotation speed around the particle center normal
short angle
base rotation of particle
double fraction
Definition collision.h:40
double endpos[3]
Definition collision.h:42
plane_t plane
Definition collision.h:44
qbool sRGB3D
whether 3D rendering is sRGB corrected (based on sRGBcapable3D)
Definition vid.h:76
vec3_t normal
Definition collision.h:13
viddef_t vid
global video state
Definition vid_shared.c:64
#define MOVE_NOMONSTERS
Definition world.h:29

References particle_t::airfriction, particle_t::alpha, particle_t::alphafade, particle_t::angle, b, particle_t::blendmode, particle_t::bounce, cl, CL_NewParticle(), cl_particles, CL_TraceLine(), collision_extendmovelength, particle_t::color, particle_t::delayedspawn, particle_t::die, trace_t::endpos, floor(), trace_t::fraction, client_state_t::free_particle, g, particle_t::gravity, i, Image_LinearFloatFromsRGB, int(), cvar_t::integer, lhrandom, particle_t::liquidfriction, client_state_t::max_particles, min, MOVE_NOMONSTERS, client_state_t::movevars_gravity, plane_t::normal, NULL, client_state_t::num_particles, particle_t::org, particle_t::orientation, PARTICLE_HBEAM, PARTICLE_ORIENTED_DOUBLESIDED, PARTICLE_SPARK, PARTICLE_VBEAM, client_state_t::particles, particletexture, PBLEND_ADD, PBLEND_INVMOD, trace_t::plane, pt_explode, pt_explode2, pt_rain, pt_raindecal, pt_snow, pt_spark, px, particle_t::qualityreduction, r, particle_t::size, particle_t::sizeincrease, particle_t::sortorigin, particle_t::spin, viddef_t::sRGB3D, particle_t::stainalpha, particle_t::staincolor, particle_t::stainsize, particle_t::staintexnum, particle_t::stretch, SUPERCONTENTS_BODY, SUPERCONTENTS_LIQUIDSMASK, SUPERCONTENTS_SOLID, particletexture_t::t1, particletexture_t::t2, tex_particle, tex_rainsplash, particle_t::texnum, client_state_t::time, particle_t::time2, particle_t::typeindex, v, cvar_t::value, VectorCopy, VectorMA, VectorRandom, particle_t::vel, and vid.

Referenced by CL_EntityParticles(), CL_NewParticle(), CL_NewParticlesFromEffectinfo(), CL_NewQuakeParticle(), CL_ParticleCube(), CL_ParticleEffect_Fallback(), CL_ParticleExplosion(), CL_ParticleExplosion2(), CL_ParticleRain(), CL_ReadPointFile_f(), CL_Smoke(), CL_Sparks(), VM_CL_SpawnParticle(), and VM_CL_SpawnParticleDelayed().

◆ CL_NewParticlesFromEffectinfo()

static void CL_NewParticlesFromEffectinfo ( int effectnameindex,
float pcount,
const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
entity_t * ent,
int palettecolor,
qbool spawndlight,
qbool spawnparticles,
float tintmins[4],
float tintmaxs[4],
float fade,
qbool wanttrail )
static

Definition at line 1569 of file cl_particles.c.

1570{
1571 qbool found = false;
1572 char vabuf[1024];
1573 if (effectnameindex < 1 || effectnameindex >= MAX_PARTICLEEFFECTNAME || !particleeffectname[effectnameindex][0])
1574 {
1575 Con_DPrintf("Unknown effect number %i received from server\n", effectnameindex);
1576 return; // no such effect
1577 }
1579 {
1580 int effectinfoindex;
1581 int supercontents;
1582 int tex, staintex;
1584 vec3_t center;
1585 vec3_t traildir;
1586 vec3_t trailpos;
1587 vec3_t rvec;
1588 vec3_t angles;
1591 vec3_t right;
1592 vec3_t up;
1593 vec_t traillen;
1594 vec_t trailstep;
1596 qbool immediatebloodstain;
1597 particle_t *part;
1598 float avgtint[4], tint[4], tintlerp;
1599 // note this runs multiple effects with the same name, each one spawns only one kind of particle, so some effects need more than one
1600 VectorLerp(originmins, 0.5, originmaxs, center);
1601 supercontents = CL_PointSuperContents(center);
1602 underwater = (supercontents & (SUPERCONTENTS_WATER | SUPERCONTENTS_SLIME)) != 0;
1603 VectorSubtract(originmaxs, originmins, traildir);
1604 traillen = VectorLength(traildir);
1605 VectorNormalize(traildir);
1606 if(tintmins)
1607 {
1608 Vector4Lerp(tintmins, 0.5, tintmaxs, avgtint);
1609 }
1610 else
1611 {
1612 Vector4Set(avgtint, 1, 1, 1, 1);
1613 }
1614 for (effectinfoindex = 0, info = particleeffectinfo;effectinfoindex < MAX_PARTICLEEFFECTINFO && info->effectnameindex;effectinfoindex++, info++)
1615 {
1616 if ((info->effectnameindex == effectnameindex) && (info->flags & PARTICLEEFFECT_DEFINED))
1617 {
1618 qbool definedastrail = info->trailspacing > 0;
1619
1620 qbool drawastrail = wanttrail;
1622 drawastrail = drawastrail || definedastrail;
1623
1624 found = true;
1625 if ((info->flags & PARTICLEEFFECT_UNDERWATER) && !underwater)
1626 continue;
1628 continue;
1629
1630 // spawn a dlight if requested
1631 if (info->lightradiusstart > 0 && spawndlight)
1632 {
1633 matrix4x4_t tempmatrix;
1634 if (drawastrail)
1635 Matrix4x4_CreateTranslate(&tempmatrix, originmaxs[0], originmaxs[1], originmaxs[2]);
1636 else
1637 Matrix4x4_CreateTranslate(&tempmatrix, center[0], center[1], center[2]);
1638 if (info->lighttime > 0 && info->lightradiusfade > 0)
1639 {
1640 // light flash (explosion, etc)
1641 // called when effect starts
1642 CL_AllocLightFlash(NULL, &tempmatrix, info->lightradiusstart, info->lightcolor[0]*avgtint[0]*avgtint[3], info->lightcolor[1]*avgtint[1]*avgtint[3], info->lightcolor[2]*avgtint[2]*avgtint[3], info->lightradiusfade, info->lighttime, LightCubemapNumToName(vabuf, sizeof(vabuf), info->lightcubemapnum, info->flags), -1, info->lightshadow, info->lightcorona[0], info->lightcorona[1], 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1643 }
1645 {
1646 // glowing entity
1647 // called by CL_LinkNetworkEntity
1648 Matrix4x4_Scale(&tempmatrix, info->lightradiusstart, 1);
1649 rvec[0] = info->lightcolor[0]*avgtint[0]*avgtint[3];
1650 rvec[1] = info->lightcolor[1]*avgtint[1]*avgtint[3];
1651 rvec[2] = info->lightcolor[2]*avgtint[2]*avgtint[3];
1652 R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &tempmatrix, rvec, -1, LightCubemapNumToName(vabuf, sizeof(vabuf), info->lightcubemapnum, info->flags), info->lightshadow, info->lightcorona[0], info->lightcorona[1], 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1654 }
1655 }
1656
1657 if (!spawnparticles)
1658 continue;
1659
1660 // spawn particles
1661 tex = info->tex[0];
1662 if (info->tex[1] > info->tex[0])
1663 {
1664 tex = (int)lhrandom(info->tex[0], info->tex[1]);
1665 tex = min(tex, info->tex[1] - 1);
1666 }
1667 if(info->staintex[0] < 0)
1668 staintex = info->staintex[0];
1669 else
1670 {
1671 staintex = (int)lhrandom(info->staintex[0], info->staintex[1]);
1672 staintex = min(staintex, info->staintex[1] - 1);
1673 }
1674 if (info->particletype == pt_decal)
1675 {
1676 VectorMAM(0.5f, velocitymins, 0.5f, velocitymaxs, velocity);
1679 VectorMAMAMAM(1.0f, center, info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos);
1680
1681 CL_SpawnDecalParticleForPoint(trailpos, info->originjitter[0], lhrandom(info->size[0], info->size[1]), lhrandom(info->alpha[0], info->alpha[1])*avgtint[3], tex, info->color[0], info->color[1]);
1682 }
1683 else if (info->orientation == PARTICLE_HBEAM)
1684 {
1685 if (!drawastrail)
1686 continue;
1687
1688 AnglesFromVectors(angles, traildir, NULL, false);
1691
1692 CL_NewParticle(center, info->particletype, info->color[0], info->color[1], tex, lhrandom(info->size[0], info->size[1]), info->size[2], lhrandom(info->alpha[0], info->alpha[1]), info->alpha[2], 0, 0, originmins[0] + trailpos[0], originmins[1] + trailpos[1], originmins[2] + trailpos[2], originmaxs[0], originmaxs[1], originmaxs[2], 0, 0, 0, 0, false, lhrandom(info->time[0], info->time[1]), info->stretchfactor, info->blendmode, info->orientation, info->staincolor[0], info->staincolor[1], staintex, lhrandom(info->stainalpha[0], info->stainalpha[1]), lhrandom(info->stainsize[0], info->stainsize[1]), 0, 0, tintmins ? avgtint : NULL);
1693 }
1694 else
1695 {
1696 float cnt;
1697 if (!cl_particles.integer)
1698 continue;
1699 switch (info->particletype)
1700 {
1701 case pt_smoke: if (!cl_particles_smoke.integer) continue;break;
1702 case pt_spark: if (!cl_particles_sparks.integer) continue;break;
1703 case pt_bubble: if (!cl_particles_bubbles.integer) continue;break;
1704 case pt_blood: if (!cl_particles_blood.integer) continue;break;
1705 case pt_rain: if (!cl_particles_rain.integer) continue;break;
1706 case pt_snow: if (!cl_particles_snow.integer) continue;break;
1707 default: break;
1708 }
1709
1710 cnt = info->countabsolute;
1711 cnt += (pcount * info->countmultiplier) * cl_particles_quality.value;
1712 // if drawastrail is not set, we will
1713 // use the regular cnt-based random
1714 // particle spawning at the center; so
1715 // do NOT apply trailspacing then!
1716 if (drawastrail && definedastrail)
1717 cnt += (traillen / info->trailspacing) * cl_particles_quality.value;
1718 cnt *= fade;
1719 if (cnt == 0)
1720 continue; // nothing to draw
1721 info->particleaccumulator += cnt;
1722
1723 if (drawastrail || definedastrail)
1724 immediatebloodstain = false;
1725 else
1726 immediatebloodstain =
1728 ||
1730
1731 if (drawastrail)
1732 {
1733 VectorCopy(originmins, trailpos);
1734 trailstep = traillen / cnt;
1735 }
1736 else
1737 {
1738 VectorCopy(center, trailpos);
1739 trailstep = 0;
1740 }
1741
1742 if (trailstep == 0)
1743 {
1744 VectorMAM(0.5f, velocitymins, 0.5f, velocitymaxs, velocity);
1746 }
1747 else
1748 AnglesFromVectors(angles, traildir, NULL, false);
1749
1751 VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos);
1753 info->particleaccumulator = bound(0, info->particleaccumulator, 16384);
1754 for (;info->particleaccumulator >= 1;info->particleaccumulator--)
1755 {
1756 if (info->tex[1] > info->tex[0])
1757 {
1758 tex = (int)lhrandom(info->tex[0], info->tex[1]);
1759 tex = min(tex, info->tex[1] - 1);
1760 }
1761 if (!(drawastrail || definedastrail))
1762 {
1763 trailpos[0] = lhrandom(originmins[0], originmaxs[0]);
1764 trailpos[1] = lhrandom(originmins[1], originmaxs[1]);
1765 trailpos[2] = lhrandom(originmins[2], originmaxs[2]);
1766 }
1767 if(tintmins)
1768 {
1769 tintlerp = lhrandom(0, 1);
1770 Vector4Lerp(tintmins, tintlerp, tintmaxs, tint);
1771 }
1772 VectorRandom(rvec);
1773 part = CL_NewParticle(center, info->particletype, info->color[0], info->color[1], tex, lhrandom(info->size[0], info->size[1]), info->size[2], lhrandom(info->alpha[0], info->alpha[1]), info->alpha[2], info->gravity, info->bounce, trailpos[0] + info->originoffset[0] + info->originjitter[0] * rvec[0], trailpos[1] + info->originoffset[1] + info->originjitter[1] * rvec[1], trailpos[2] + info->originoffset[2] + info->originjitter[2] * rvec[2], lhrandom(velocitymins[0], velocitymaxs[0]) * info->velocitymultiplier + info->velocityoffset[0] + info->velocityjitter[0] * rvec[0] + velocity[0], lhrandom(velocitymins[1], velocitymaxs[1]) * info->velocitymultiplier + info->velocityoffset[1] + info->velocityjitter[1] * rvec[1] + velocity[1], lhrandom(velocitymins[2], velocitymaxs[2]) * info->velocitymultiplier + info->velocityoffset[2] + info->velocityjitter[2] * rvec[2] + velocity[2], info->airfriction, info->liquidfriction, 0, 0, info->countabsolute <= 0, lhrandom(info->time[0], info->time[1]), info->stretchfactor, info->blendmode, info->orientation, info->staincolor[0], info->staincolor[1], staintex, lhrandom(info->stainalpha[0], info->stainalpha[1]), lhrandom(info->stainsize[0], info->stainsize[1]), lhrandom(info->rotate[0], info->rotate[1]), lhrandom(info->rotate[2], info->rotate[3]), tintmins ? tint : NULL);
1774 if (immediatebloodstain && part)
1775 {
1776 immediatebloodstain = false;
1778 }
1779 if (trailstep)
1780 VectorMA(trailpos, trailstep, traildir, trailpos);
1781 }
1782 }
1783 }
1784 }
1785 }
1786 if (!found)
1787 CL_ParticleEffect_Fallback(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, wanttrail);
1788}
#define SUPERCONTENTS_SLIME
Definition bspfile.h:198
#define SUPERCONTENTS_WATER
Definition bspfile.h:197
#define CL_PointSuperContents(point)
void CL_AllocLightFlash(entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, char *cubemapname, int style, int shadowenable, vec_t corona, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
Definition cl_main.c:852
particleeffectinfo_t particleeffectinfo[MAX_PARTICLEEFFECTINFO]
#define PARTICLEEFFECT_UNDERWATER
static char * LightCubemapNumToName(char *vabuf, size_t vasize, int lightcubemapnum, int flags)
static void CL_ImmediateBloodStain(particle_t *part)
cvar_t cl_particles_sparks
cvar_t cl_particles_snow
#define PARTICLEEFFECT_DEFINED
#define PARTICLEEFFECT_NOTUNDERWATER
cvar_t cl_decals_newsystem_immediatebloodstain
cvar_t cl_particles_quake
cvar_t cl_particles_forcetraileffects
cvar_t cl_particles_blood
cvar_t cl_particles_rain
char particleeffectname[MAX_PARTICLEEFFECTNAME][64]
static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, qbool wanttrail)
cvar_t cl_particles_smoke
cvar_t cl_particles_quality
void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size, float alpha, int texnum, int color1, int color2)
cvar_t cl_particles_bubbles
@ pt_bubble
@ pt_smoke
@ pt_decal
#define LIGHTFLAG_NORMALMODE
Definition client.h:34
#define LIGHTFLAG_REALTIMEMODE
Definition client.h:35
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
vector velocity
vector angles
r_refdef_t r_refdef
Definition gl_rmain.c:57
void AnglesFromVectors(vec3_t angles, const vec3_t forward, const vec3_t up, qbool flippitch)
LadyHavoc: calculates pitch/yaw/roll angles from forward and up vectors.
Definition mathlib.c:650
void AngleVectors(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition mathlib.c:444
#define VectorLerp(v1, lerp, v2, out)
Definition mathlib.h:120
#define bound(min, num, max)
Definition mathlib.h:34
#define VectorLength(a)
Definition mathlib.h:109
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, out)
Definition mathlib.h:117
#define Vector4Set(vec, r, g, b, a)
Definition mathlib.h:86
#define VectorSubtract(a, b, out)
Definition mathlib.h:99
#define Vector4Lerp(v1, lerp, v2, out)
Definition mathlib.h:93
#define VectorMAM(scale1, b1, scale2, b2, out)
Definition mathlib.h:116
#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, out)
Definition mathlib.h:118
void Matrix4x4_CreateTranslate(matrix4x4_t *out, double x, double y, double z)
Definition matrixlib.c:584
void Matrix4x4_Scale(matrix4x4_t *out, double rotatescale, double originscale)
Definition matrixlib.c:1837
#define MAX_DLIGHTS
max number of dynamic lights (rocket flashes, etc) in scene at once
Definition qdefs.h:132
#define MAX_PARTICLEEFFECTINFO
maximum number of unique particle effects (each name may associate with several of these)
Definition qdefs.h:136
#define MAX_PARTICLEEFFECTNAME
maximum number of unique names of particle effects (for particleeffectnum)
Definition qdefs.h:135
bool qbool
Definition qtypes.h:9
void R_RTLight_Update(rtlight_t *rtlight, int isstatic, matrix4x4_t *matrix, vec3_t color, int style, const char *cubemapname, int shadow, vec_t corona, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
Definition r_shadow.c:2980
static struct @33 underwater
porientation_t orientation
float relativeoriginoffset[3]
unsigned int staincolor[2]
float relativevelocityoffset[3]
unsigned int color[2]
rtlight_t templights[MAX_DLIGHTS]
Definition render.h:373
rtlight_t * lights[MAX_DLIGHTS]
Definition render.h:372
r_refdef_scene_t scene
Definition render.h:418
static vec3_t forward
Definition sv_user.c:305
static vec3_t right
Definition sv_user.c:305
static vec3_t up
Definition sv_user.c:305

References particleeffectinfo_t::airfriction, particleeffectinfo_t::alpha, angles, AnglesFromVectors(), AngleVectors(), particleeffectinfo_t::blendmode, particleeffectinfo_t::bounce, bound, CL_AllocLightFlash(), cl_decals_newsystem_immediatebloodstain, CL_ImmediateBloodStain(), CL_NewParticle(), CL_ParticleEffect_Fallback(), cl_particles, cl_particles_blood, cl_particles_bubbles, cl_particles_forcetraileffects, cl_particles_quake, cl_particles_quality, cl_particles_rain, cl_particles_smoke, cl_particles_snow, cl_particles_sparks, CL_PointSuperContents, CL_SpawnDecalParticleForPoint(), particleeffectinfo_t::color, Con_DPrintf(), particleeffectinfo_t::countabsolute, particleeffectinfo_t::countmultiplier, particleeffectinfo_t::effectnameindex, particleeffectinfo_t::flags, forward, particleeffectinfo_t::gravity, int(), cvar_t::integer, lhrandom, particleeffectinfo_t::lightcolor, particleeffectinfo_t::lightcorona, particleeffectinfo_t::lightcubemapnum, LightCubemapNumToName(), LIGHTFLAG_NORMALMODE, LIGHTFLAG_REALTIMEMODE, particleeffectinfo_t::lightradiusfade, particleeffectinfo_t::lightradiusstart, r_refdef_scene_t::lights, particleeffectinfo_t::lightshadow, particleeffectinfo_t::lighttime, particleeffectinfo_t::liquidfriction, Matrix4x4_CreateTranslate(), Matrix4x4_Scale(), MAX_DLIGHTS, MAX_PARTICLEEFFECTINFO, MAX_PARTICLEEFFECTNAME, min, NULL, r_refdef_scene_t::numlights, particleeffectinfo_t::orientation, particleeffectinfo_t::originjitter, particleeffectinfo_t::originoffset, PARTICLE_HBEAM, particleeffectinfo_t::particleaccumulator, PARTICLEEFFECT_DEFINED, PARTICLEEFFECT_NOTUNDERWATER, PARTICLEEFFECT_UNDERWATER, particleeffectinfo, particleeffectname, particleeffectinfo_t::particletype, pt_blood, pt_bubble, pt_decal, pt_rain, pt_smoke, pt_snow, pt_spark, r_refdef, R_RTLight_Update(), particleeffectinfo_t::relativeoriginoffset, particleeffectinfo_t::relativevelocityoffset, right, particleeffectinfo_t::rotate, r_refdef_t::scene, particleeffectinfo_t::size, particleeffectinfo_t::stainalpha, particleeffectinfo_t::staincolor, particleeffectinfo_t::stainsize, particleeffectinfo_t::staintex, particleeffectinfo_t::stretchfactor, SUPERCONTENTS_SLIME, SUPERCONTENTS_WATER, r_refdef_scene_t::templights, particleeffectinfo_t::tex, particleeffectinfo_t::time, particleeffectinfo_t::trailspacing, underwater, up, cvar_t::value, Vector4Lerp, Vector4Set, VectorCopy, VectorLength, VectorLerp, VectorMA, VectorMAM, VectorMAMAM, VectorMAMAMAM, VectorNormalize, VectorRandom, VectorSubtract, velocity, particleeffectinfo_t::velocityjitter, particleeffectinfo_t::velocitymultiplier, and particleeffectinfo_t::velocityoffset.

Referenced by CL_ParticleBox(), CL_ParticleEffect_Fallback(), and CL_ParticleTrail().

◆ CL_NewQuakeParticle()

particle_t * CL_NewQuakeParticle ( const vec3_t origin,
const unsigned short ptypeindex,
const int color_1,
const int color_2,
const float gravity,
const float offset_x,
const float offset_y,
const float offset_z,
const float velocity_offset_x,
const float velocity_offset_y,
const float velocity_offset_z,
const float air_friction,
const float liquid_friction,
const float origin_jitter,
const float velocity_jitter,
const float lifetime )

Creates a simple particle, a square like Quake, or a disc like GLQuake.

Parameters
[in]origin?
[in]color_1,color_2Minimum and maximum range of color, randomly interpolated with pcolor2 to decide particle color
[in]gravityHow much effect gravity has on the particle (0-1)
[in]offset_x,offset_y,offset_zStarting origin of particle
[in]velocity_offset_x,velocity_offset_y,velocity_offset_zStarting velocity of particle
[in]air_frictionHow much the particle slows down, in air, per second (0-1 typically, can slowdown faster than 1)
[in]liquid_frictionHow much the particle slows down, in liquids, per second (0-1 typically, can slowdown faster than 1)
[in]origin_jitter?
[in]velocity_jitter?
[in]lifetimeHow long the particle can live (note it is also removed if alpha drops to nothing)
Returns
Pointer to the new particle

Definition at line 869 of file cl_particles.c.

886{
887 int texture;
888
889 // Set the particle texture based on the value of cl_particles_quake; defaulting to the GLQuake disc
892 else
894
895 return CL_NewParticle(
896 origin,
897 ptypeindex, // type
898 color_1,
899 color_2,
900 texture,
901 0.8f, // size
902 0, // size increase
903 255, // alpha
904 0, // alpha fade
905 gravity,
906 0, // bounce
907 offset_x,
908 offset_y,
909 offset_z,
910 velocity_offset_x,
911 velocity_offset_y,
912 velocity_offset_z,
913 air_friction,
914 liquid_friction,
915 origin_jitter,
916 velocity_jitter,
917 true, // quality reduction
918 lifetime,
919 1, // stretch
920 PBLEND_ALPHA, // blend mode
921 PARTICLE_BILLBOARD, // orientation
922 -1, // stain color 1
923 -1, // stain color 2
924 -1, // stain texture
925 1, // stain alpha
926 1, // stain size
927 0, // angle
928 0, // spin
929 NULL // tint
930 );
931}
static const int tex_square
vector origin
GLenum GLenum GLuint texture
Definition glquake.h:613

References CL_NewParticle(), cl_particles_quake, cvar_t::integer, NULL, origin, PARTICLE_BILLBOARD, PBLEND_ALPHA, tex_particle, tex_square, and texture.

Referenced by CL_ParticleEffect_Fallback(), CL_ParticleExplosion(), and CL_ParticleExplosion2().

◆ CL_ParseParticleEffect()

void CL_ParseParticleEffect ( void )

Definition at line 1914 of file cl_particles.c.

1915{
1916 vec3_t org, dir;
1917 int i, count, msgcount, color;
1918
1920 for (i=0 ; i<3 ; i++)
1921 dir[i] = MSG_ReadChar(&cl_message) * (1.0 / 16.0);
1922 msgcount = MSG_ReadByte(&cl_message);
1924
1925 if (msgcount == 255)
1926 count = 1024;
1927 else
1928 count = msgcount;
1929
1931}
client_static_t cls
Definition cl_main.c:116
void CL_ParticleEffect(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor)
@ EFFECT_SVC_PARTICLE
void MSG_ReadVector(sizebuf_t *sb, vec3_t v, protocolversion_t protocol)
Definition com_msg.c:401
#define MSG_ReadChar(sb)
Definition common.h:187
#define MSG_ReadByte(sb)
Definition common.h:188
vector color
GLenum GLenum GLsizei count
Definition glquake.h:656
sizebuf_t cl_message
Definition netconn.c:71
vec2 dir
protocolversion_t protocol
Definition client.h:617

References cl_message, CL_ParticleEffect(), cls, color, count, dir, EFFECT_SVC_PARTICLE, i, MSG_ReadByte, MSG_ReadChar, MSG_ReadVector(), NULL, and client_static_t::protocol.

Referenced by CL_ParseServerMessage().

◆ CL_Particle_PixelCoordsForTexnum()

static void CL_Particle_PixelCoordsForTexnum ( int texnum,
int * basex,
int * basey,
int * width,
int * height )
static

Definition at line 2189 of file cl_particles.c.

2190{
2191 *basex = (texnum % particlefontcols) * particlefontcellwidth;
2195}
int particlefontrows
int particlefontcellheight
int particlefontcols
int particlefontcellwidth
GLenum GLsizei width
Definition glquake.h:622
GLenum GLsizei GLsizei height
Definition glquake.h:622

References height, particlefontcellheight, particlefontcellwidth, particlefontcols, particlefontrows, and width.

Referenced by R_InitParticleTexture(), and setuptex().

◆ CL_ParticleBox()

void CL_ParticleBox ( int effectnameindex,
float pcount,
const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
entity_t * ent,
int palettecolor,
qbool spawndlight,
qbool spawnparticles,
float tintmins[4],
float tintmaxs[4],
float fade )

Definition at line 1795 of file cl_particles.c.

1796{
1797 CL_NewParticlesFromEffectinfo(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, tintmins, tintmaxs, fade, false);
1798}
static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, float tintmins[4], float tintmaxs[4], float fade, qbool wanttrail)

References CL_NewParticlesFromEffectinfo().

Referenced by CL_ParticleEffect(), and VM_CL_boxparticles().

◆ CL_ParticleCube()

void CL_ParticleCube ( const vec3_t mins,
const vec3_t maxs,
const vec3_t dir,
int count,
int colorbase,
vec_t gravity,
vec_t randomvel )

Definition at line 2073 of file cl_particles.c.

2074{
2075 vec3_t center;
2076 int k;
2077 if (!cl_particles.integer) return;
2078 VectorMAM(0.5f, mins, 0.5f, maxs, center);
2079
2081 while (count--)
2082 {
2083 k = particlepalette[colorbase + (rand()&3)];
2084 CL_NewParticle(center, pt_alphastatic, k, k, tex_particle, 2, 0, 255, 128, gravity, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), dir[0], dir[1], dir[2], 0, 0, 0, randomvel, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
2085 }
2086}
@ pt_alphastatic
vector mins
vector maxs

References CL_NewParticle(), cl_particles, cl_particles_quality, count, dir, int(), cvar_t::integer, lhrandom, maxs, mins, NULL, PARTICLE_BILLBOARD, particlepalette, PBLEND_ALPHA, pt_alphastatic, tex_particle, cvar_t::value, and VectorMAM.

Referenced by CL_ParseTempEntity(), and VM_CL_te_particlecube().

◆ CL_ParticleEffect()

void CL_ParticleEffect ( int effectnameindex,
float pcount,
const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
entity_t * ent,
int palettecolor )

Definition at line 1801 of file cl_particles.c.

1802{
1803 CL_ParticleBox(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, true, true, NULL, NULL, 1);
1804}
void CL_ParticleBox(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qbool spawndlight, qbool spawnparticles, float tintmins[4], float tintmaxs[4], float fade)

References CL_ParticleBox(), and NULL.

Referenced by CL_ParseParticleEffect(), CL_ParsePointParticles(), CL_ParsePointParticles1(), CL_ParseTempEntity(), VM_CL_particle(), VM_CL_pointparticles(), VM_CL_te_blood(), VM_CL_te_bloodshower(), VM_CL_te_explosion(), VM_CL_te_explosionquad(), VM_CL_te_flamejet(), VM_CL_te_gunshot(), VM_CL_te_gunshotquad(), VM_CL_te_knightspike(), VM_CL_te_lavasplash(), VM_CL_te_plasmaburn(), VM_CL_te_smallflash(), VM_CL_te_spark(), VM_CL_te_spike(), VM_CL_te_spikequad(), VM_CL_te_superspike(), VM_CL_te_superspikequad(), VM_CL_te_tarexplosion(), VM_CL_te_teleport(), and VM_CL_te_wizspike().

◆ CL_ParticleEffect_Fallback()

static void CL_ParticleEffect_Fallback ( int effectnameindex,
float count,
const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
entity_t * ent,
int palettecolor,
qbool spawndlight,
qbool spawnparticles,
qbool wanttrail )
static

Definition at line 1024 of file cl_particles.c.

1025{
1026 vec3_t center;
1027 matrix4x4_t lightmatrix;
1028 particle_t *part;
1029
1030 VectorLerp(originmins, 0.5, originmaxs, center);
1031 Matrix4x4_CreateTranslate(&lightmatrix, center[0], center[1], center[2]);
1032 if (effectnameindex == EFFECT_SVC_PARTICLE)
1033 {
1035 {
1036 // bloodhack checks if this effect's color matches regular or lightning blood and if so spawns a blood effect instead
1037 if (count == 1024)
1038 CL_NewParticlesFromEffectinfo(EFFECT_TE_EXPLOSION, 1, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1039 else if (cl_particles_blood_bloodhack.integer && !cl_particles_quake.integer && (palettecolor == 73 || palettecolor == 225))
1040 CL_NewParticlesFromEffectinfo(EFFECT_TE_BLOOD, count / 2.0f, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1041 else
1042 {
1044 for (;count > 0;count--)
1045 {
1046 int k = particlepalette[(palettecolor & ~7) + (rand()&7)];
1048 center, // origin
1049 pt_alphastatic, // type
1050 k, // color 1
1051 k, // color 2
1052 0.15, // gravity
1053 lhrandom(originmins[0], originmaxs[0]), // offset x
1054 lhrandom(originmins[1], originmaxs[1]), // offset y
1055 lhrandom(originmins[2], originmaxs[2]), // offset z
1056 lhrandom(velocitymins[0], velocitymaxs[0]), // velocity offset x
1057 lhrandom(velocitymins[1], velocitymaxs[1]), // velocity offset y
1058 lhrandom(velocitymins[2], velocitymaxs[2]), // velocity offset z
1059 0, // air friction
1060 0, // liquid friction
1061 8, // origin jitter
1062 3, // velocity jitter
1063 lhrandom(0.1, 0.4) // lifetime
1064 );
1065 }
1066 }
1067 }
1068 }
1069 else if (effectnameindex == EFFECT_TE_WIZSPIKE)
1070 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 30*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 20, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1071 else if (effectnameindex == EFFECT_TE_KNIGHTSPIKE)
1072 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 226, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1073 else if (effectnameindex == EFFECT_TE_SPIKE)
1074 {
1076 {
1078 {
1080 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 10*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1081 }
1082 else
1083 {
1084 CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 4*count);
1085 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, 15*count);
1086 CL_NewParticle(center, pt_static, 0x808080,0x808080, tex_particle, 3, 0, 256, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1087 }
1088 }
1089 // bullet hole
1090 R_Stain(center, 16, 40, 40, 40, 64, 88, 88, 88, 64);
1091 CL_SpawnDecalParticleForPoint(center, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1092 }
1093 else if (effectnameindex == EFFECT_TE_SPIKEQUAD)
1094 {
1096 {
1098 {
1100 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 10*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1101 }
1102 else
1103 {
1104 CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 4*count);
1105 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, 15*count);
1106 CL_NewParticle(center, pt_static, 0x808080,0x808080, tex_particle, 3, 0, 256, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1107 }
1108 }
1109 // bullet hole
1110 R_Stain(center, 16, 40, 40, 40, 64, 88, 88, 88, 64);
1111 CL_SpawnDecalParticleForPoint(center, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1112 CL_AllocLightFlash(NULL, &lightmatrix, 100, 0.15f, 0.15f, 1.5f, 500, 0.2, NULL, -1, true, 1, 0.25, 1, 0, 0, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1113 }
1114 else if (effectnameindex == EFFECT_TE_SUPERSPIKE)
1115 {
1117 {
1119 {
1121 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1122 }
1123 else
1124 {
1125 CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 8*count);
1126 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, 30*count);
1127 CL_NewParticle(center, pt_static, 0x808080,0x808080, tex_particle, 3, 0, 256, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1128 }
1129 }
1130 // bullet hole
1131 R_Stain(center, 16, 40, 40, 40, 64, 88, 88, 88, 64);
1132 CL_SpawnDecalParticleForPoint(center, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1133 }
1134 else if (effectnameindex == EFFECT_TE_SUPERSPIKEQUAD)
1135 {
1137 {
1139 {
1141 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1142 }
1143 else
1144 {
1145 CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 8*count);
1146 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, 30*count);
1147 CL_NewParticle(center, pt_static, 0x808080,0x808080, tex_particle, 3, 0, 256, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1148 }
1149 }
1150 // bullet hole
1151 R_Stain(center, 16, 40, 40, 40, 64, 88, 88, 88, 64);
1152 CL_SpawnDecalParticleForPoint(center, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1153 CL_AllocLightFlash(NULL, &lightmatrix, 100, 0.15f, 0.15f, 1.5f, 500, 0.2, NULL, -1, true, 1, 0.25, 1, 0, 0, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1154 }
1155 else if (effectnameindex == EFFECT_TE_BLOOD)
1156 {
1158 return;
1160 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 2*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 73, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1161 else
1162 {
1163 static double bloodaccumulator = 0;
1164 qbool immediatebloodstain = (cl_decals_newsystem_immediatebloodstain.integer >= 1);
1165 //CL_NewParticle(center, pt_alphastatic, 0x4f0000,0x7f0000, tex_particle, 2.5, 0, 256, 256, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 1, 4, 0, 0, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, NULL);
1166 bloodaccumulator += count * 0.333 * cl_particles_quality.value;
1167 for (;bloodaccumulator > 0;bloodaccumulator--)
1168 {
1169 part = CL_NewParticle(center, pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, 0, cl_particles_blood_alpha.value * 768, cl_particles_blood_alpha.value * 384, 1, -1, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 0, 64, true, 0, 1, PBLEND_INVMOD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1170 if (immediatebloodstain && part)
1171 {
1172 immediatebloodstain = false;
1174 }
1175 }
1176 }
1177 }
1178 else if (effectnameindex == EFFECT_TE_SPARK)
1179 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, count);
1180 else if (effectnameindex == EFFECT_TE_PLASMABURN)
1181 {
1182 // plasma scorch mark
1183 R_Stain(center, 40, 40, 40, 40, 64, 88, 88, 88, 64);
1184 CL_SpawnDecalParticleForPoint(center, 6, 6, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1185 CL_AllocLightFlash(NULL, &lightmatrix, 200, 1, 1, 1, 1000, 0.2, NULL, -1, true, 1, 0.25, 1, 0, 0, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1186 }
1187 else if (effectnameindex == EFFECT_TE_GUNSHOT)
1188 {
1190 {
1192 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1193 else
1194 {
1195 CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 4*count);
1196 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, 20*count);
1197 CL_NewParticle(center, pt_static, 0x808080,0x808080, tex_particle, 3, 0, 256, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1198 }
1199 }
1200 // bullet hole
1201 R_Stain(center, 16, 40, 40, 40, 64, 88, 88, 88, 64);
1202 CL_SpawnDecalParticleForPoint(center, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1203 }
1204 else if (effectnameindex == EFFECT_TE_GUNSHOTQUAD)
1205 {
1207 {
1209 CL_NewParticlesFromEffectinfo(EFFECT_SVC_PARTICLE, 20*count, originmins, originmaxs, velocitymins, velocitymaxs, NULL, 0, spawndlight, spawnparticles, NULL, NULL, 1, wanttrail);
1210 else
1211 {
1212 CL_Smoke(originmins, originmaxs, velocitymins, velocitymaxs, 4*count);
1213 CL_Sparks(originmins, originmaxs, velocitymins, velocitymaxs, 20*count);
1214 CL_NewParticle(center, pt_static, 0x808080,0x808080, tex_particle, 3, 0, 256, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1215 }
1216 }
1217 // bullet hole
1218 R_Stain(center, 16, 40, 40, 40, 64, 88, 88, 88, 64);
1219 CL_SpawnDecalParticleForPoint(center, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1220 CL_AllocLightFlash(NULL, &lightmatrix, 100, 0.15f, 0.15f, 1.5f, 500, 0.2, NULL, -1, true, 1, 0.25, 1, 0, 0, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1221 }
1222 else if (effectnameindex == EFFECT_TE_EXPLOSION)
1223 {
1224 CL_ParticleExplosion(center);
1225 CL_AllocLightFlash(NULL, &lightmatrix, 350, 4.0f, 2.0f, 0.50f, 700, 0.5, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1226 }
1227 else if (effectnameindex == EFFECT_TE_EXPLOSIONQUAD)
1228 {
1229 CL_ParticleExplosion(center);
1230 CL_AllocLightFlash(NULL, &lightmatrix, 350, 2.5f, 2.0f, 4.0f, 700, 0.5, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1231 }
1232 else if (effectnameindex == EFFECT_TE_TAREXPLOSION)
1233 {
1235 {
1236 int i;
1237 for (i = 0;i < 1024 * cl_particles_quality.value;i++)
1238 {
1239 if (i & 1)
1240 CL_NewParticle(center, pt_alphastatic, particlepalette[66], particlepalette[71], tex_particle, 1.5f, 0, 255, 0, 0, 0, center[0], center[1], center[2], 0, 0, 0, -4, -4, 16, 256, true, (rand() & 1) ? 1.4 : 1.0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1241 else
1242 CL_NewParticle(center, pt_alphastatic, particlepalette[150], particlepalette[155], tex_particle, 1.5f, 0, 255, 0, 0, 0, center[0], center[1], center[2], 0, 0, lhrandom(-256, 256), 0, 0, 16, 0, true, (rand() & 1) ? 1.4 : 1.0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1243 }
1244 }
1245 else
1246 CL_ParticleExplosion(center);
1247 CL_AllocLightFlash(NULL, &lightmatrix, 600, 1.6f, 0.8f, 2.0f, 1200, 0.5, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1248 }
1249 else if (effectnameindex == EFFECT_TE_SMALLFLASH)
1250 CL_AllocLightFlash(NULL, &lightmatrix, 200, 2, 2, 2, 1000, 0.2, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1251 else if (effectnameindex == EFFECT_TE_FLAMEJET)
1252 {
1254 while (count-- > 0)
1255 CL_NewParticle(center, pt_smoke, 0x6f0f00, 0xe3974f, tex_particle, 4, 0, lhrandom(64, 128), 384, -1, 1.1, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 0, 128, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1256 }
1257 else if (effectnameindex == EFFECT_TE_LAVASPLASH)
1258 {
1259 float i, j, inc, vel;
1260 vec3_t dir, org;
1261
1262 inc = 8 / cl_particles_quality.value;
1263 for (i = -128;i < 128;i += inc)
1264 {
1265 for (j = -128;j < 128;j += inc)
1266 {
1267 dir[0] = j + lhrandom(0, inc);
1268 dir[1] = i + lhrandom(0, inc);
1269 dir[2] = 256;
1270 org[0] = center[0] + dir[0];
1271 org[1] = center[1] + dir[1];
1272 org[2] = center[2] + lhrandom(0, 64);
1273 vel = lhrandom(50, 120) / VectorLength(dir); // normalize and scale
1274 CL_NewParticle(center, pt_alphastatic, particlepalette[224], particlepalette[231], tex_particle, 1.5f, 0, 255, 0, 0.05, 0, org[0], org[1], org[2], dir[0] * vel, dir[1] * vel, dir[2] * vel, 0, 0, 0, 0, true, lhrandom(2, 2.62), 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1275 }
1276 }
1277 }
1278 else if (effectnameindex == EFFECT_TE_TELEPORT)
1279 {
1280 float i, j, k, inc, vel;
1281 vec3_t dir;
1282
1284 inc = 4 / cl_particles_quality.value;
1285 else
1286 inc = 8 / cl_particles_quality.value;
1287 for (i = -16;i < 16;i += inc)
1288 {
1289 for (j = -16;j < 16;j += inc)
1290 {
1291 for (k = -24;k < 32;k += inc)
1292 {
1293 VectorSet(dir, i*8, j*8, k*8);
1295 vel = lhrandom(50, 113);
1297 CL_NewParticle(center, pt_alphastatic, particlepalette[7], particlepalette[14], tex_particle, 1.5f, 0, 255, 0, 0, 0, center[0] + i + lhrandom(0, inc), center[1] + j + lhrandom(0, inc), center[2] + k + lhrandom(0, inc), dir[0] * vel, dir[1] * vel, dir[2] * vel, 0, 0, 0, 0, true, lhrandom(0.2, 0.34), 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1298 else
1299 CL_NewParticle(center, pt_alphastatic, particlepalette[7], particlepalette[14], tex_particle, 1.5f, 0, inc * lhrandom(37, 63), inc * 187, 0, 0, center[0] + i + lhrandom(0, inc), center[1] + j + lhrandom(0, inc), center[2] + k + lhrandom(0, inc), dir[0] * vel, dir[1] * vel, dir[2] * vel, 0, 0, 0, 0, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1300 }
1301 }
1302 }
1304 CL_NewParticle(center, pt_static, 0xffffff, 0xffffff, tex_particle, 30, 0, 256, 512, 0, 0, center[0], center[1], center[2], 0, 0, 0, 0, 0, 0, 0, false, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1305 CL_AllocLightFlash(NULL, &lightmatrix, 200, 2.0f, 2.0f, 2.0f, 400, 99.0f, NULL, -1, true, 1, 0.25, 1, 0, 0, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1306 }
1307 else if (effectnameindex == EFFECT_TE_TEI_G3)
1308 CL_NewParticle(center, pt_beam, 0xFFFFFF, 0xFFFFFF, tex_beam, 8, 0, 256, 256, 0, 0, originmins[0], originmins[1], originmins[2], originmaxs[0], originmaxs[1], originmaxs[2], 0, 0, 0, 0, false, 0, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL);
1309 else if (effectnameindex == EFFECT_TE_TEI_SMOKE)
1310 {
1312 {
1313 count *= 0.25f * cl_particles_quality.value;
1314 while (count-- > 0)
1315 CL_NewParticle(center, pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 0, 255, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 0, 0, 1.5f, 6.0f, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1316 }
1317 }
1318 else if (effectnameindex == EFFECT_TE_TEI_BIGEXPLOSION)
1319 {
1320 CL_ParticleExplosion(center);
1321 CL_AllocLightFlash(NULL, &lightmatrix, 500, 2.5f, 2.0f, 1.0f, 500, 9999, NULL, -1, true, 1, 0.25, 0.5, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1322 }
1323 else if (effectnameindex == EFFECT_TE_TEI_PLASMAHIT)
1324 {
1325 float f;
1326 R_Stain(center, 40, 40, 40, 40, 64, 88, 88, 88, 64);
1327 CL_SpawnDecalParticleForPoint(center, 6, 8, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1329 for (f = 0;f < count;f += 4.0f / cl_particles_quality.value)
1330 CL_NewParticle(center, pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 0, 255, 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 0, 0, 20, 155, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1332 for (f = 0;f < count;f += 1.0f / cl_particles_quality.value)
1333 CL_NewParticle(center, pt_spark, 0x2030FF, 0x80C0FF, tex_particle, 2.0f, 0, lhrandom(64, 255), 512, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 0, 0, 0, 465, true, 0, 1, PBLEND_ADD, PARTICLE_SPARK, -1, -1, -1, 1, 1, 0, 0, NULL);
1334 CL_AllocLightFlash(NULL, &lightmatrix, 500, 0.6f, 1.2f, 2.0f, 2000, 9999, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1335 }
1336 else if (effectnameindex == EFFECT_EF_FLAME)
1337 {
1338 if (!spawnparticles)
1339 count = 0;
1341 while (count-- > 0)
1342 CL_NewParticle(center, pt_smoke, 0x6f0f00, 0xe3974f, tex_particle, 4, 0, lhrandom(64, 128), 384, -1, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 16, 128, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1343 CL_AllocLightFlash(NULL, &lightmatrix, 200, 2.0f, 1.5f, 0.5f, 0, 0, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1344 }
1345 else if (effectnameindex == EFFECT_EF_STARDUST)
1346 {
1347 if (!spawnparticles)
1348 count = 0;
1350 while (count-- > 0)
1351 CL_NewParticle(center, pt_static, 0x903010, 0xFFD030, tex_particle, 4, 0, lhrandom(64, 128), 128, 1, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 0.2, 0.8, 16, 128, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1352 CL_AllocLightFlash(NULL, &lightmatrix, 200, 1.0f, 0.7f, 0.3f, 0, 0, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1353 }
1354 else if (!strncmp(particleeffectname[effectnameindex], "TR_", 3))
1355 {
1356 vec3_t dir, pos;
1357 float len, dec, qd;
1358 int smoke, blood, bubbles, r, color, spawnedcount;
1359
1360 if (spawndlight && r_refdef.scene.numlights < MAX_DLIGHTS)
1361 {
1362 vec4_t light;
1363 Vector4Set(light, 0, 0, 0, 0);
1364
1365 if (effectnameindex == EFFECT_TR_ROCKET)
1366 Vector4Set(light, 3.0f, 1.5f, 0.5f, 200);
1367 else if (effectnameindex == EFFECT_TR_VORESPIKE)
1368 {
1370 Vector4Set(light, 0.3f, 0.6f, 1.2f, 100);
1371 else
1372 Vector4Set(light, 1.2f, 0.5f, 1.0f, 200);
1373 }
1374 else if (effectnameindex == EFFECT_TR_NEXUIZPLASMA)
1375 Vector4Set(light, 0.75f, 1.5f, 3.0f, 200);
1376
1377 if (light[3])
1378 {
1379 matrix4x4_t traillightmatrix;
1380 Matrix4x4_CreateFromQuakeEntity(&traillightmatrix, originmaxs[0], originmaxs[1], originmaxs[2], 0, 0, 0, light[3]);
1381 R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &traillightmatrix, light, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1383 }
1384 }
1385
1386 if (!spawnparticles)
1387 return;
1388
1389 if (originmaxs[0] == originmins[0] && originmaxs[1] == originmins[1] && originmaxs[2] == originmins[2])
1390 return;
1391
1392 VectorSubtract(originmaxs, originmins, dir);
1394
1395 if (ent)
1396 {
1397 dec = -ent->persistent.trail_time;
1398 ent->persistent.trail_time += len;
1399 if (ent->persistent.trail_time < 0.01f)
1400 return;
1401
1402 // if we skip out, leave it reset
1403 ent->persistent.trail_time = 0.0f;
1404 }
1405 else
1406 dec = 0;
1407
1408 // advance into this frame to reach the first puff location
1409 VectorMA(originmins, dec, dir, pos);
1410 len -= dec;
1411
1415 qd = 1.0f / cl_particles_quality.value;
1416 spawnedcount = 0;
1417
1418 while (len >= 0 && ++spawnedcount <= 16384)
1419 {
1420 dec = 3;
1421 if (blood)
1422 {
1423 if (effectnameindex == EFFECT_TR_BLOOD)
1424 {
1426 {
1427 color = particlepalette[67 + (rand()&3)];
1428 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0.25, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0, 2);
1429 }
1430 else
1431 {
1432 dec = 16;
1433 CL_NewParticle(center, pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, 0, qd * cl_particles_blood_alpha.value * 768.0f, qd * cl_particles_blood_alpha.value * 384.0f, 1, -1, pos[0], pos[1], pos[2], lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 0, 64, true, 0, 1, PBLEND_INVMOD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1434 }
1435 }
1436 else if (effectnameindex == EFFECT_TR_SLIGHTBLOOD)
1437 {
1439 {
1440 dec = 6;
1441 color = particlepalette[67 + (rand()&3)];
1442 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0.25, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0, 2);
1443 }
1444 else
1445 {
1446 dec = 32;
1447 CL_NewParticle(center, pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, 0, qd * cl_particles_blood_alpha.value * 768.0f, qd * cl_particles_blood_alpha.value * 384.0f, 1, -1, pos[0], pos[1], pos[2], lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 1, 4, 0, 64, true, 0, 1, PBLEND_INVMOD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1448 }
1449 }
1450 }
1451 if (smoke)
1452 {
1453 if (effectnameindex == EFFECT_TR_ROCKET)
1454 {
1456 {
1457 r = rand()&3;
1459 CL_NewQuakeParticle(center, pt_alphastatic, color, color, -0.10, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0, 0.1372549 * (6 - r));
1460 }
1461 else
1462 {
1463 CL_NewParticle(center, pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, 0, cl_particles_smoke_alpha.value*62, cl_particles_smoke_alphafade.value*62, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1464 CL_NewParticle(center, pt_static, 0x801010, 0xFFA020, tex_smoke[rand()&7], 3, 0, cl_particles_smoke_alpha.value*288, cl_particles_smoke_alphafade.value*1400, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 20, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1465 }
1466 }
1467 else if (effectnameindex == EFFECT_TR_GRENADE)
1468 {
1470 {
1471 r = 2 + (rand()%4);
1473 CL_NewQuakeParticle(center, pt_alphastatic, color, color, -0.15, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 3, 0, 0.1372549 * (6 - r));
1474 }
1475 else
1476 {
1477 CL_NewParticle(center, pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, 0, cl_particles_smoke_alpha.value*50, cl_particles_smoke_alphafade.value*75, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1478 }
1479 }
1480 else if (effectnameindex == EFFECT_TR_WIZSPIKE)
1481 {
1483 {
1484 dec = 6;
1485 color = particlepalette[52 + (rand()&7)];
1486 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0, pos[0], pos[1], pos[2], 30*dir[1], 30*-dir[0], 0, 0, 0, 0, 0, 0.5);
1487 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0, pos[0], pos[1], pos[2], 30*-dir[1], 30*dir[0], 0, 0, 0, 0, 0, 0.5);
1488 }
1489 else if (gamemode == GAME_GOODVSBAD2)
1490 {
1491 dec = 6;
1492 CL_NewParticle(center, pt_static, 0x00002E, 0x000030, tex_particle, 6, 0, 128, 384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1493 }
1494 else
1495 {
1496 color = particlepalette[20 + (rand()&7)];
1497 CL_NewParticle(center, pt_static, color, color, tex_particle, 2, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1498 }
1499 }
1500 else if (effectnameindex == EFFECT_TR_KNIGHTSPIKE)
1501 {
1503 {
1504 dec = 6;
1505 color = particlepalette[230 + (rand()&7)];
1506 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0, pos[0], pos[1], pos[2], 30 * dir[1], 30 * -dir[0], 0, 0, 0, 0, 0, 0.5);
1507 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0, pos[0], pos[1], pos[2], 30 * -dir[1], 30 * dir[0], 0, 0, 0, 0, 0, 0.5);
1508 }
1509 else
1510 {
1511 color = particlepalette[226 + (rand()&7)];
1512 CL_NewParticle(center, pt_static, color, color, tex_particle, 2, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1513 }
1514 }
1515 else if (effectnameindex == EFFECT_TR_VORESPIKE)
1516 {
1518 {
1519 color = particlepalette[152 + (rand()&3)];
1520 CL_NewQuakeParticle(center, pt_alphastatic, color, color, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 8, 0, 0.3);
1521 }
1522 else if (gamemode == GAME_GOODVSBAD2)
1523 {
1524 dec = 6;
1525 CL_NewParticle(center, pt_alphastatic, particlepalette[0 + (rand()&255)], particlepalette[0 + (rand()&255)], tex_particle, 6, 0, 255, 384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1526 }
1527 else if (gamemode == GAME_PRYDON)
1528 {
1529 dec = 6;
1530 CL_NewParticle(center, pt_static, 0x103040, 0x204050, tex_particle, 6, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1531 }
1532 else
1533 CL_NewParticle(center, pt_static, 0x502030, 0x502030, tex_particle, 3, 0, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1534 }
1535 else if (effectnameindex == EFFECT_TR_NEHAHRASMOKE)
1536 {
1537 dec = 7;
1538 CL_NewParticle(center, pt_alphastatic, 0x303030, 0x606060, tex_smoke[rand()&7], 7, 0, 64, 320, 0, 0, pos[0], pos[1], pos[2], 0, 0, lhrandom(4, 12), 0, 0, 0, 4, false, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1539 }
1540 else if (effectnameindex == EFFECT_TR_NEXUIZPLASMA)
1541 {
1542 dec = 4;
1543 CL_NewParticle(center, pt_static, 0x283880, 0x283880, tex_particle, 4, 0, 255, 1024, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 16, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1544 }
1545 else if (effectnameindex == EFFECT_TR_GLOWTRAIL)
1546 CL_NewParticle(center, pt_alphastatic, particlepalette[palettecolor], particlepalette[palettecolor], tex_particle, 5, 0, 128, 320, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1547 }
1548 if (bubbles)
1549 {
1550 if (effectnameindex == EFFECT_TR_ROCKET)
1551 CL_NewParticle(center, pt_bubble, 0x404040, 0x808080, tex_bubble, 2, 0, lhrandom(128, 512), 512, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, 0.0625, 0.25, 0, 16, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1552 else if (effectnameindex == EFFECT_TR_GRENADE)
1553 CL_NewParticle(center, pt_bubble, 0x404040, 0x808080, tex_bubble, 2, 0, lhrandom(128, 512), 512, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, 0.0625, 0.25, 0, 16, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1554 }
1555 // advance to next time and position
1556 dec *= qd;
1557 len -= dec;
1558 VectorMA (pos, dec, dir, pos);
1559 }
1560 if (ent)
1561 ent->persistent.trail_time = len;
1562 }
1563 else
1564 Con_DPrintf("CL_ParticleEffect_Fallback: no fallback found for effect %s\n", particleeffectname[effectnameindex]);
1565}
cvar_t cl_particles_blood_bloodhack
cvar_t cl_particles_blood_alpha
static void CL_Sparks(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float sparkcount)
static const int tex_bubble
cvar_t cl_particles_smoke_alpha
static const int tex_bulletdecal[8]
particle_t * CL_NewQuakeParticle(const vec3_t origin, const unsigned short ptypeindex, const int color_1, const int color_2, const float gravity, const float offset_x, const float offset_y, const float offset_z, const float velocity_offset_x, const float velocity_offset_y, const float velocity_offset_z, const float air_friction, const float liquid_friction, const float origin_jitter, const float velocity_jitter, const float lifetime)
Creates a simple particle, a square like Quake, or a disc like GLQuake.
void CL_ParticleExplosion(const vec3_t org)
cvar_t cl_particles_smoke_alphafade
int ramp3[8]
static const int tex_bloodparticle[8]
static const int tex_smoke[8]
static const int tex_beam
cvar_t cl_particles_bulletimpacts
static void CL_Smoke(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float smokecount)
@ EFFECT_TE_WIZSPIKE
@ EFFECT_TR_GLOWTRAIL
@ EFFECT_TE_TEI_SMOKE
@ EFFECT_EF_STARDUST
@ EFFECT_TE_FLAMEJET
@ EFFECT_TR_SLIGHTBLOOD
@ EFFECT_TE_SUPERSPIKEQUAD
@ EFFECT_TE_SPIKEQUAD
@ EFFECT_TE_SPARK
@ EFFECT_TR_WIZSPIKE
@ EFFECT_TE_GUNSHOTQUAD
@ EFFECT_TE_EXPLOSIONQUAD
@ EFFECT_TE_EXPLOSION
@ EFFECT_TR_NEHAHRASMOKE
@ EFFECT_TR_ROCKET
@ EFFECT_TE_GUNSHOT
@ EFFECT_TR_VORESPIKE
@ EFFECT_TR_GRENADE
@ EFFECT_TE_PLASMABURN
@ EFFECT_TE_TAREXPLOSION
@ EFFECT_TR_BLOOD
@ EFFECT_EF_FLAME
@ EFFECT_TE_LAVASPLASH
@ EFFECT_TE_TELEPORT
@ EFFECT_TE_SMALLFLASH
@ EFFECT_TE_KNIGHTSPIKE
@ EFFECT_TE_BLOOD
@ EFFECT_TE_TEI_PLASMAHIT
@ EFFECT_TR_NEXUIZPLASMA
@ EFFECT_TE_SUPERSPIKE
@ EFFECT_TE_TEI_G3
@ EFFECT_TR_KNIGHTSPIKE
@ EFFECT_TE_TEI_BIGEXPLOSION
@ EFFECT_TE_SPIKE
@ pt_static
@ pt_beam
gamemode_t gamemode
Definition com_game.c:26
@ GAME_GOODVSBAD2
Definition com_game.h:36
@ GAME_PRYDON
Definition com_game.h:44
void R_Stain(const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
Definition gl_rsurf.c:298
float VectorNormalizeLength(vec3_t v)
returns vector length
Definition mathlib.c:763
#define VectorSet(vec, x, y, z)
Definition mathlib.h:96
void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, double x, double y, double z, double pitch, double yaw, double roll, double scale)
Definition matrixlib.c:715
vec_t vec4_t[4]
Definition qtypes.h:72
float f
entity_persistent_t persistent
Definition client.h:474

References CL_AllocLightFlash(), cl_decals_newsystem_immediatebloodstain, CL_ImmediateBloodStain(), CL_NewParticle(), CL_NewParticlesFromEffectinfo(), CL_NewQuakeParticle(), CL_ParticleExplosion(), cl_particles, cl_particles_blood, cl_particles_blood_alpha, cl_particles_blood_bloodhack, cl_particles_bubbles, cl_particles_bulletimpacts, cl_particles_quake, cl_particles_quality, cl_particles_smoke, cl_particles_smoke_alpha, cl_particles_smoke_alphafade, cl_particles_sparks, CL_PointSuperContents, CL_Smoke(), CL_Sparks(), CL_SpawnDecalParticleForPoint(), color, Con_DPrintf(), count, dir, EFFECT_EF_FLAME, EFFECT_EF_STARDUST, EFFECT_SVC_PARTICLE, EFFECT_TE_BLOOD, EFFECT_TE_EXPLOSION, EFFECT_TE_EXPLOSIONQUAD, EFFECT_TE_FLAMEJET, EFFECT_TE_GUNSHOT, EFFECT_TE_GUNSHOTQUAD, EFFECT_TE_KNIGHTSPIKE, EFFECT_TE_LAVASPLASH, EFFECT_TE_PLASMABURN, EFFECT_TE_SMALLFLASH, EFFECT_TE_SPARK, EFFECT_TE_SPIKE, EFFECT_TE_SPIKEQUAD, EFFECT_TE_SUPERSPIKE, EFFECT_TE_SUPERSPIKEQUAD, EFFECT_TE_TAREXPLOSION, EFFECT_TE_TEI_BIGEXPLOSION, EFFECT_TE_TEI_G3, EFFECT_TE_TEI_PLASMAHIT, EFFECT_TE_TEI_SMOKE, EFFECT_TE_TELEPORT, EFFECT_TE_WIZSPIKE, EFFECT_TR_BLOOD, EFFECT_TR_GLOWTRAIL, EFFECT_TR_GRENADE, EFFECT_TR_KNIGHTSPIKE, EFFECT_TR_NEHAHRASMOKE, EFFECT_TR_NEXUIZPLASMA, EFFECT_TR_ROCKET, EFFECT_TR_SLIGHTBLOOD, EFFECT_TR_VORESPIKE, EFFECT_TR_WIZSPIKE, f, GAME_GOODVSBAD2, GAME_PRYDON, gamemode, i, cvar_t::integer, lhrandom, LIGHTFLAG_NORMALMODE, LIGHTFLAG_REALTIMEMODE, r_refdef_scene_t::lights, Matrix4x4_CreateFromQuakeEntity(), Matrix4x4_CreateTranslate(), MAX_DLIGHTS, NULL, r_refdef_scene_t::numlights, PARTICLE_BILLBOARD, PARTICLE_HBEAM, PARTICLE_SPARK, particleeffectname, particlepalette, PBLEND_ADD, PBLEND_ALPHA, PBLEND_INVMOD, entity_t::persistent, pt_alphastatic, pt_beam, pt_blood, pt_bubble, pt_smoke, pt_spark, pt_static, r, r_refdef, R_RTLight_Update(), R_Stain(), ramp3, r_refdef_t::scene, SUPERCONTENTS_SLIME, SUPERCONTENTS_WATER, r_refdef_scene_t::templights, tex_beam, tex_bloodparticle, tex_bubble, tex_bulletdecal, tex_particle, tex_smoke, entity_persistent_t::trail_time, cvar_t::value, Vector4Set, VectorLength, VectorLerp, VectorMA, VectorNormalize, VectorNormalizeLength(), VectorSet, and VectorSubtract.

Referenced by CL_NewParticlesFromEffectinfo().

◆ CL_ParticleEffectIndexForName()

int CL_ParticleEffectIndexForName ( const char * name)

Definition at line 481 of file cl_particles.c.

482{
483 int i;
484 for (i = 1;i < MAX_PARTICLEEFFECTNAME && particleeffectname[i][0];i++)
485 if (!strcmp(particleeffectname[i], name))
486 return i;
487 return 0;
488}
const GLchar * name
Definition glquake.h:601

References i, MAX_PARTICLEEFFECTNAME, name, and particleeffectname.

Referenced by VM_CL_particleeffectnum().

◆ CL_ParticleEffectNameForIndex()

const char * CL_ParticleEffectNameForIndex ( int i)

Definition at line 490 of file cl_particles.c.

491{
493 return NULL;
494 return particleeffectname[i];
495}

References i, MAX_PARTICLEEFFECTNAME, NULL, and particleeffectname.

◆ CL_ParticleExplosion()

void CL_ParticleExplosion ( const vec3_t org)

Definition at line 1939 of file cl_particles.c.

1940{
1941 int i;
1942 trace_t trace;
1943
1944 R_Stain(org, 96, 40, 40, 40, 64, 88, 88, 88, 64);
1945 CL_SpawnDecalParticleForPoint(org, 40, 48, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF);
1946
1948 {
1949 for (i = 0; i < 1024; i++)
1950 {
1951 int color;
1952 int r = rand()&3;
1953
1954 if (i & 1)
1955 {
1957
1959 org,
1960 pt_explode,
1961 color, color,
1962 0.05, // gravity
1963 org[0], org[1], org[2], // offset
1964 0, 0, 0, // velocity
1965 2, // air friction
1966 0, // liquid friction
1967 16, // origin jitter
1968 256, // velocity jitter
1969 5 // lifetime
1970 );
1971 }
1972 else
1973 {
1975
1977 org,
1979 color, color,
1980 0.05, // gravity
1981 org[0], org[1], org[2], // offset
1982 0, 0, 0, // velocity
1983 0, // air friction
1984 0, // liquid friction
1985 16, // origin jitter
1986 256, // velocity jitter
1987 5 // lifetime
1988 );
1989 }
1990 }
1991 }
1992 else
1993 {
1994 i = CL_PointSuperContents(org);
1996 {
1998 for (i = 0;i < 128 * cl_particles_quality.value;i++)
1999 CL_NewParticle(org, pt_bubble, 0x404040, 0x808080, tex_bubble, 2, 0, lhrandom(128, 255), 128, -0.125, 1.5, org[0], org[1], org[2], 0, 0, 0, 0.0625, 0.25, 16, 96, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
2000 }
2001 else
2002 {
2004 {
2005 for (i = 0;i < 512 * cl_particles_quality.value;i++)
2006 {
2007 int k = 0;
2008 vec3_t v, v2;
2009 do
2010 {
2012 VectorMA(org, 128, v2, v);
2013 trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value, true, false, NULL, false, false);
2014 }
2015 while (k++ < 16 && trace.fraction < 0.1f);
2016 VectorSubtract(trace.endpos, org, v2);
2017 VectorScale(v2, 2.0f, v2);
2018 CL_NewParticle(org, pt_spark, 0x903010, 0xFFD030, tex_particle, 1.0f, 0, lhrandom(0, 255), 512, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0, 0, 0, 0, true, 0, 1, PBLEND_ADD, PARTICLE_SPARK, -1, -1, -1, 1, 1, 0, 0, NULL);
2019 }
2020 }
2021 }
2022 }
2023
2025 R_NewExplosion(org);
2026}
cvar_t cl_particles_explosions_sparks
int ramp1[8]
cvar_t cl_particles_explosions_shell
int ramp2[8]
GLfloat GLfloat GLfloat v2
Definition glquake.h:747
#define VectorScale(in, scale, out)
Definition mathlib.h:111
void R_NewExplosion(const vec3_t org)

References CL_NewParticle(), CL_NewQuakeParticle(), cl_particles, cl_particles_bubbles, cl_particles_explosions_shell, cl_particles_explosions_sparks, cl_particles_quake, cl_particles_quality, cl_particles_sparks, CL_PointSuperContents, CL_SpawnDecalParticleForPoint(), CL_TraceLine(), collision_extendmovelength, color, trace_t::endpos, trace_t::fraction, i, cvar_t::integer, lhrandom, MOVE_NOMONSTERS, NULL, PARTICLE_BILLBOARD, PARTICLE_SPARK, particlepalette, PBLEND_ADD, pt_bubble, pt_explode, pt_explode2, pt_spark, r, R_NewExplosion(), R_Stain(), ramp1, ramp2, SUPERCONTENTS_SLIME, SUPERCONTENTS_SOLID, SUPERCONTENTS_WATER, tex_bubble, tex_bulletdecal, tex_particle, v, v2, cvar_t::value, VectorMA, VectorRandom, VectorScale, and VectorSubtract.

Referenced by CL_ParseTempEntity(), CL_ParticleEffect_Fallback(), and VM_CL_te_explosionrgb().

◆ CL_ParticleExplosion2()

void CL_ParticleExplosion2 ( const vec3_t org,
int colorStart,
int colorLength )

Definition at line 2034 of file cl_particles.c.

2035{
2036 int i, k;
2037 if (!cl_particles.integer) return;
2038
2039 for (i = 0;i < 512 * cl_particles_quality.value;i++)
2040 {
2041 k = particlepalette[colorStart + (i % colorLength)];
2043 CL_NewQuakeParticle(org, pt_alphastatic, k, k, 0, org[0], org[1], org[2], 0, 0, 0, -4, -4, 16, 256, 0.3);
2044 else
2045 CL_NewParticle(org, pt_alphastatic, k, k, tex_particle, lhrandom(0.5, 1.5), 0, 255, 512, 0, 0, org[0], org[1], org[2], 0, 0, 0, lhrandom(1.5, 3), lhrandom(1.5, 3), 8, 192, true, 0, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
2046 }
2047}

References CL_NewParticle(), CL_NewQuakeParticle(), cl_particles, cl_particles_quake, cl_particles_quality, i, cvar_t::integer, lhrandom, NULL, PARTICLE_BILLBOARD, particlepalette, PBLEND_ALPHA, pt_alphastatic, tex_particle, and cvar_t::value.

Referenced by CL_ParseTempEntity(), and VM_CL_te_explosion2().

◆ CL_ParticleRain()

void CL_ParticleRain ( const vec3_t mins,
const vec3_t maxs,
const vec3_t dir,
int count,
int colorbase,
int type )

Definition at line 2088 of file cl_particles.c.

2089{
2090 int k;
2091 float minz, maxz, lifetime = 30;
2092 float particle_size;
2093 vec3_t org;
2094
2095 if (!cl_particles.integer) return;
2096 if (dir[2] < 0) // falling
2097 {
2098 minz = maxs[2] + dir[2] * 0.1;
2099 maxz = maxs[2];
2100 if (cl.worldmodel)
2101 lifetime = (maxz - cl.worldmodel->normalmins[2]) / max(1, -dir[2]);
2102 }
2103 else // rising??
2104 {
2105 minz = mins[2];
2106 maxz = maxs[2] + dir[2] * 0.1;
2107 if (cl.worldmodel)
2108 lifetime = (cl.worldmodel->normalmaxs[2] - minz) / max(1, dir[2]);
2109 }
2110
2112
2113 switch(type)
2114 {
2115 case 0:
2116 if (!cl_particles_rain.integer) break;
2117
2118 count *= 4; // ick, this should be in the mod or maps?
2119 particle_size = (gamemode == GAME_GOODVSBAD2) ? 20 : 0.5;
2120
2121 while(count--)
2122 {
2123 k = particlepalette[colorbase + (rand()&3)];
2124 VectorSet(org, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz));
2125 CL_NewParticle(org, pt_rain, k, k, tex_particle, particle_size, 0, lhrandom(32, 64), 0, 0, -1, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 0, 0, 0, true, lifetime, 1, PBLEND_ADD, PARTICLE_SPARK, -1, -1, -1, 1, 1, 0, 0, NULL);
2126 }
2127 break;
2128 case 1:
2129 if (!cl_particles_snow.integer) break;
2130
2131 particle_size = (gamemode == GAME_GOODVSBAD2) ? 20 : 1.0;
2132
2133 while(count--)
2134 {
2135 k = particlepalette[colorbase + (rand()&3)];
2136 VectorSet(org, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz));
2137 CL_NewParticle(org, pt_snow, k, k, tex_particle, 1, 0, lhrandom(64, 128), 0, 0, -1, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 0, 0, 0, true, lifetime, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
2138 }
2139 break;
2140 default:
2141 Con_Printf ("CL_ParticleRain: unknown type %i (0 = rain, 1 = snow)\n", type);
2142 }
2143}
float particle_size
GLenum type
Definition glquake.h:656
#define max(A, B)
Definition mathlib.h:38
struct model_s * worldmodel
Definition client.h:934

References cl, CL_NewParticle(), cl_particles, cl_particles_quality, cl_particles_rain, cl_particles_snow, Con_Printf(), count, dir, GAME_GOODVSBAD2, gamemode, int(), cvar_t::integer, lhrandom, max, maxs, mins, NULL, PARTICLE_BILLBOARD, particle_size, PARTICLE_SPARK, particlepalette, PBLEND_ADD, pt_rain, pt_snow, tex_particle, type, cvar_t::value, VectorSet, and client_state_t::worldmodel.

Referenced by CL_ParseTempEntity(), VM_CL_te_particlerain(), and VM_CL_te_particlesnow().

◆ CL_Particles_Init()

void CL_Particles_Init ( void )

Definition at line 586 of file cl_particles.c.

587{
588 Cmd_AddCommand(CF_CLIENT, "pointfile", CL_ReadPointFile_f, "display point file produced by qbsp when a leak was detected in the map (a line leading through the leak hole, to an entity inside the level)");
589 Cmd_AddCommand(CF_CLIENT, "cl_particles_reloadeffects", CL_Particles_LoadEffectInfo_f, "reloads effectinfo.txt and maps/levelname_effectinfo.txt (where levelname is the current map) if parameter is given, loads from custom file (no levelname_effectinfo are loaded in this case)");
590
624}
cvar_t cl_particles_visculling
void CL_ReadPointFile_f(cmd_state_t *cmd)
cvar_t cl_particles_blood_decal_alpha
cvar_t cl_decals_newsystem_bloodsmears
cvar_t cl_particles_alpha
cvar_t cl_particles_blood_decal_scalemax
cvar_t cl_particles_collisions
cvar_t cl_particles_blood_decal_scalemin
cvar_t cl_particles_size
cvar_t cl_decals_models
cvar_t cl_decals_bias
cvar_t cl_decals_fadetime
cvar_t cl_decals_time
static void CL_Particles_LoadEffectInfo_f(cmd_state_t *cmd)
cvar_t cl_decals_newsystem_intensitymultiplier
cvar_t cl_decals_max
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599

References CF_CLIENT, cl_decals, cl_decals_bias, cl_decals_fadetime, cl_decals_max, cl_decals_models, cl_decals_newsystem_bloodsmears, cl_decals_newsystem_immediatebloodstain, cl_decals_newsystem_intensitymultiplier, cl_decals_time, cl_particles, cl_particles_alpha, cl_particles_blood, cl_particles_blood_alpha, cl_particles_blood_bloodhack, cl_particles_blood_decal_alpha, cl_particles_blood_decal_scalemax, cl_particles_blood_decal_scalemin, cl_particles_bubbles, cl_particles_bulletimpacts, cl_particles_collisions, cl_particles_explosions_shell, cl_particles_explosions_sparks, cl_particles_forcetraileffects, CL_Particles_LoadEffectInfo_f(), cl_particles_quake, cl_particles_quality, cl_particles_rain, cl_particles_size, cl_particles_smoke, cl_particles_smoke_alpha, cl_particles_smoke_alphafade, cl_particles_snow, cl_particles_sparks, cl_particles_visculling, CL_ReadPointFile_f(), Cmd_AddCommand(), and Cvar_RegisterVariable().

Referenced by CL_Init().

◆ CL_Particles_LoadEffectInfo()

static void CL_Particles_LoadEffectInfo ( const char * customfile)
static

Definition at line 538 of file cl_particles.c.

539{
540 int i;
541 int filepass;
542 unsigned char *filedata;
543 fs_offset_t filesize;
544 char filename[MAX_QPATH];
546 memset(particleeffectinfo, 0, sizeof(particleeffectinfo));
547 memset(particleeffectname, 0, sizeof(particleeffectname));
548 for (i = 0;i < EFFECT_TOTAL;i++)
550 for (filepass = 0;;filepass++)
551 {
552 if (filepass == 0)
553 {
554 if (customfile)
555 dp_strlcpy(filename, customfile, sizeof(filename));
556 else
557 dp_strlcpy(filename, "effectinfo.txt", sizeof(filename));
558 }
559 else if (filepass == 1)
560 {
561 if (!cl.worldbasename[0] || customfile)
562 continue;
563 dpsnprintf(filename, sizeof(filename), "%s_effectinfo.txt", cl.worldnamenoextension);
564 }
565 else
566 break;
567 filedata = FS_LoadFile(filename, tempmempool, true, &filesize);
568 if (!filedata)
569 continue;
570 CL_Particles_ParseEffectInfo((const char *)filedata, (const char *)filedata + filesize, filename);
571 Mem_Free(filedata);
572 }
573}
static const char * standardeffectnames[EFFECT_TOTAL]
static void CL_Particles_ParseEffectInfo(const char *textstart, const char *textend, const char *filename)
int numparticleeffectinfo
@ EFFECT_TOTAL
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
int64_t fs_offset_t
Definition fs.h:37
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
char worldbasename[MAX_QPATH]
Definition client.h:898
char worldnamenoextension[MAX_QPATH]
Definition client.h:900
mempool_t * tempmempool
Definition zone.c:794
#define Mem_Free(mem)
Definition zone.h:96

References cl, CL_Particles_ParseEffectInfo(), dp_strlcpy, dpsnprintf(), EFFECT_TOTAL, FS_LoadFile(), i, MAX_QPATH, Mem_Free, numparticleeffectinfo, particleeffectinfo, particleeffectname, standardeffectnames, tempmempool, client_state_t::worldbasename, and client_state_t::worldnamenoextension.

Referenced by CL_Particles_LoadEffectInfo_f(), r_part_newmap(), and r_part_start().

◆ CL_Particles_LoadEffectInfo_f()

static void CL_Particles_LoadEffectInfo_f ( cmd_state_t * cmd)
static

Definition at line 575 of file cl_particles.c.

576{
578}
static void CL_Particles_LoadEffectInfo(const char *customfile)
static int Cmd_Argc(cmd_state_t *cmd)
Definition cmd.h:249
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
Definition cmd.h:254
void cmd(string command,...)

References CL_Particles_LoadEffectInfo(), cmd(), Cmd_Argc(), Cmd_Argv(), and NULL.

Referenced by CL_Particles_Init().

◆ CL_Particles_ParseEffectInfo()

static void CL_Particles_ParseEffectInfo ( const char * textstart,
const char * textend,
const char * filename )
static

Definition at line 314 of file cl_particles.c.

315{
316 int arrayindex;
317 int argc;
318 int i;
319 int linenumber;
321 const char *text = textstart;
322 char argv[16][1024];
323 for (linenumber = 1;;linenumber++)
324 {
325 argc = 0;
326 for (arrayindex = 0;arrayindex < 16;arrayindex++)
327 argv[arrayindex][0] = 0;
328 for (;;)
329 {
330 if (!COM_ParseToken_Simple(&text, true, false, true))
331 return;
332 if (!strcmp(com_token, "\n"))
333 break;
334 if (argc < 16)
335 {
336 dp_strlcpy(argv[argc], com_token, sizeof(argv[argc]));
337 argc++;
338 }
339 }
340 if (argc < 1)
341 continue;
342#define checkparms(n) if (argc != (n)) {Con_Printf("%s:%i: error while parsing: %s given %i parameters, should be %i parameters\n", filename, linenumber, argv[0], argc, (n));break;}
343#define readints(array, n) checkparms(n+1);for (arrayindex = 0;arrayindex < argc - 1;arrayindex++) array[arrayindex] = strtol(argv[1+arrayindex], NULL, 0)
344#define readfloats(array, n) checkparms(n+1);for (arrayindex = 0;arrayindex < argc - 1;arrayindex++) array[arrayindex] = atof(argv[1+arrayindex])
345#define readint(var) checkparms(2);var = strtol(argv[1], NULL, 0)
346#define readfloat(var) checkparms(2);var = atof(argv[1])
347#define readbool(var) checkparms(2);var = strtol(argv[1], NULL, 0) != 0
348 if (!strcmp(argv[0], "effect"))
349 {
350 int effectnameindex;
351 checkparms(2);
353 {
354 Con_Printf("%s:%i: too many effects!\n", filename, linenumber);
355 break;
356 }
357 for (effectnameindex = 1;effectnameindex < MAX_PARTICLEEFFECTNAME;effectnameindex++)
358 {
359 if (particleeffectname[effectnameindex][0])
360 {
361 if (!strcmp(particleeffectname[effectnameindex], argv[1]))
362 break;
363 }
364 else
365 {
366 dp_strlcpy(particleeffectname[effectnameindex], argv[1], sizeof(particleeffectname[effectnameindex]));
367 break;
368 }
369 }
370 // if we run out of names, abort
371 if (effectnameindex == MAX_PARTICLEEFFECTNAME)
372 {
373 Con_Printf("%s:%i: too many effects!\n", filename, linenumber);
374 break;
375 }
376 for(i = 0; i < numparticleeffectinfo; ++i)
377 {
378 info = particleeffectinfo + i;
379 if(!(info->flags & PARTICLEEFFECT_DEFINED))
380 if(info->effectnameindex == effectnameindex)
381 break;
382 }
384 continue;
386 // copy entire info from baseline, then fix up the nameindex
388 info->effectnameindex = effectnameindex;
389 continue;
390 }
391 else if (info == NULL)
392 {
393 Con_Printf("%s:%i: command %s encountered before effect\n", filename, linenumber, argv[0]);
394 break;
395 }
396
398 if (!strcmp(argv[0], "countabsolute")) {readfloat(info->countabsolute);}
399 else if (!strcmp(argv[0], "count")) {readfloat(info->countmultiplier);}
400 else if (!strcmp(argv[0], "type"))
401 {
402 checkparms(2);
403 if (!strcmp(argv[1], "alphastatic")) info->particletype = pt_alphastatic;
404 else if (!strcmp(argv[1], "static")) info->particletype = pt_static;
405 else if (!strcmp(argv[1], "spark")) info->particletype = pt_spark;
406 else if (!strcmp(argv[1], "beam")) info->particletype = pt_beam;
407 else if (!strcmp(argv[1], "rain")) info->particletype = pt_rain;
408 else if (!strcmp(argv[1], "raindecal")) info->particletype = pt_raindecal;
409 else if (!strcmp(argv[1], "snow")) info->particletype = pt_snow;
410 else if (!strcmp(argv[1], "bubble")) info->particletype = pt_bubble;
411 else if (!strcmp(argv[1], "blood")) {info->particletype = pt_blood;info->gravity = 1;}
412 else if (!strcmp(argv[1], "smoke")) info->particletype = pt_smoke;
413 else if (!strcmp(argv[1], "decal")) info->particletype = pt_decal;
414 else if (!strcmp(argv[1], "entityparticle")) info->particletype = pt_entityparticle;
415 else Con_Printf("%s:%i: unrecognized particle type %s\n", filename, linenumber, argv[1]);
418 }
419 else if (!strcmp(argv[0], "blend"))
420 {
421 checkparms(2);
422 if (!strcmp(argv[1], "alpha")) info->blendmode = PBLEND_ALPHA;
423 else if (!strcmp(argv[1], "add")) info->blendmode = PBLEND_ADD;
424 else if (!strcmp(argv[1], "invmod")) info->blendmode = PBLEND_INVMOD;
425 else Con_Printf("%s:%i: unrecognized blendmode %s\n", filename, linenumber, argv[1]);
426 }
427 else if (!strcmp(argv[0], "orientation"))
428 {
429 checkparms(2);
430 if (!strcmp(argv[1], "billboard")) info->orientation = PARTICLE_BILLBOARD;
431 else if (!strcmp(argv[1], "spark")) info->orientation = PARTICLE_SPARK;
432 else if (!strcmp(argv[1], "oriented")) info->orientation = PARTICLE_ORIENTED_DOUBLESIDED;
433 else if (!strcmp(argv[1], "beam")) info->orientation = PARTICLE_HBEAM;
434 else Con_Printf("%s:%i: unrecognized orientation %s\n", filename, linenumber, argv[1]);
435 }
436 else if (!strcmp(argv[0], "color")) {readints(info->color, 2);}
437 else if (!strcmp(argv[0], "tex")) {readints(info->tex, 2);}
438 else if (!strcmp(argv[0], "size")) {readfloats(info->size, 2);}
439 else if (!strcmp(argv[0], "sizeincrease")) {readfloat(info->size[2]);}
440 else if (!strcmp(argv[0], "alpha")) {readfloats(info->alpha, 3);}
441 else if (!strcmp(argv[0], "time")) {readfloats(info->time, 2);}
442 else if (!strcmp(argv[0], "gravity")) {readfloat(info->gravity);}
443 else if (!strcmp(argv[0], "bounce")) {readfloat(info->bounce);}
444 else if (!strcmp(argv[0], "airfriction")) {readfloat(info->airfriction);}
445 else if (!strcmp(argv[0], "liquidfriction")) {readfloat(info->liquidfriction);}
446 else if (!strcmp(argv[0], "originoffset")) {readfloats(info->originoffset, 3);}
447 else if (!strcmp(argv[0], "relativeoriginoffset")) {readfloats(info->relativeoriginoffset, 3);}
448 else if (!strcmp(argv[0], "velocityoffset")) {readfloats(info->velocityoffset, 3);}
449 else if (!strcmp(argv[0], "relativevelocityoffset")) {readfloats(info->relativevelocityoffset, 3);}
450 else if (!strcmp(argv[0], "originjitter")) {readfloats(info->originjitter, 3);}
451 else if (!strcmp(argv[0], "velocityjitter")) {readfloats(info->velocityjitter, 3);}
452 else if (!strcmp(argv[0], "velocitymultiplier")) {readfloat(info->velocitymultiplier);}
453 else if (!strcmp(argv[0], "lightradius")) {readfloat(info->lightradiusstart);}
454 else if (!strcmp(argv[0], "lightradiusfade")) {readfloat(info->lightradiusfade);}
455 else if (!strcmp(argv[0], "lighttime")) {readfloat(info->lighttime);}
456 else if (!strcmp(argv[0], "lightcolor")) {readfloats(info->lightcolor, 3);}
457 else if (!strcmp(argv[0], "lightshadow")) {readbool(info->lightshadow);}
458 else if (!strcmp(argv[0], "lightcubemapnum")) {readint(info->lightcubemapnum);}
459 else if (!strcmp(argv[0], "lightcorona")) {readints(info->lightcorona, 2);}
460 else if (!strcmp(argv[0], "underwater")) {checkparms(1);info->flags |= PARTICLEEFFECT_UNDERWATER;}
461 else if (!strcmp(argv[0], "notunderwater")) {checkparms(1);info->flags |= PARTICLEEFFECT_NOTUNDERWATER;}
462 else if (!strcmp(argv[0], "trailspacing")) {readfloat(info->trailspacing);if (info->trailspacing > 0) info->countmultiplier = 1.0f / info->trailspacing;}
463 else if (!strcmp(argv[0], "stretchfactor")) {readfloat(info->stretchfactor);}
464 else if (!strcmp(argv[0], "staincolor")) {readints(info->staincolor, 2);}
465 else if (!strcmp(argv[0], "stainalpha")) {readfloats(info->stainalpha, 2);}
466 else if (!strcmp(argv[0], "stainsize")) {readfloats(info->stainsize, 2);}
467 else if (!strcmp(argv[0], "staintex")) {readints(info->staintex, 2);}
468 else if (!strcmp(argv[0], "stainless")) {info->staintex[0] = -2; info->staincolor[0] = (unsigned int)-1; info->staincolor[1] = (unsigned int)-1; info->stainalpha[0] = 1; info->stainalpha[1] = 1; info->stainsize[0] = 2; info->stainsize[1] = 2; }
469 else if (!strcmp(argv[0], "rotate")) {readfloats(info->rotate, 4);}
470 else if (!strcmp(argv[0], "forcenearest")) {checkparms(1);info->flags |= PARTICLEEFFECT_FORCENEAREST;}
471 else
472 Con_Printf("%s:%i: skipping unknown command %s\n", filename, linenumber, argv[0]);
473#undef checkparms
474#undef readints
475#undef readfloats
476#undef readint
477#undef readfloat
478 }
479}
#define readints(array, n)
#define readint(var)
particleeffectinfo_t baselineparticleeffectinfo
particletype_t particletype[pt_total]
#define readfloats(array, n)
#define readbool(var)
#define readfloat(var)
#define PARTICLEEFFECT_FORCENEAREST
char com_token[MAX_INPUTLINE]
Definition common.c:39
qbool COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
Definition common.c:463
porientation_t orientation
pblend_t blendmode

References particleeffectinfo_t::airfriction, particleeffectinfo_t::alpha, argv(), baselineparticleeffectinfo, particleeffectinfo_t::blendmode, particletype_t::blendmode, particleeffectinfo_t::bounce, checkparms, particleeffectinfo_t::color, COM_ParseToken_Simple(), com_token, Con_Printf(), particleeffectinfo_t::countabsolute, particleeffectinfo_t::countmultiplier, dp_strlcpy, particleeffectinfo_t::effectnameindex, particleeffectinfo_t::flags, particleeffectinfo_t::gravity, i, int(), particleeffectinfo_t::lightcolor, particleeffectinfo_t::lightcorona, particleeffectinfo_t::lightcubemapnum, particleeffectinfo_t::lightradiusfade, particleeffectinfo_t::lightradiusstart, particleeffectinfo_t::lightshadow, particleeffectinfo_t::lighttime, particleeffectinfo_t::liquidfriction, MAX_PARTICLEEFFECTINFO, MAX_PARTICLEEFFECTNAME, NULL, numparticleeffectinfo, particleeffectinfo_t::orientation, particletype_t::orientation, particleeffectinfo_t::originjitter, particleeffectinfo_t::originoffset, PARTICLE_BILLBOARD, PARTICLE_HBEAM, PARTICLE_ORIENTED_DOUBLESIDED, PARTICLE_SPARK, PARTICLEEFFECT_DEFINED, PARTICLEEFFECT_FORCENEAREST, PARTICLEEFFECT_NOTUNDERWATER, PARTICLEEFFECT_UNDERWATER, particleeffectinfo, particleeffectname, particleeffectinfo_t::particletype, particletype, PBLEND_ADD, PBLEND_ALPHA, PBLEND_INVMOD, pt_alphastatic, pt_beam, pt_blood, pt_bubble, pt_decal, pt_entityparticle, pt_rain, pt_raindecal, pt_smoke, pt_snow, pt_spark, pt_static, readbool, readfloat, readfloats, readint, readints, particleeffectinfo_t::relativeoriginoffset, particleeffectinfo_t::relativevelocityoffset, particleeffectinfo_t::rotate, particleeffectinfo_t::size, particleeffectinfo_t::stainalpha, particleeffectinfo_t::staincolor, particleeffectinfo_t::stainsize, particleeffectinfo_t::staintex, particleeffectinfo_t::stretchfactor, particleeffectinfo_t::tex, particleeffectinfo_t::time, particleeffectinfo_t::trailspacing, particleeffectinfo_t::velocityjitter, particleeffectinfo_t::velocitymultiplier, and particleeffectinfo_t::velocityoffset.

Referenced by CL_Particles_LoadEffectInfo().

◆ CL_Particles_Shutdown()

void CL_Particles_Shutdown ( void )

Definition at line 626 of file cl_particles.c.

627{
628}

Referenced by CL_Shutdown().

◆ CL_ParticleTrail()

void CL_ParticleTrail ( int effectnameindex,
float pcount,
const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
entity_t * ent,
int palettecolor,
qbool spawndlight,
qbool spawnparticles,
float tintmins[4],
float tintmaxs[4],
float fade )

Definition at line 1790 of file cl_particles.c.

1791{
1792 CL_NewParticlesFromEffectinfo(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, tintmins, tintmaxs, fade, true);
1793}

References CL_NewParticlesFromEffectinfo().

Referenced by CL_LinkNetworkEntity(), CL_ParseTempEntity(), CL_ParseTrailParticles(), CL_UpdateNetworkEntityTrail(), VM_CL_boxparticles(), and VM_CL_trailparticles().

◆ CL_ReadPointFile_f()

void CL_ReadPointFile_f ( cmd_state_t * cmd)

Definition at line 1839 of file cl_particles.c.

1840{
1841 double org[3], leakorg[3];
1842 vec3_t vecorg;
1843 int r, c, s;
1844 char *pointfile = NULL, *pointfilepos, *t, tchar;
1845 char name[MAX_QPATH];
1846
1847 if (!cl.worldmodel)
1848 return;
1849
1850 dpsnprintf(name, sizeof(name), "%s.pts", cl.worldnamenoextension);
1851 pointfile = (char *)FS_LoadFile(name, tempmempool, true, NULL);
1852 if (!pointfile)
1853 {
1854 Con_Printf("Could not open %s\n", name);
1855 return;
1856 }
1857
1858 Con_Printf("Reading %s...\n", name);
1859 VectorClear(leakorg);
1860 c = 0;
1861 s = 0;
1862 pointfilepos = pointfile;
1863 while (*pointfilepos)
1864 {
1865 while (*pointfilepos == '\n' || *pointfilepos == '\r')
1866 pointfilepos++;
1867 if (!*pointfilepos)
1868 break;
1869 t = pointfilepos;
1870 while (*t && *t != '\n' && *t != '\r')
1871 t++;
1872 tchar = *t;
1873 *t = 0;
1874#if _MSC_VER >= 1400
1875#define sscanf sscanf_s
1876#endif
1877 r = sscanf (pointfilepos,"%lf %lf %lf", &org[0], &org[1], &org[2]);
1878 VectorCopy(org, vecorg);
1879 *t = tchar;
1880 pointfilepos = t;
1881 if (r != 3)
1882 break;
1883 if (c == 0)
1884 VectorCopy(org, leakorg);
1885 c++;
1886
1887 if (cl.num_particles < cl.max_particles - 3)
1888 {
1889 s++;
1890 CL_NewParticle(vecorg, pt_alphastatic, particlepalette[(-c)&15], particlepalette[(-c)&15], tex_particle, 2, 0, 255, 0, 0, 0, org[0], org[1], org[2], 0, 0, 0, 0, 0, 0, 0, true, 1<<30, 1, PBLEND_ALPHA, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
1891 }
1892 }
1893 Mem_Free(pointfile);
1894 VectorCopy(leakorg, vecorg);
1895 Con_Printf("%i points read (%i particles spawned)\nLeak at %f %f %f\n", c, s, leakorg[0], leakorg[1], leakorg[2]);
1896
1897 if (c == 0)
1898 {
1899 return;
1900 }
1901
1902 CL_NewParticle(vecorg, pt_beam, 0xFF0000, 0xFF0000, tex_beam, 64, 0, 255, 0, 0, 0, org[0] - 4096, org[1], org[2], org[0] + 4096, org[1], org[2], 0, 0, 0, 0, false, 1<<30, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL);
1903 CL_NewParticle(vecorg, pt_beam, 0x00FF00, 0x00FF00, tex_beam, 64, 0, 255, 0, 0, 0, org[0], org[1] - 4096, org[2], org[0], org[1] + 4096, org[2], 0, 0, 0, 0, false, 1<<30, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL);
1904 CL_NewParticle(vecorg, pt_beam, 0x0000FF, 0x0000FF, tex_beam, 64, 0, 255, 0, 0, 0, org[0], org[1], org[2] - 4096, org[0], org[1], org[2] + 4096, 0, 0, 0, 0, false, 1<<30, 1, PBLEND_ADD, PARTICLE_HBEAM, -1, -1, -1, 1, 1, 0, 0, NULL);
1905}
#define VectorClear(a)
Definition mathlib.h:97

References cl, CL_NewParticle(), Con_Printf(), dpsnprintf(), FS_LoadFile(), client_state_t::max_particles, MAX_QPATH, Mem_Free, name, NULL, client_state_t::num_particles, PARTICLE_BILLBOARD, PARTICLE_HBEAM, particlepalette, PBLEND_ADD, PBLEND_ALPHA, pt_alphastatic, pt_beam, r, tempmempool, tex_beam, tex_particle, VectorClear, VectorCopy, client_state_t::worldmodel, and client_state_t::worldnamenoextension.

Referenced by CL_Particles_Init().

◆ CL_Smoke()

static void CL_Smoke ( const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
float smokecount )
static

Definition at line 2061 of file cl_particles.c.

2062{
2063 vec3_t center;
2064 VectorMAM(0.5f, originmins, 0.5f, originmaxs, center);
2066 {
2067 smokecount *= cl_particles_quality.value;
2068 while(smokecount-- > 0)
2069 CL_NewParticle(center, pt_smoke, 0x101010, 0x101010, tex_smoke[rand()&7], 2, 2, 255, 256, 0, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]), 0, 0, 0, smokecount > 0 ? 16 : 0, true, 0, 1, PBLEND_ADD, PARTICLE_BILLBOARD, -1, -1, -1, 1, 1, 0, 0, NULL);
2070 }
2071}

References CL_NewParticle(), cl_particles_quality, cl_particles_smoke, cvar_t::integer, lhrandom, NULL, PARTICLE_BILLBOARD, PBLEND_ADD, pt_smoke, tex_smoke, cvar_t::value, and VectorMAM.

Referenced by CL_ParticleEffect_Fallback().

◆ CL_Sparks()

static void CL_Sparks ( const vec3_t originmins,
const vec3_t originmaxs,
const vec3_t velocitymins,
const vec3_t velocitymaxs,
float sparkcount )
static

Definition at line 2049 of file cl_particles.c.

2050{
2051 vec3_t center;
2052 VectorMAM(0.5f, originmins, 0.5f, originmaxs, center);
2054 {
2055 sparkcount *= cl_particles_quality.value;
2056 while(sparkcount-- > 0)
2057 CL_NewParticle(center, pt_spark, particlepalette[0x68], particlepalette[0x6f], tex_particle, 0.5f, 0, lhrandom(64, 255), 512, 1, 0, lhrandom(originmins[0], originmaxs[0]), lhrandom(originmins[1], originmaxs[1]), lhrandom(originmins[2], originmaxs[2]), lhrandom(velocitymins[0], velocitymaxs[0]), lhrandom(velocitymins[1], velocitymaxs[1]), lhrandom(velocitymins[2], velocitymaxs[2]) + cl.movevars_gravity * 0.1f, 0, 0, 0, 64, true, 0, 1, PBLEND_ADD, PARTICLE_SPARK, -1, -1, -1, 1, 1, 0, 0, NULL);
2058 }
2059}

References cl, CL_NewParticle(), cl_particles_quality, cl_particles_sparks, cvar_t::integer, lhrandom, client_state_t::movevars_gravity, NULL, PARTICLE_SPARK, particlepalette, PBLEND_ADD, pt_spark, tex_particle, cvar_t::value, and VectorMAM.

Referenced by CL_ParticleEffect_Fallback().

◆ CL_SpawnDecalParticleForPoint()

void CL_SpawnDecalParticleForPoint ( const vec3_t org,
float maxdist,
float size,
float alpha,
int texnum,
int color1,
int color2 )

Definition at line 981 of file cl_particles.c.

982{
983 int i;
984 vec_t bestfrac;
985 vec3_t bestorg;
986 vec3_t bestnormal;
987 vec3_t org2;
988 int besthitent = 0, hitent;
989 trace_t trace;
990 bestfrac = 10;
991 for (i = 0;i < 32;i++)
992 {
993 VectorRandom(org2);
994 VectorMA(org, maxdist, org2, org2);
995 trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, 0, collision_extendmovelength.value, true, false, &hitent, false, true);
996 // take the closest trace result that doesn't end up hitting a NOMARKS
997 // surface (sky for example)
998 if (bestfrac > trace.fraction && !(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS))
999 {
1000 bestfrac = trace.fraction;
1001 besthitent = hitent;
1002 VectorCopy(trace.endpos, bestorg);
1003 VectorCopy(trace.plane.normal, bestnormal);
1004 }
1005 }
1006 if (bestfrac < 1)
1007 CL_SpawnDecalParticleForSurface(besthitent, bestorg, bestnormal, color1, color2, texnum, size, alpha);
1008}
#define SUPERCONTENTS_SKY
Definition bspfile.h:200
void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t normal, int color1, int color2, int texnum, float size, float alpha)
vector size
float alpha
#define Q3SURFACEFLAG_NOMARKS
int hitq3surfaceflags
Definition collision.h:60

References alpha, CL_SpawnDecalParticleForSurface(), CL_TraceLine(), collision_extendmovelength, trace_t::endpos, trace_t::fraction, trace_t::hitq3surfaceflags, i, MOVE_NOMONSTERS, plane_t::normal, NULL, trace_t::plane, Q3SURFACEFLAG_NOMARKS, size, SUPERCONTENTS_SKY, SUPERCONTENTS_SOLID, cvar_t::value, VectorCopy, VectorMA, and VectorRandom.

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleEffect_Fallback(), and CL_ParticleExplosion().

◆ CL_SpawnDecalParticleForSurface()

void CL_SpawnDecalParticleForSurface ( int hitent,
const vec3_t org,
const vec3_t normal,
int color1,
int color2,
int texnum,
float size,
float alpha )

Definition at line 959 of file cl_particles.c.

960{
961 int l1, l2;
962 entity_render_t *ent = &cl.entities[hitent].render;
963 unsigned char color[3];
964 if (!cl_decals.integer)
965 return;
966 if (!ent->allowdecals)
967 return;
968
969 l2 = (int)lhrandom(0.5, 256.5);
970 l1 = 256 - l2;
971 color[0] = ((((color1 >> 16) & 0xFF) * l1 + ((color2 >> 16) & 0xFF) * l2) >> 8) & 0xFF;
972 color[1] = ((((color1 >> 8) & 0xFF) * l1 + ((color2 >> 8) & 0xFF) * l2) >> 8) & 0xFF;
973 color[2] = ((((color1 >> 0) & 0xFF) * l1 + ((color2 >> 0) & 0xFF) * l2) >> 8) & 0xFF;
974
975 if (vid.sRGB3D)
977 else
978 R_DecalSystem_SplatEntities(org, normal, color[0]*(1.0f/255.0f), color[1]*(1.0f/255.0f), color[2]*(1.0f/255.0f), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size);
979}
vec3 normal
entity_t * entities
Definition client.h:991

References entity_render_t::allowdecals, alpha, cl, cl_decals, color, client_state_t::entities, Image_LinearFloatFromsRGB, int(), cvar_t::integer, lhrandom, normal, particletexture, R_DecalSystem_SplatEntities(), entity_t::render, size, viddef_t::sRGB3D, and vid.

Referenced by CL_SpawnDecalParticleForPoint(), and R_DrawParticles().

◆ LightCubemapNumToName()

static char * LightCubemapNumToName ( char * vabuf,
size_t vasize,
int lightcubemapnum,
int flags )
static

Definition at line 1011 of file cl_particles.c.

1012{
1013 if (lightcubemapnum <= 0)
1014 return NULL;
1015 // `!` is prepended if the cubemap must be nearest-filtered
1017 return va(vabuf, vasize, "!cubemaps/%i", lightcubemapnum);
1018 return va(vabuf, vasize, "cubemaps/%i", lightcubemapnum);
1019}
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
float flags

References flags, NULL, PARTICLEEFFECT_FORCENEAREST, and va().

Referenced by CL_NewParticlesFromEffectinfo().

◆ particletextureblotch()

static void particletextureblotch ( unsigned char * data,
float radius,
float red,
float green,
float blue,
float alpha )
static

Definition at line 2207 of file cl_particles.c.

2208{
2209 int x, y;
2210 float cx, cy, dx, dy, f, iradius;
2211 unsigned char *d;
2212 cx = (lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius) + lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius)) * 0.5f;
2213 cy = (lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius) + lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius)) * 0.5f;
2214 iradius = 1.0f / radius;
2215 alpha *= (1.0f / 255.0f);
2216 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2217 {
2218 for (x = 0;x < PARTICLETEXTURESIZE;x++)
2219 {
2220 dx = (x - cx);
2221 dy = (y - cy);
2222 f = (1.0f - sqrt(dx * dx + dy * dy) * iradius) * alpha;
2223 if (f > 0)
2224 {
2225 if (f > 1)
2226 f = 1;
2227 d = data + (y * PARTICLETEXTURESIZE + x) * 4;
2228 d[0] += (int)(f * (blue - d[0]));
2229 d[1] += (int)(f * (green - d[1]));
2230 d[2] += (int)(f * (red - d[2]));
2231 }
2232 }
2233 }
2234}
#define PARTICLETEXTURESIZE
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
GLsizeiptr const GLvoid * data
Definition glquake.h:639
GLclampf GLclampf blue
Definition glquake.h:642
GLclampf green
Definition glquake.h:642
float sqrt(float f)

References alpha, blue, data, f, green, int(), lhrandom, PARTICLETEXTURESIZE, sqrt(), x, and y.

Referenced by R_InitBloodTextures(), and R_InitParticleTexture().

◆ particletextureinvert()

static void particletextureinvert ( unsigned char * data)
static

Definition at line 2249 of file cl_particles.c.

2250{
2251 int i;
2252 for (i = 0;i < PARTICLETEXTURESIZE*PARTICLETEXTURESIZE;i++, data += 4)
2253 {
2254 data[0] = 255 - data[0];
2255 data[1] = 255 - data[1];
2256 data[2] = 255 - data[2];
2257 }
2258}

References data, i, and PARTICLETEXTURESIZE.

Referenced by R_InitBloodTextures(), and R_InitParticleTexture().

◆ R_DrawParticle_TransparentCallback()

static void R_DrawParticle_TransparentCallback ( const entity_render_t * ent,
const rtlight_t * rtlight,
int numsurfaces,
int * surfacelist )
static

Definition at line 2624 of file cl_particles.c.

2625{
2626 vec3_t vecorg, vecvel, baseright, baseup;
2627 int surfacelistindex;
2628 int batchstart, batchcount;
2629 const particle_t *p;
2630 pblend_t blendmode;
2632 float *v3f, *t2f, *c4f;
2633 particletexture_t *tex;
2634 float up2[3], v[3], right[3], up[3], fog, ifog, size, len, lenfactor, alpha;
2635// float ambient[3], diffuse[3], diffusenormal[3];
2636 float palpha, spintime, spinrad, spincos, spinsin, spinm1, spinm2, spinm3, spinm4;
2637 vec4_t colormultiplier;
2638 float minparticledist_start, minparticledist_end;
2639 qbool dofade;
2640
2641 RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false);
2642
2643 Vector4Set(colormultiplier, r_refdef.view.colorscale * (1.0 / 256.0f), r_refdef.view.colorscale * (1.0 / 256.0f), r_refdef.view.colorscale * (1.0 / 256.0f), cl_particles_alpha.value * (1.0 / 256.0f));
2644
2645 r_refdef.stats[r_stat_particles] += numsurfaces;
2646// R_Mesh_ResetTextureState();
2647 GL_DepthMask(false);
2648 GL_DepthRange(0, 1);
2649 GL_PolygonOffset(0, 0);
2650 GL_DepthTest(true);
2652
2653 spintime = r_refdef.scene.time;
2654
2657 dofade = (minparticledist_start < minparticledist_end);
2658
2659 // first generate all the vertices at once
2660 for (surfacelistindex = 0, v3f = particle_vertex3f, t2f = particle_texcoord2f, c4f = particle_color4f;surfacelistindex < numsurfaces;surfacelistindex++, v3f += 3*4, t2f += 2*4, c4f += 4*4)
2661 {
2662 p = cl.particles + surfacelist[surfacelistindex];
2663
2664 blendmode = (pblend_t)p->blendmode;
2665 palpha = p->alpha;
2666 if(dofade && p->orientation != PARTICLE_VBEAM && p->orientation != PARTICLE_HBEAM)
2667 palpha *= min(1, (DotProduct(p->org, r_refdef.view.forward) - minparticledist_start) / (minparticledist_end - minparticledist_start));
2668 alpha = palpha * colormultiplier[3];
2669 // ensure alpha multiplier saturates properly
2670 if (alpha > 1.0f)
2671 alpha = 1.0f;
2672
2673 switch (blendmode)
2674 {
2675 case PBLEND_INVALID:
2676 case PBLEND_INVMOD:
2677 // additive and modulate can just fade out in fog (this is correct)
2678 if (r_refdef.fogenabled)
2679 alpha *= RSurf_FogVertex(p->org);
2680 // collapse alpha into color for these blends (so that the particlefont does not need alpha on most textures)
2681 alpha *= 1.0f / 256.0f;
2682 c4f[0] = p->color[0] * alpha;
2683 c4f[1] = p->color[1] * alpha;
2684 c4f[2] = p->color[2] * alpha;
2685 c4f[3] = 0;
2686 break;
2687 case PBLEND_ADD:
2688 // additive and modulate can just fade out in fog (this is correct)
2689 if (r_refdef.fogenabled)
2690 alpha *= RSurf_FogVertex(p->org);
2691 // collapse alpha into color for these blends (so that the particlefont does not need alpha on most textures)
2692 c4f[0] = p->color[0] * colormultiplier[0] * alpha;
2693 c4f[1] = p->color[1] * colormultiplier[1] * alpha;
2694 c4f[2] = p->color[2] * colormultiplier[2] * alpha;
2695 c4f[3] = 0;
2696 break;
2697 case PBLEND_ALPHA:
2698 c4f[0] = p->color[0] * colormultiplier[0];
2699 c4f[1] = p->color[1] * colormultiplier[1];
2700 c4f[2] = p->color[2] * colormultiplier[2];
2701 c4f[3] = alpha;
2702 // note: lighting is not cheap!
2704 {
2705 float a[3], c[3], dir[3];
2706 vecorg[0] = p->org[0];
2707 vecorg[1] = p->org[1];
2708 vecorg[2] = p->org[2];
2710 c4f[0] = p->color[0] * colormultiplier[0] * (a[0] + 0.25f * c[0]);
2711 c4f[1] = p->color[1] * colormultiplier[1] * (a[1] + 0.25f * c[1]);
2712 c4f[2] = p->color[2] * colormultiplier[2] * (a[2] + 0.25f * c[2]);
2713 }
2714 // mix in the fog color
2715 if (r_refdef.fogenabled)
2716 {
2717 fog = RSurf_FogVertex(p->org);
2718 ifog = 1 - fog;
2719 c4f[0] = c4f[0] * fog + r_refdef.fogcolor[0] * ifog;
2720 c4f[1] = c4f[1] * fog + r_refdef.fogcolor[1] * ifog;
2721 c4f[2] = c4f[2] * fog + r_refdef.fogcolor[2] * ifog;
2722 }
2723 // for premultiplied alpha we have to apply the alpha to the color (after fog of course)
2724 VectorScale(c4f, alpha, c4f);
2725 break;
2726 }
2727 // copy the color into the other three vertices
2728 Vector4Copy(c4f, c4f + 4);
2729 Vector4Copy(c4f, c4f + 8);
2730 Vector4Copy(c4f, c4f + 12);
2731
2733 tex = &particletexture[p->texnum];
2734 switch(p->orientation)
2735 {
2736// case PARTICLE_INVALID:
2737 case PARTICLE_BILLBOARD:
2738 if (p->angle + p->spin)
2739 {
2740 spinrad = (p->angle + p->spin * (spintime - p->delayedspawn)) * (float)(M_PI / 180.0f);
2741 spinsin = sin(spinrad) * size;
2742 spincos = cos(spinrad) * size;
2743 spinm1 = -p->stretch * spincos;
2744 spinm2 = -spinsin;
2745 spinm3 = spinsin;
2746 spinm4 = -p->stretch * spincos;
2747 VectorMAM(spinm1, r_refdef.view.left, spinm2, r_refdef.view.up, right);
2748 VectorMAM(spinm3, r_refdef.view.left, spinm4, r_refdef.view.up, up);
2749 }
2750 else
2751 {
2754 }
2755
2756 v3f[ 0] = p->org[0] - right[0] - up[0];
2757 v3f[ 1] = p->org[1] - right[1] - up[1];
2758 v3f[ 2] = p->org[2] - right[2] - up[2];
2759 v3f[ 3] = p->org[0] - right[0] + up[0];
2760 v3f[ 4] = p->org[1] - right[1] + up[1];
2761 v3f[ 5] = p->org[2] - right[2] + up[2];
2762 v3f[ 6] = p->org[0] + right[0] + up[0];
2763 v3f[ 7] = p->org[1] + right[1] + up[1];
2764 v3f[ 8] = p->org[2] + right[2] + up[2];
2765 v3f[ 9] = p->org[0] + right[0] - up[0];
2766 v3f[10] = p->org[1] + right[1] - up[1];
2767 v3f[11] = p->org[2] + right[2] - up[2];
2768 t2f[0] = tex->s1;t2f[1] = tex->t2;
2769 t2f[2] = tex->s1;t2f[3] = tex->t1;
2770 t2f[4] = tex->s2;t2f[5] = tex->t1;
2771 t2f[6] = tex->s2;t2f[7] = tex->t2;
2772 break;
2774 vecvel[0] = p->vel[0];
2775 vecvel[1] = p->vel[1];
2776 vecvel[2] = p->vel[2];
2777 VectorVectors(vecvel, baseright, baseup);
2778 if (p->angle + p->spin)
2779 {
2780 spinrad = (p->angle + p->spin * (spintime - p->delayedspawn)) * (float)(M_PI / 180.0f);
2781 spinsin = sin(spinrad) * size;
2782 spincos = cos(spinrad) * size;
2783 spinm1 = p->stretch * spincos;
2784 spinm2 = -spinsin;
2785 spinm3 = spinsin;
2786 spinm4 = p->stretch * spincos;
2787 VectorMAM(spinm1, baseright, spinm2, baseup, right);
2788 VectorMAM(spinm3, baseright, spinm4, baseup, up);
2789 }
2790 else
2791 {
2792 VectorScale(baseright, size * p->stretch, right);
2793 VectorScale(baseup, size, up);
2794 }
2795 v3f[ 0] = p->org[0] - right[0] - up[0];
2796 v3f[ 1] = p->org[1] - right[1] - up[1];
2797 v3f[ 2] = p->org[2] - right[2] - up[2];
2798 v3f[ 3] = p->org[0] - right[0] + up[0];
2799 v3f[ 4] = p->org[1] - right[1] + up[1];
2800 v3f[ 5] = p->org[2] - right[2] + up[2];
2801 v3f[ 6] = p->org[0] + right[0] + up[0];
2802 v3f[ 7] = p->org[1] + right[1] + up[1];
2803 v3f[ 8] = p->org[2] + right[2] + up[2];
2804 v3f[ 9] = p->org[0] + right[0] - up[0];
2805 v3f[10] = p->org[1] + right[1] - up[1];
2806 v3f[11] = p->org[2] + right[2] - up[2];
2807 t2f[0] = tex->s1;t2f[1] = tex->t2;
2808 t2f[2] = tex->s1;t2f[3] = tex->t1;
2809 t2f[4] = tex->s2;t2f[5] = tex->t1;
2810 t2f[6] = tex->s2;t2f[7] = tex->t2;
2811 break;
2812 case PARTICLE_SPARK:
2813 len = VectorLength(p->vel);
2814 VectorNormalize2(p->vel, up);
2815 lenfactor = p->stretch * 0.04 * len;
2816 if(lenfactor < size * 0.5)
2817 lenfactor = size * 0.5;
2818 VectorMA(p->org, -lenfactor, up, v);
2819 VectorMA(p->org, lenfactor, up, up2);
2820 R_CalcBeam_Vertex3f(v3f, v, up2, size);
2821 t2f[0] = tex->s1;t2f[1] = tex->t2;
2822 t2f[2] = tex->s1;t2f[3] = tex->t1;
2823 t2f[4] = tex->s2;t2f[5] = tex->t1;
2824 t2f[6] = tex->s2;t2f[7] = tex->t2;
2825 break;
2826 case PARTICLE_VBEAM:
2827 R_CalcBeam_Vertex3f(v3f, p->org, p->vel, size);
2828 VectorSubtract(p->vel, p->org, up);
2830 v[0] = DotProduct(p->org, up) * (1.0f / 64.0f) * p->stretch;
2831 v[1] = DotProduct(p->vel, up) * (1.0f / 64.0f) * p->stretch;
2832 t2f[0] = tex->s2;t2f[1] = v[0];
2833 t2f[2] = tex->s1;t2f[3] = v[0];
2834 t2f[4] = tex->s1;t2f[5] = v[1];
2835 t2f[6] = tex->s2;t2f[7] = v[1];
2836 break;
2837 case PARTICLE_HBEAM:
2838 R_CalcBeam_Vertex3f(v3f, p->org, p->vel, size);
2839 VectorSubtract(p->vel, p->org, up);
2841 v[0] = DotProduct(p->org, up) * (1.0f / 64.0f) * p->stretch;
2842 v[1] = DotProduct(p->vel, up) * (1.0f / 64.0f) * p->stretch;
2843 t2f[0] = v[0];t2f[1] = tex->t1;
2844 t2f[2] = v[0];t2f[3] = tex->t2;
2845 t2f[4] = v[1];t2f[5] = tex->t2;
2846 t2f[6] = v[1];t2f[7] = tex->t1;
2847 break;
2848 }
2850 {
2851 R_DebugLine(v3f, v3f + 3);
2852 R_DebugLine(v3f + 3, v3f + 6);
2853 R_DebugLine(v3f + 6, v3f + 9);
2854 R_DebugLine(v3f + 9, v3f);
2855 }
2856 }
2857
2858 // now render batches of particles based on blendmode and texture
2859 blendmode = PBLEND_INVALID;
2860 texture = NULL;
2861 batchstart = 0;
2862 batchcount = 0;
2864 for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
2865 {
2866 p = cl.particles + surfacelist[surfacelistindex];
2867
2869 {
2871 R_SetupShader_Generic(texture, false, false, false);
2872 }
2873
2874 if (p->blendmode == PBLEND_INVMOD)
2875 {
2876 // inverse modulate blend - group these
2878 // iterate until we find a change in settings
2879 batchstart = surfacelistindex++;
2880 for (;surfacelistindex < numsurfaces;surfacelistindex++)
2881 {
2882 p = cl.particles + surfacelist[surfacelistindex];
2884 break;
2885 }
2886 }
2887 else
2888 {
2889 // additive or alpha blend - group these
2890 // (we can group these because we premultiplied the texture alpha)
2892 // iterate until we find a change in settings
2893 batchstart = surfacelistindex++;
2894 for (;surfacelistindex < numsurfaces;surfacelistindex++)
2895 {
2896 p = cl.particles + surfacelist[surfacelistindex];
2898 break;
2899 }
2900 }
2901
2902 batchcount = surfacelistindex - batchstart;
2903 R_Mesh_Draw(batchstart * 4, batchcount * 4, batchstart * 2, batchcount * 2, NULL, NULL, 0, particle_elements, NULL, 0);
2904 }
2905}
float particle_color4f[MESHQUEUE_TRANSPARENT_BATCHSIZE *16]
float particle_vertex3f[MESHQUEUE_TRANSPARENT_BATCHSIZE *12]
static cvar_t r_drawparticles_nearclip_min
float particle_texcoord2f[MESHQUEUE_TRANSPARENT_BATCHSIZE *8]
static cvar_t r_drawparticles_nearclip_max
unsigned short particle_elements[MESHQUEUE_TRANSPARENT_BATCHSIZE *6]
pblend_t
@ PBLEND_INVALID
void GL_CullFace(int state)
void GL_DepthMask(int state)
void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, int element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, int element3s_bufferoffset)
void GL_DepthTest(int state)
void GL_DepthRange(float nearfrac, float farfrac)
void GL_PolygonOffset(float planeoffset, float depthoffset)
void GL_BlendFunc(int blendfunc1, int blendfunc2)
void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
float RSurf_FogVertex(const float *v)
Definition gl_rmain.c:7324
void R_SetupShader_Generic(rtexture_t *t, qbool usegamma, qbool notrippy, qbool suppresstexalpha)
Definition gl_rmain.c:1461
cvar_t r_showparticleedges
Definition gl_rmain.c:94
void R_DebugLine(vec3_t start, vec3_t end)
Definition gl_rmain.c:10107
void R_CalcBeam_Vertex3f(float *vert, const float *org1, const float *org2, float width)
Definition gl_rmain.c:6253
void RSurf_ActiveModelEntity(const entity_render_t *ent, qbool wantnormals, qbool wanttangents, qbool prepass)
Definition gl_rmain.c:6921
#define GL_NONE
Definition glquake.h:127
#define GL_ZERO
Definition glquake.h:73
#define GL_ONE_MINUS_SRC_ALPHA
Definition glquake.h:80
#define GL_ONE
Definition glquake.h:74
#define GL_ONE_MINUS_SRC_COLOR
Definition glquake.h:76
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
LadyHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
Definition mathlib.c:199
#define VectorNormalize2(v, dest)
Definition mathlib.h:105
#define Vector4Copy(in, out)
Definition mathlib.h:84
#define DotProduct(a, b)
Definition mathlib.h:98
#define M_PI
Definition mathlib.h:28
void R_CompleteLightPoint(float *ambient, float *diffuse, float *lightdir, const vec3_t p, const int flags, float lightmapintensity, float ambientintensity)
Definition r_shadow.c:6014
#define LP_DYNLIGHT
Definition r_shadow.h:194
#define LP_LIGHTMAP
Definition r_shadow.h:192
#define LP_RTWORLD
Definition r_shadow.h:193
@ r_stat_particles
Definition r_stats.h:21
ret a
rtexture_t * texture
float ambientintensity
Definition render.h:384
float lightmapintensity
Definition render.h:387
entity_render_t * worldentity
the world
Definition render.h:355
double time
(client gameworld) time for rendering time based effects
Definition render.h:352
qbool fogenabled
Definition render.h:440
r_refdef_view_t view
Definition render.h:406
float fogcolor[3]
Definition render.h:424
int stats[r_stat_count]
Definition render.h:466
vec3_t left
Definition render.h:269
float colorscale
global RGB color multiplier for rendering
Definition render.h:302
vec3_t origin
Definition render.h:267
vec3_t forward
Definition render.h:268

References a, alpha, particle_t::alpha, r_refdef_scene_t::ambientintensity, particle_t::angle, particle_t::blendmode, cl, cl_particles_alpha, cl_particles_size, particle_t::color, r_refdef_view_t::colorscale, cos(), particle_t::delayedspawn, dir, DotProduct, r_refdef_t::fogcolor, r_refdef_t::fogenabled, r_refdef_view_t::forward, GL_BlendFunc(), GL_CullFace(), GL_DepthMask(), GL_DepthRange(), GL_DepthTest(), GL_NONE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR, GL_PolygonOffset(), GL_ZERO, cvar_t::integer, r_refdef_view_t::left, particletype_t::lighting, r_refdef_scene_t::lightmapintensity, LP_DYNLIGHT, LP_LIGHTMAP, LP_RTWORLD, M_PI, min, NULL, particle_t::org, particle_t::orientation, r_refdef_view_t::origin, PARTICLE_BILLBOARD, particle_color4f, particle_elements, PARTICLE_HBEAM, PARTICLE_ORIENTED_DOUBLESIDED, PARTICLE_SPARK, particle_texcoord2f, PARTICLE_VBEAM, particle_vertex3f, client_state_t::particles, particletexture, particletype, PBLEND_ADD, PBLEND_ALPHA, PBLEND_INVALID, PBLEND_INVMOD, R_CalcBeam_Vertex3f(), R_CompleteLightPoint(), R_DebugLine(), r_drawparticles_nearclip_max, r_drawparticles_nearclip_min, R_Mesh_Draw(), R_Mesh_PrepareVertices_Generic_Arrays(), r_refdef, R_SetupShader_Generic(), r_showparticleedges, r_stat_particles, right, RSurf_ActiveModelEntity(), RSurf_FogVertex(), particletexture_t::s1, particletexture_t::s2, r_refdef_t::scene, sin(), particle_t::size, size, particle_t::spin, r_refdef_t::stats, particle_t::stretch, particletexture_t::t1, particletexture_t::t2, particle_t::texnum, particletexture_t::texture, texture, r_refdef_scene_t::time, particle_t::typeindex, r_refdef_view_t::up, up, v, cvar_t::value, Vector4Copy, Vector4Set, VectorLength, VectorMA, VectorMAM, VectorNormalize, VectorNormalize2, VectorScale, VectorSubtract, VectorVectors(), particle_t::vel, r_refdef_t::view, and r_refdef_scene_t::worldentity.

Referenced by R_DrawParticles().

◆ R_DrawParticles()

void R_DrawParticles ( void )

Definition at line 2907 of file cl_particles.c.

2908{
2909 int i, a;
2910 int drawparticles = r_drawparticles.integer;
2911 float minparticledist_start;
2912 particle_t *p;
2913 float gravity, frametime, f, dist, oldorg[3], decaldir[3];
2914 float drawdist2;
2915 int hitent;
2916 trace_t trace;
2917 qbool update;
2918 float pt_explode_frame_interval, pt_explode2_frame_interval;
2919 int color;
2920
2923
2924 // LadyHavoc: early out conditions
2925 if (!cl.num_particles)
2926 return;
2927
2928 // Handling of the colour ramp for pt_explode and pt_explode2
2929 pt_explode_frame_interval = frametime * 10;
2930 pt_explode2_frame_interval = frametime * 15;
2931
2933 gravity = frametime * cl.movevars_gravity;
2934 update = frametime > 0;
2936 drawdist2 = drawdist2*drawdist2;
2937
2938 for (i = 0, p = cl.particles;i < cl.num_particles;i++, p++)
2939 {
2940 if (!p->typeindex)
2941 {
2942 if (cl.free_particle > i)
2943 cl.free_particle = i;
2944 continue;
2945 }
2946
2947 if (update)
2948 {
2949 if (p->delayedspawn > cl.time)
2950 continue;
2951
2952 p->size += p->sizeincrease * frametime;
2953 p->alpha -= p->alphafade * frametime;
2954
2955 if (p->alpha <= 0 || p->die <= cl.time)
2956 goto killparticle;
2957
2959 {
2961 {
2962 if (p->typeindex == pt_blood)
2963 p->size += frametime * 8;
2964 else
2965 p->vel[2] -= p->gravity * gravity;
2966 f = 1.0f - min(p->liquidfriction * frametime, 1);
2967 VectorScale(p->vel, f, p->vel);
2968 }
2969 else
2970 {
2971 p->vel[2] -= p->gravity * gravity;
2972 if (p->airfriction)
2973 {
2974 f = 1.0f - min(p->airfriction * frametime, 1);
2975 VectorScale(p->vel, f, p->vel);
2976 }
2977 }
2978
2979 VectorCopy(p->org, oldorg);
2980 VectorMA(p->org, frametime, p->vel, p->org);
2981// if (p->bounce && cl.time >= p->delayedcollisions)
2983 {
2984 trace = CL_TraceLine(oldorg, p->org, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, 0, collision_extendmovelength.value, true, false, &hitent, false, false);
2985 // if the trace started in or hit something of SUPERCONTENTS_NODROP
2986 // or if the trace hit something flagged as NOIMPACT
2987 // then remove the particle
2989 goto killparticle;
2990 VectorCopy(trace.endpos, p->org);
2991 // react if the particle hit something
2992 if (trace.fraction < 1)
2993 {
2994 VectorCopy(trace.endpos, p->org);
2995
2996 if (p->staintexnum >= 0)
2997 {
2998 // blood - splash on solid
3000 {
3001 R_Stain(p->org, 16,
3002 p->staincolor[0], p->staincolor[1], p->staincolor[2], (int)(p->stainalpha * p->stainsize * (1.0f / 160.0f)),
3003 p->staincolor[0], p->staincolor[1], p->staincolor[2], (int)(p->stainalpha * p->stainsize * (1.0f / 160.0f)));
3004 if (cl_decals.integer)
3005 {
3006 // create a decal for the blood splat
3007 a = 0xFFFFFF ^ (p->staincolor[0]*65536+p->staincolor[1]*256+p->staincolor[2]);
3009 {
3010 VectorCopy(p->vel, decaldir);
3011 VectorNormalize(decaldir);
3012 }
3013 else
3014 VectorCopy(trace.plane.normal, decaldir);
3015 CL_SpawnDecalParticleForSurface(hitent, p->org, decaldir, a, a, p->staintexnum, p->stainsize, p->stainalpha); // staincolor needs to be inverted for decals!
3016 }
3017 }
3018 }
3019
3020 if (p->typeindex == pt_blood)
3021 {
3022 // blood - splash on solid
3024 goto killparticle;
3025 if(p->staintexnum == -1) // staintex < -1 means no stains at all
3026 {
3027 R_Stain(p->org, 16, 64, 16, 16, (int)(p->alpha * p->size * (1.0f / 80.0f)), 64, 32, 32, (int)(p->alpha * p->size * (1.0f / 80.0f)));
3028 if (cl_decals.integer)
3029 {
3030 // create a decal for the blood splat
3032 {
3033 VectorCopy(p->vel, decaldir);
3034 VectorNormalize(decaldir);
3035 }
3036 else
3037 VectorCopy(trace.plane.normal, decaldir);
3038 CL_SpawnDecalParticleForSurface(hitent, p->org, decaldir, p->color[0] * 65536 + p->color[1] * 256 + p->color[2], p->color[0] * 65536 + p->color[1] * 256 + p->color[2], tex_blooddecal[rand()&7], p->size * lhrandom(cl_particles_blood_decal_scalemin.value, cl_particles_blood_decal_scalemax.value), cl_particles_blood_decal_alpha.value * 768);
3039 }
3040 }
3041 goto killparticle;
3042 }
3043 else if (p->bounce < 0)
3044 {
3045 // bounce -1 means remove on impact
3046 goto killparticle;
3047 }
3048 else
3049 {
3050 // anything else - bounce off solid
3051 dist = DotProduct(p->vel, trace.plane.normal) * -p->bounce;
3052 VectorMA(p->vel, dist, trace.plane.normal, p->vel);
3053 }
3054 }
3055 }
3056
3057 if (VectorLength2(p->vel) < 0.03)
3058 {
3059 if(p->orientation == PARTICLE_SPARK) // sparks are virtually invisible if very slow, so rather let them go off
3060 goto killparticle;
3061 VectorClear(p->vel);
3062 }
3063 }
3064
3065 if (p->typeindex != pt_static)
3066 {
3067 switch (p->typeindex)
3068 {
3069 case pt_entityparticle:
3070 // particle that removes itself after one rendered frame
3071 if (p->time2)
3072 goto killparticle;
3073 else
3074 p->time2 = 1;
3075 break;
3076 case pt_blood:
3079 goto killparticle;
3080 break;
3081 case pt_bubble:
3084 goto killparticle;
3085 break;
3086 case pt_rain:
3089 goto killparticle;
3090 break;
3091 case pt_snow:
3092 if (cl.time > p->time2)
3093 {
3094 // snow flutter
3095 p->time2 = cl.time + (rand() & 3) * 0.1;
3096 p->vel[0] = p->vel[0] * 0.9f + lhrandom(-32, 32);
3097 p->vel[1] = p->vel[0] * 0.9f + lhrandom(-32, 32);
3098 }
3101 goto killparticle;
3102 break;
3103 case pt_explode:
3104 // Progress the particle colour up the ramp
3105 p->time2 += pt_explode_frame_interval;
3106 if (p->time2 >= 8)
3107 p->die = -1;
3108 else
3109 {
3111 p->color[0] = color >> 16;
3112 p->color[1] = color >> 8;
3113 p->color[2] = color >> 0;
3114 }
3115 break;
3116 case pt_explode2:
3117 // Progress the particle colour up the ramp
3118 p->time2 += pt_explode2_frame_interval;
3119 if (p->time2 >= 8)
3120 p->die = -1;
3121 else
3122 {
3124 p->color[0] = color >> 16;
3125 p->color[1] = color >> 8;
3126 p->color[2] = color >> 0;
3127 }
3128 break;
3129 default:
3130 break;
3131 }
3132 }
3133 }
3134 else if (p->delayedspawn > cl.time)
3135 continue;
3136 if (!drawparticles)
3137 continue;
3138 // don't render particles too close to the view (they chew fillrate)
3139 // also don't render particles behind the view (useless)
3140 // further checks to cull to the frustum would be too slow here
3141 switch(p->typeindex)
3142 {
3143 case pt_beam:
3144 // beams have no culling
3146 break;
3147 default:
3151 {
3153 if(leaf)
3155 continue;
3156 }
3157 // anything else just has to be in front of the viewer and visible at this distance
3158 if (!r_refdef.view.useperspective || (DotProduct(p->org, r_refdef.view.forward) >= minparticledist_start && VectorDistance2(p->org, r_refdef.view.origin) < drawdist2 * (p->size * p->size)))
3160 break;
3161 }
3162
3163 continue;
3164killparticle:
3165 p->typeindex = 0;
3166 if (cl.free_particle > i)
3167 cl.free_particle = i;
3168 }
3169
3170 // reduce cl.num_particles if possible
3171 while (cl.num_particles > 0 && cl.particles[cl.num_particles - 1].typeindex == 0)
3172 cl.num_particles--;
3173
3175 {
3176 particle_t *oldparticles = cl.particles;
3179 memcpy(cl.particles, oldparticles, cl.num_particles * sizeof(particle_t));
3180 Mem_Free(oldparticles);
3181 }
3182}
#define SUPERCONTENTS_LAVA
Definition bspfile.h:199
#define SUPERCONTENTS_NODROP
Definition bspfile.h:203
static cvar_t r_drawparticles_drawdistance
static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
cvar_t r_drawparticles
float frametime
#define VectorLength2(a)
Definition mathlib.h:110
#define VectorDistance2(a, b)
Definition mathlib.h:107
void R_MeshQueue_AddTransparent(dptransparentsortcategory_t category, const vec3_t center, void(*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
Definition meshqueue.c:33
#define CHECKPVSBIT(pvs, b)
#define Q3SURFACEFLAG_NOIMPACT
#define MAX_PARTICLES
upper limit on cl.particles size
Definition qdefs.h:154
@ TRANSPARENTSORT_DISTANCE
Definition r_qshader.h:194
double particles_updatetime
Definition client.h:1013
mempool_t * levelmempool
Definition client.h:571
int clusterindex
mleaf_t *(* PointInLeaf)(struct model_s *model, const vec3_t p)
model_brush_t brush
model_t * worldmodel
same as worldentity->model
Definition render.h:358
r_refdef_viewcache_t viewcache
Definition render.h:407
float quality
render quality (0 to 1) - affects r_drawparticles_drawdistance and others
Definition render.h:321
int useperspective
if turned off it renders an ortho view
Definition render.h:280
unsigned char * world_pvsbits
Definition render.h:340
qbool world_novis
if true, the view is currently in a leaf without pvs data
Definition render.h:344
int startsupercontents
Definition collision.h:56
int hitsupercontents
Definition collision.h:58
#define MOVE_NORMAL
Definition world.h:28
#define Mem_Alloc(pool, size)
Definition zone.h:92

References a, particle_t::airfriction, particle_t::alpha, particle_t::alphafade, particle_t::bounce, bound, model_t::brush, CHECKPVSBIT, cl, cl_decals, cl_decals_newsystem_bloodsmears, cl_particles_blood_decal_alpha, cl_particles_blood_decal_scalemax, cl_particles_blood_decal_scalemin, cl_particles_collisions, cl_particles_visculling, CL_PointSuperContents, CL_SpawnDecalParticleForSurface(), CL_TraceLine(), cls, mleaf_t::clusterindex, collision_extendmovelength, color, particle_t::color, particle_t::delayedspawn, particle_t::die, DotProduct, trace_t::endpos, f, r_refdef_view_t::forward, trace_t::fraction, frametime, client_state_t::free_particle, particle_t::gravity, trace_t::hitq3surfaceflags, trace_t::hitsupercontents, i, int(), cvar_t::integer, client_static_t::levelmempool, lhrandom, particle_t::liquidfriction, MAX_PARTICLES, client_state_t::max_particles, Mem_Alloc, Mem_Free, min, MOVE_NORMAL, client_state_t::movevars_gravity, plane_t::normal, NULL, client_state_t::num_particles, particle_t::org, particle_t::orientation, r_refdef_view_t::origin, PARTICLE_HBEAM, PARTICLE_SPARK, PARTICLE_VBEAM, particlepalette, client_state_t::particles, client_state_t::particles_updatetime, trace_t::plane, model_brush_t::PointInLeaf, pt_beam, pt_blood, pt_bubble, pt_entityparticle, pt_explode, pt_explode2, pt_rain, pt_snow, pt_static, Q3SURFACEFLAG_NOIMPACT, Q3SURFACEFLAG_NOMARKS, r_refdef_view_t::quality, R_DrawParticle_TransparentCallback(), r_drawparticles, r_drawparticles_drawdistance, r_drawparticles_nearclip_min, R_MeshQueue_AddTransparent(), r_refdef, R_Stain(), ramp1, ramp2, r_refdef_t::scene, particle_t::size, particle_t::sizeincrease, particle_t::sortorigin, particle_t::stainalpha, particle_t::staincolor, particle_t::stainsize, particle_t::staintexnum, trace_t::startsupercontents, SUPERCONTENTS_LAVA, SUPERCONTENTS_LIQUIDSMASK, SUPERCONTENTS_NODROP, SUPERCONTENTS_SLIME, SUPERCONTENTS_SOLID, SUPERCONTENTS_WATER, tex_blooddecal, client_state_t::time, particle_t::time2, TRANSPARENTSORT_DISTANCE, particle_t::typeindex, r_refdef_view_t::useperspective, cvar_t::value, VectorClear, VectorCopy, VectorDistance2, VectorLength, VectorLength2, VectorMA, VectorNormalize, VectorScale, particle_t::vel, r_refdef_t::view, r_refdef_t::viewcache, r_refdef_viewcache_t::world_novis, r_refdef_viewcache_t::world_pvsbits, and r_refdef_scene_t::worldmodel.

Referenced by R_RenderScene().

◆ R_InitBloodTextures()

static void R_InitBloodTextures ( unsigned char * particletexturedata)
static

Definition at line 2261 of file cl_particles.c.

2262{
2263 int i, j, k, m;
2264 size_t datasize = PARTICLETEXTURESIZE*PARTICLETEXTURESIZE*4;
2265 unsigned char *data = (unsigned char *)Mem_Alloc(tempmempool, datasize);
2266
2267 // blood particles
2268 for (i = 0;i < 8;i++)
2269 {
2270 memset(data, 255, datasize);
2271 for (k = 0;k < 24;k++)
2273 //particletextureclamp(data, 32, 32, 32, 255, 255, 255);
2275 setuptex(tex_bloodparticle[i], data, particletexturedata);
2276 }
2277
2278 // blood decals
2279 for (i = 0;i < 8;i++)
2280 {
2281 memset(data, 255, datasize);
2282 m = 8;
2283 for (j = 1;j < 10;j++)
2284 for (k = min(j, m - 1);k < m;k++)
2285 particletextureblotch(data, (float)j*PARTICLETEXTURESIZE/64.0f, 96, 0, 0, 320 - j * 8);
2286 //particletextureclamp(data, 32, 32, 32, 255, 255, 255);
2288 setuptex(tex_blooddecal[i], data, particletexturedata);
2289 }
2290
2291 Mem_Free(data);
2292}
static void particletextureinvert(unsigned char *data)
static void setuptex(int texnum, unsigned char *data, unsigned char *particletexturedata)
static void particletextureblotch(unsigned char *data, float radius, float red, float green, float blue, float alpha)

References data, i, Mem_Alloc, Mem_Free, min, particletextureblotch(), particletextureinvert(), PARTICLETEXTURESIZE, setuptex(), tempmempool, tex_blooddecal, and tex_bloodparticle.

Referenced by R_InitParticleTexture().

◆ R_InitParticleTexture()

static void R_InitParticleTexture ( void )
static

Definition at line 2297 of file cl_particles.c.

2298{
2299 int x, y, d, i, k, m;
2300 int basex, basey, w, h;
2301 float dx, dy, f, s1, t1, s2, t2;
2302 vec3_t light;
2303 char *buf;
2304 fs_offset_t filesize;
2305 char texturename[MAX_QPATH];
2306 skinframe_t *sf;
2307
2308 // a note: decals need to modulate (multiply) the background color to
2309 // properly darken it (stain), and they need to be able to alpha fade,
2310 // this is a very difficult challenge because it means fading to white
2311 // (no change to background) rather than black (darkening everything
2312 // behind the whole decal polygon), and to accomplish this the texture is
2313 // inverted (dark red blood on white background becomes brilliant cyan
2314 // and white on black background) so we can alpha fade it to black, then
2315 // we invert it again during the blendfunc to make it work...
2316
2317#ifndef DUMPPARTICLEFONT
2318 decalskinframe = R_SkinFrame_LoadExternal("particles/particlefont.tga", TEXF_ALPHA | TEXF_FORCELINEAR | TEXF_RGBMULTIPLYBYALPHA, false, false);
2319 if (decalskinframe)
2320 {
2322 // TODO maybe allow custom grid size?
2327 particlefontcols = 8;
2328 particlefontrows = 8;
2329 }
2330 else
2331#endif
2332 {
2333 unsigned char *particletexturedata = (unsigned char *)Mem_Alloc(tempmempool, PARTICLEFONTSIZE*PARTICLEFONTSIZE*4);
2334 size_t datasize = PARTICLETEXTURESIZE*PARTICLETEXTURESIZE*4;
2335 unsigned char *data = (unsigned char *)Mem_Alloc(tempmempool, datasize);
2336 unsigned char *noise1 = (unsigned char *)Mem_Alloc(tempmempool, PARTICLETEXTURESIZE*2*PARTICLETEXTURESIZE*2);
2337 unsigned char *noise2 = (unsigned char *)Mem_Alloc(tempmempool, PARTICLETEXTURESIZE*2*PARTICLETEXTURESIZE*2);
2338
2341 particlefontcols = 8;
2342 particlefontrows = 8;
2343
2344 memset(particletexturedata, 255, PARTICLEFONTSIZE*PARTICLEFONTSIZE*4);
2345
2346 // smoke
2347 for (i = 0;i < 8;i++)
2348 {
2349 memset(data, 255, datasize);
2350 do
2351 {
2354 m = 0;
2355 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2356 {
2357 dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2358 for (x = 0;x < PARTICLETEXTURESIZE;x++)
2359 {
2360 dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2361 d = (noise2[y*PARTICLETEXTURESIZE*2+x] - 128) * 3 + 192;
2362 if (d > 0)
2363 d = (int)(d * (1-(dx*dx+dy*dy)));
2364 d = (d * noise1[y*PARTICLETEXTURESIZE*2+x]) >> 7;
2365 d = bound(0, d, 255);
2366 data[(y*PARTICLETEXTURESIZE+x)*4+3] = (unsigned char) d;
2367 if (m < d)
2368 m = d;
2369 }
2370 }
2371 }
2372 while (m < 224);
2373 setuptex(tex_smoke[i], data, particletexturedata);
2374 }
2375
2376 // rain splash
2377 memset(data, 255, datasize);
2378 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2379 {
2380 dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2381 for (x = 0;x < PARTICLETEXTURESIZE;x++)
2382 {
2383 dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2384 f = 255.0f * (1.0 - 4.0f * fabs(10.0f - sqrt(dx*dx+dy*dy)));
2385 data[(y*PARTICLETEXTURESIZE+x)*4+3] = (int) (bound(0.0f, f, 255.0f));
2386 }
2387 }
2388 setuptex(tex_rainsplash, data, particletexturedata);
2389
2390 // normal particle
2391 memset(data, 255, datasize);
2392 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2393 {
2394 dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2395 for (x = 0;x < PARTICLETEXTURESIZE;x++)
2396 {
2397 dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2398 d = (int)(256 * (1 - (dx*dx+dy*dy)));
2399 d = bound(0, d, 255);
2400 data[(y*PARTICLETEXTURESIZE+x)*4+3] = (unsigned char) d;
2401 }
2402 }
2403 setuptex(tex_particle, data, particletexturedata);
2404
2405 // rain
2406 memset(data, 255, datasize);
2407 light[0] = 1;light[1] = 1;light[2] = 1;
2408 VectorNormalize(light);
2409 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2410 {
2411 dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2412 // stretch upper half of bubble by +50% and shrink lower half by -50%
2413 // (this gives an elongated teardrop shape)
2414 if (dy > 0.5f)
2415 dy = (dy - 0.5f) * 2.0f;
2416 else
2417 dy = (dy - 0.5f) / 1.5f;
2418 for (x = 0;x < PARTICLETEXTURESIZE;x++)
2419 {
2420 dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2421 // shrink bubble width to half
2422 dx *= 2.0f;
2423 data[(y*PARTICLETEXTURESIZE+x)*4+3] = shadebubble(dx, dy, light);
2424 }
2425 }
2426 setuptex(tex_raindrop, data, particletexturedata);
2427
2428 // bubble
2429 memset(data, 255, datasize);
2430 light[0] = 1;light[1] = 1;light[2] = 1;
2431 VectorNormalize(light);
2432 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2433 {
2434 dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2435 for (x = 0;x < PARTICLETEXTURESIZE;x++)
2436 {
2437 dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
2438 data[(y*PARTICLETEXTURESIZE+x)*4+3] = shadebubble(dx, dy, light);
2439 }
2440 }
2441 setuptex(tex_bubble, data, particletexturedata);
2442
2443 // Blood particles and blood decals
2444 R_InitBloodTextures (particletexturedata);
2445
2446 // bullet decals
2447 for (i = 0;i < 8;i++)
2448 {
2449 memset(data, 255, datasize);
2450 for (k = 0;k < 12;k++)
2452 for (k = 0;k < 3;k++)
2454 //particletextureclamp(data, 64, 64, 64, 255, 255, 255);
2456 setuptex(tex_bulletdecal[i], data, particletexturedata);
2457 }
2458
2459#ifdef DUMPPARTICLEFONT
2460 Image_WriteTGABGRA ("particles/particlefont.tga", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata);
2461#endif
2462
2465
2466 Mem_Free(particletexturedata);
2467 Mem_Free(data);
2470 }
2471 for (i = 0;i < MAX_PARTICLETEXTURES;i++)
2472 {
2473 CL_Particle_PixelCoordsForTexnum(i, &basex, &basey, &w, &h);
2475 particletexture[i].s1 = (basex + 1) / (float)particlefontwidth;
2476 particletexture[i].t1 = (basey + 1) / (float)particlefontheight;
2477 particletexture[i].s2 = (basex + w - 1) / (float)particlefontwidth;
2478 particletexture[i].t2 = (basey + h - 1) / (float)particlefontheight;
2479 }
2480
2481#ifndef DUMPPARTICLEFONT
2484#endif
2485 {
2486 unsigned char noise3[64][64], data2[64][16][4];
2487 // nexbeam
2488 fractalnoise(&noise3[0][0], 64, 4);
2489 m = 0;
2490 for (y = 0;y < 64;y++)
2491 {
2492 dy = (y - 0.5f*64) / (64*0.5f-1);
2493 for (x = 0;x < 16;x++)
2494 {
2495 dx = (x - 0.5f*16) / (16*0.5f-2);
2496 d = (int)((1 - sqrt(fabs(dx))) * noise3[y][x]);
2497 data2[y][x][0] = data2[y][x][1] = data2[y][x][2] = (unsigned char) bound(0, d, 255);
2498 data2[y][x][3] = 255;
2499 }
2500 }
2501
2502#ifdef DUMPPARTICLEFONT
2503 Image_WriteTGABGRA ("particles/nexbeam.tga", 64, 64, &data2[0][0][0]);
2504#endif
2506 }
2511
2512 // now load an texcoord/texture override file
2513 buf = (char *) FS_LoadFile("particles/particlefont.txt", tempmempool, false, &filesize);
2514 if(buf)
2515 {
2516 const char *bufptr;
2517 bufptr = buf;
2518 for(;;)
2519 {
2520 if(!COM_ParseToken_Simple(&bufptr, true, false, true))
2521 break;
2522 if(!strcmp(com_token, "\n"))
2523 continue; // empty line
2524 i = atoi(com_token);
2525
2526 texturename[0] = 0;
2527 s1 = 0;
2528 t1 = 0;
2529 s2 = 1;
2530 t2 = 1;
2531
2532 if (COM_ParseToken_Simple(&bufptr, true, false, true) && strcmp(com_token, "\n"))
2533 {
2534 dp_strlcpy(texturename, com_token, sizeof(texturename));
2535 s1 = atof(com_token);
2536 if (COM_ParseToken_Simple(&bufptr, true, false, true) && strcmp(com_token, "\n"))
2537 {
2538 texturename[0] = 0;
2539 t1 = atof(com_token);
2540 if (COM_ParseToken_Simple(&bufptr, true, false, true) && strcmp(com_token, "\n"))
2541 {
2542 s2 = atof(com_token);
2543 if (COM_ParseToken_Simple(&bufptr, true, false, true) && strcmp(com_token, "\n"))
2544 {
2545 t2 = atof(com_token);
2546 dp_strlcpy(texturename, "particles/particlefont.tga", sizeof(texturename));
2547 if (COM_ParseToken_Simple(&bufptr, true, false, true) && strcmp(com_token, "\n"))
2548 dp_strlcpy(texturename, com_token, sizeof(texturename));
2549 }
2550 }
2551 }
2552 else
2553 s1 = 0;
2554 }
2555 if (!texturename[0])
2556 {
2557 Con_Printf("particles/particlefont.txt: syntax should be texnum x1 y1 x2 y2 texturename or texnum x1 y1 x2 y2 or texnum texturename\n");
2558 continue;
2559 }
2561 {
2562 Con_Printf("particles/particlefont.txt: texnum %i outside valid range (0 to %i)\n", i, MAX_PARTICLETEXTURES);
2563 continue;
2564 }
2565 sf = R_SkinFrame_LoadExternal(texturename, TEXF_ALPHA | TEXF_FORCELINEAR | TEXF_RGBMULTIPLYBYALPHA, true, true); // note: this loads as sRGB if sRGB is active!
2567 particletexture[i].s1 = s1;
2568 particletexture[i].t1 = t1;
2569 particletexture[i].s2 = s2;
2570 particletexture[i].t2 = t2;
2571 }
2572 Mem_Free(buf);
2573 }
2574}
static void R_InitBloodTextures(unsigned char *particletexturedata)
static unsigned char shadebubble(float dx, float dy, vec3_t light)
skinframe_t * decalskinframe
static rtexture_t * particlefonttexture
static void CL_Particle_PixelCoordsForTexnum(int texnum, int *basex, int *basey, int *width, int *height)
int particlefontheight
#define PARTICLEFONTSIZE
static rtexturepool_t * particletexturepool
static const int tex_raindrop
int particlefontwidth
void fractalnoise(unsigned char *noise, int size, int startgrid)
Definition fractalnoise.c:4
skinframe_t * R_SkinFrame_LoadExternal(const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
Definition gl_rmain.c:2314
skinframe_t * R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qbool sRGB)
Definition gl_rmain.c:2546
rtexture_t * R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
rtexture_t * loadtextureimage(rtexturepool_t *pool, const char *filename, qbool complain, int flags, qbool allowFixtrans, qbool sRGB)
Definition image.c:1245
int image_height
Definition image.c:10
qbool Image_WriteTGABGRA(const char *filename, int width, int height, const unsigned char *data)
Definition image.c:1436
int image_width
Definition image.c:9
float fabs(float f)
string noise1
Definition progsdefs.qc:209
string noise3
Definition progsdefs.qc:209
string noise2
Definition progsdefs.qc:209
#define MAX_PARTICLETEXTURES
maximum number of unique particle textures in the particle font
Definition qdefs.h:137
#define TEXF_RGBMULTIPLYBYALPHA
Definition r_textures.h:13
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_FORCELINEAR
Definition r_textures.h:19
@ TEXTYPE_BGRA
Definition r_textures.h:53
struct rtexture_s * base
Definition r_textures.h:129

References skinframe_t::base, bound, buf, CL_Particle_PixelCoordsForTexnum(), COM_ParseToken_Simple(), com_token, Con_Printf(), data, decalskinframe, dp_strlcpy, f, fabs(), fractalnoise(), FS_LoadFile(), i, image_height, image_width, Image_WriteTGABGRA(), int(), loadtextureimage(), MAX_PARTICLETEXTURES, MAX_QPATH, Mem_Alloc, Mem_Free, noise1, noise2, noise3, NULL, particlefontcellheight, particlefontcellwidth, particlefontcols, particlefontheight, particlefontrows, PARTICLEFONTSIZE, particlefonttexture, particlefontwidth, particletexture, particletextureblotch(), particletextureinvert(), particletexturepool, PARTICLETEXTURESIZE, R_InitBloodTextures(), R_LoadTexture2D(), R_SkinFrame_LoadExternal(), R_SkinFrame_LoadInternalBGRA(), particletexture_t::s1, particletexture_t::s2, setuptex(), shadebubble(), sqrt(), viddef_t::sRGB3D, particletexture_t::t1, particletexture_t::t2, tempmempool, tex_beam, tex_bubble, tex_bulletdecal, tex_particle, tex_raindrop, tex_rainsplash, tex_smoke, TEXF_ALPHA, TEXF_FORCELINEAR, TEXF_RGBMULTIPLYBYALPHA, particletexture_t::texture, texture, TEXTYPE_BGRA, VectorNormalize, vid, w, x, and y.

Referenced by r_part_start().

◆ r_part_newmap()

static void r_part_newmap ( void )
static

Definition at line 2592 of file cl_particles.c.

2593{
2594 if (decalskinframe)
2597}
void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
Definition gl_rmain.c:2176

References CL_Particles_LoadEffectInfo(), decalskinframe, NULL, and R_SkinFrame_MarkUsed().

Referenced by R_Particles_Init().

◆ r_part_shutdown()

static void r_part_shutdown ( void )
static

Definition at line 2587 of file cl_particles.c.

2588{
2590}
void R_FreeTexturePool(rtexturepool_t **rtexturepool)

References particletexturepool, and R_FreeTexturePool().

Referenced by R_Particles_Init().

◆ r_part_start()

static void r_part_start ( void )
static

Definition at line 2576 of file cl_particles.c.

2577{
2578 int i;
2579 // generate particlepalette for convenience from the main one
2580 for (i = 0;i < 256;i++)
2581 particlepalette[i] = palette_rgb[i][0] * 65536 + palette_rgb[i][1] * 256 + palette_rgb[i][2];
2585}
static void R_InitParticleTexture(void)
rtexturepool_t * R_AllocTexturePool(void)
unsigned char palette_rgb[256][3]
Definition palette.c:7

References CL_Particles_LoadEffectInfo(), i, NULL, palette_rgb, particlepalette, particletexturepool, R_AllocTexturePool(), and R_InitParticleTexture().

Referenced by R_Particles_Init().

◆ R_Particles_Init()

void R_Particles_Init ( void )

Definition at line 2602 of file cl_particles.c.

2603{
2604 int i;
2605 for (i = 0;i < MESHQUEUE_TRANSPARENT_BATCHSIZE;i++)
2606 {
2607 particle_elements[i*6+0] = i*4+0;
2608 particle_elements[i*6+1] = i*4+1;
2609 particle_elements[i*6+2] = i*4+2;
2610 particle_elements[i*6+3] = i*4+0;
2611 particle_elements[i*6+4] = i*4+2;
2612 particle_elements[i*6+5] = i*4+3;
2613 }
2614
2622}
static void r_part_start(void)
cvar_t r_drawdecals
static void r_part_newmap(void)
static cvar_t r_drawdecals_drawdistance
static void r_part_shutdown(void)
#define MESHQUEUE_TRANSPARENT_BATCHSIZE
Definition meshqueue.h:6
void R_RegisterModule(const char *name, void(*start)(void), void(*shutdown)(void), void(*newmap)(void), void(*devicelost)(void), void(*devicerestored)(void))
Definition r_modules.c:25

References Cvar_RegisterVariable(), i, MESHQUEUE_TRANSPARENT_BATCHSIZE, NULL, particle_elements, r_drawdecals, r_drawdecals_drawdistance, r_drawparticles, r_drawparticles_drawdistance, r_drawparticles_nearclip_max, r_drawparticles_nearclip_min, r_part_newmap(), r_part_shutdown(), r_part_start(), and R_RegisterModule().

Referenced by Render_Init().

◆ setuptex()

static void setuptex ( int texnum,
unsigned char * data,
unsigned char * particletexturedata )
static

Definition at line 2197 of file cl_particles.c.

2198{
2199 int basex, basey, w, h, y;
2200 CL_Particle_PixelCoordsForTexnum(texnum, &basex, &basey, &w, &h);
2202 Sys_Error("invalid particle texture size for autogenerating");
2203 for (y = 0;y < PARTICLETEXTURESIZE;y++)
2204 memcpy(particletexturedata + ((basey + y) * PARTICLEFONTSIZE + basex) * 4, data + y * PARTICLETEXTURESIZE * 4, PARTICLETEXTURESIZE * 4);
2205}
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
Definition sys_shared.c:724

References CL_Particle_PixelCoordsForTexnum(), data, PARTICLEFONTSIZE, PARTICLETEXTURESIZE, Sys_Error(), w, and y.

Referenced by R_InitBloodTextures(), and R_InitParticleTexture().

◆ shadebubble()

static unsigned char shadebubble ( float dx,
float dy,
vec3_t light )
static

Definition at line 2155 of file cl_particles.c.

2156{
2157 float dz, f, dot;
2158 vec3_t normal;
2159 dz = 1 - (dx*dx+dy*dy);
2160 if (dz > 0) // it does hit the sphere
2161 {
2162 f = 0;
2163 // back side
2164 normal[0] = dx;normal[1] = dy;normal[2] = dz;
2166 dot = DotProduct(normal, light);
2167 if (dot > 0.5) // interior reflection
2168 f += ((dot * 2) - 1);
2169 else if (dot < -0.5) // exterior reflection
2170 f += ((dot * -2) - 1);
2171 // front side
2172 normal[0] = dx;normal[1] = dy;normal[2] = -dz;
2174 dot = DotProduct(normal, light);
2175 if (dot > 0.5) // interior reflection
2176 f += ((dot * 2) - 1);
2177 else if (dot < -0.5) // exterior reflection
2178 f += ((dot * -2) - 1);
2179 f *= 128;
2180 f += 16; // just to give it a haze so you can see the outline
2181 f = bound(0, f, 255);
2182 return (unsigned char) f;
2183 }
2184 else
2185 return 0;
2186}

References bound, DotProduct, f, normal, and VectorNormalize.

Referenced by R_InitParticleTexture().

Variable Documentation

◆ baselineparticleeffectinfo

particleeffectinfo_t baselineparticleeffectinfo

Definition at line 201 of file cl_particles.c.

202{
203 0, //int effectnameindex; // which effect this belongs to
204 // PARTICLEEFFECT_* bits
205 0, //int flags;
206 // blood effects may spawn very few particles, so proper fraction-overflow
207 // handling is very important, this variable keeps track of the fraction
208 0.0, //double particleaccumulator;
209 // the math is: countabsolute + requestedcount * countmultiplier * quality
210 // absolute number of particles to spawn, often used for decals
211 // (unaffected by quality and requestedcount)
212 0.0f, //float countabsolute;
213 // multiplier for the number of particles CL_ParticleEffect was told to
214 // spawn, most effects do not really have a count and hence use 1, so
215 // this is often the actual count to spawn, not merely a multiplier
216 0.0f, //float countmultiplier;
217 // if > 0 this causes the particle to spawn in an evenly spaced line from
218 // originmins to originmaxs (causing them to describe a trail, not a box)
219 0.0f, //float trailspacing;
220 // type of particle to spawn (defines some aspects of behavior)
221 pt_alphastatic, //ptype_t particletype;
222 // blending mode used on this particle type
223 PBLEND_ALPHA, //pblend_t blendmode;
224 // orientation of this particle type (BILLBOARD, SPARK, BEAM, etc)
225 PARTICLE_BILLBOARD, //porientation_t orientation;
226 // range of colors to choose from in hex RRGGBB (like HTML color tags),
227 // randomly interpolated at spawn
228 {0xFFFFFF, 0xFFFFFF}, //unsigned int color[2];
229 // a random texture is chosen in this range (note the second value is one
230 // past the last choosable, so for example 8,16 chooses any from 8 up and
231 // including 15)
232 // if start and end of the range are the same, no randomization is done
233 {63, 63 /* tex_particle */}, //int tex[2];
234 // range of size values randomly chosen when spawning, plus size increase over time
235 {1, 1, 0.0f}, //float size[3];
236 // range of alpha values randomly chosen when spawning, plus alpha fade
237 {0.0f, 256.0f, 256.0f}, //float alpha[3];
238 // how long the particle should live (note it is also removed if alpha drops to 0)
239 {16777216.0f, 16777216.0f}, //float time[2];
240 // how much gravity affects this particle (negative makes it fly up!)
241 0.0f, //float gravity;
242 // how much bounce the particle has when it hits a surface
243 // if negative the particle is removed on impact
244 0.0f, //float bounce;
245 // if in air this friction is applied
246 // if negative the particle accelerates
247 0.0f, //float airfriction;
248 // if in liquid (water/slime/lava) this friction is applied
249 // if negative the particle accelerates
250 0.0f, //float liquidfriction;
251 // these offsets are added to the values given to particleeffect(), and
252 // then an ellipsoid-shaped jitter is added as defined by these
253 // (they are the 3 radii)
254 1.0f, //float stretchfactor;
255 // stretch velocity factor (used for sparks)
256 {0.0f, 0.0f, 0.0f}, //float originoffset[3];
257 {0.0f, 0.0f, 0.0f}, //float relativeoriginoffset[3];
258 {0.0f, 0.0f, 0.0f}, //float velocityoffset[3];
259 {0.0f, 0.0f, 0.0f}, //float relativevelocityoffset[3];
260 {0.0f, 0.0f, 0.0f}, //float originjitter[3];
261 {0.0f, 0.0f, 0.0f}, //float velocityjitter[3];
262 0.0f, //float velocitymultiplier;
263 // an effect can also spawn a dlight
264 0.0f, //float lightradiusstart;
265 0.0f, //float lightradiusfade;
266 16777216.0f, //float lighttime;
267 {1.0f, 1.0f, 1.0f}, //float lightcolor[3];
268 true, //qbool lightshadow;
269 0, //int lightcubemapnum;
270 {1.0f, 0.25f}, //float lightcorona[2];
271 {(unsigned int)-1, (unsigned int)-1}, //unsigned int staincolor[2]; // note: 0x808080 = neutral (particle's own color), these are modding factors for the particle's original color!
272 {-1, -1}, //int staintex[2];
273 {1.0f, 1.0f}, //float stainalpha[2];
274 {2.0f, 2.0f}, //float stainsize[2];
275 // other parameters
276 {0.0f, 360.0f, 0.0f, 0.0f}, //float rotate[4]; // min/max base angle, min/max rotation over time
277};

Referenced by CL_Particles_ParseEffectInfo().

◆ cl_decals

cvar_t cl_decals = {CF_CLIENT | CF_ARCHIVE, "cl_decals", "1", "enables decals (bullet holes, blood, etc)"}

Definition at line 303 of file cl_particles.c.

303{CF_CLIENT | CF_ARCHIVE, "cl_decals", "1", "enables decals (bullet holes, blood, etc)"};
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53

Referenced by CL_ImmediateBloodStain(), CL_Particles_Init(), CL_SpawnDecalParticleForSurface(), M_Menu_Options_Effects_AdjustSliders(), M_Options_Effects_Draw(), and R_DrawParticles().

◆ cl_decals_bias

cvar_t cl_decals_bias = {CF_CLIENT | CF_ARCHIVE, "cl_decals_bias", "0.125", "distance to bias decals from surface to prevent depth fighting"}

Definition at line 310 of file cl_particles.c.

310{CF_CLIENT | CF_ARCHIVE, "cl_decals_bias", "0.125", "distance to bias decals from surface to prevent depth fighting"};

Referenced by CL_Particles_Init(), and R_DecalSystem_SplatTriangle().

◆ cl_decals_fadetime

cvar_t cl_decals_fadetime = {CF_CLIENT | CF_ARCHIVE, "cl_decals_fadetime", "1", "how long decals take to fade away"}

Definition at line 305 of file cl_particles.c.

305{CF_CLIENT | CF_ARCHIVE, "cl_decals_fadetime", "1", "how long decals take to fade away"};

Referenced by CL_Particles_Init(), R_DrawModelDecals_Entity(), and R_DrawModelDecals_FadeEntity().

◆ cl_decals_max

cvar_t cl_decals_max = {CF_CLIENT | CF_ARCHIVE, "cl_decals_max", "4096", "maximum number of decals allowed to exist in the world at once"}

Definition at line 311 of file cl_particles.c.

311{CF_CLIENT | CF_ARCHIVE, "cl_decals_max", "4096", "maximum number of decals allowed to exist in the world at once"};

Referenced by CL_Particles_Init(), and R_DrawModelDecals_FadeEntity().

◆ cl_decals_models

cvar_t cl_decals_models = {CF_CLIENT | CF_ARCHIVE, "cl_decals_models", "0", "enables decals on animated models"}

Definition at line 309 of file cl_particles.c.

309{CF_CLIENT | CF_ARCHIVE, "cl_decals_models", "0", "enables decals on animated models"};

Referenced by CL_Particles_Init(), and R_DecalSystem_SplatEntity().

◆ cl_decals_newsystem_bloodsmears

cvar_t cl_decals_newsystem_bloodsmears = {CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_bloodsmears", "1", "enable use of particle velocity as decal projection direction rather than surface normal"}

Definition at line 308 of file cl_particles.c.

308{CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_bloodsmears", "1", "enable use of particle velocity as decal projection direction rather than surface normal"};

Referenced by CL_Particles_Init(), and R_DrawParticles().

◆ cl_decals_newsystem_immediatebloodstain

cvar_t cl_decals_newsystem_immediatebloodstain = {CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_immediatebloodstain", "2", "0: no on-spawn blood stains; 1: on-spawn blood stains for pt_blood; 2: always use on-spawn blood stains"}

Definition at line 307 of file cl_particles.c.

307{CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_immediatebloodstain", "2", "0: no on-spawn blood stains; 1: on-spawn blood stains for pt_blood; 2: always use on-spawn blood stains"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleEffect_Fallback(), and CL_Particles_Init().

◆ cl_decals_newsystem_intensitymultiplier

cvar_t cl_decals_newsystem_intensitymultiplier = {CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_intensitymultiplier", "2", "boosts intensity of decals (because the distance fade can make them hard to see otherwise)"}

Definition at line 306 of file cl_particles.c.

306{CF_CLIENT | CF_ARCHIVE, "cl_decals_newsystem_intensitymultiplier", "2", "boosts intensity of decals (because the distance fade can make them hard to see otherwise)"};

Referenced by CL_Particles_Init(), and R_DecalSystem_SplatTriangle().

◆ cl_decals_time

cvar_t cl_decals_time = {CF_CLIENT | CF_ARCHIVE, "cl_decals_time", "20", "how long before decals start to fade away"}

Definition at line 304 of file cl_particles.c.

304{CF_CLIENT | CF_ARCHIVE, "cl_decals_time", "20", "how long before decals start to fade away"};

Referenced by CL_Particles_Init(), R_DrawModelDecals_Entity(), and R_DrawModelDecals_FadeEntity().

◆ cl_particles

◆ cl_particles_alpha

cvar_t cl_particles_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_alpha", "1", "multiplies opacity of particles"}

Definition at line 281 of file cl_particles.c.

281{CF_CLIENT | CF_ARCHIVE, "cl_particles_alpha", "1", "multiplies opacity of particles"};

Referenced by CL_Particles_Init(), and R_DrawParticle_TransparentCallback().

◆ cl_particles_blood

cvar_t cl_particles_blood = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood", "1", "enables blood effects"}

Definition at line 284 of file cl_particles.c.

284{CF_CLIENT | CF_ARCHIVE, "cl_particles_blood", "1", "enables blood effects"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleEffect_Fallback(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_blood_alpha

cvar_t cl_particles_blood_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_alpha", "1", "opacity of blood, does not affect decals"}

Definition at line 285 of file cl_particles.c.

285{CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_alpha", "1", "opacity of blood, does not affect decals"};

Referenced by CL_ParticleEffect_Fallback(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_blood_bloodhack

cvar_t cl_particles_blood_bloodhack = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_bloodhack", "1", "make certain quake particle() calls create blood effects instead"}

Definition at line 289 of file cl_particles.c.

289{CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_bloodhack", "1", "make certain quake particle() calls create blood effects instead"};

Referenced by CL_ParticleEffect_Fallback(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_blood_decal_alpha

cvar_t cl_particles_blood_decal_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_alpha", "1", "opacity of blood decal"}

Definition at line 286 of file cl_particles.c.

286{CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_alpha", "1", "opacity of blood decal"};

Referenced by CL_Particles_Init(), and R_DrawParticles().

◆ cl_particles_blood_decal_scalemax

cvar_t cl_particles_blood_decal_scalemax = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_scalemax", "2", "maximal random scale of decal"}

Definition at line 288 of file cl_particles.c.

288{CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_scalemax", "2", "maximal random scale of decal"};

Referenced by CL_Particles_Init(), and R_DrawParticles().

◆ cl_particles_blood_decal_scalemin

cvar_t cl_particles_blood_decal_scalemin = {CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_scalemin", "1.5", "minimal random scale of decal"}

Definition at line 287 of file cl_particles.c.

287{CF_CLIENT | CF_ARCHIVE, "cl_particles_blood_decal_scalemin", "1.5", "minimal random scale of decal"};

Referenced by CL_Particles_Init(), and R_DrawParticles().

◆ cl_particles_bubbles

cvar_t cl_particles_bubbles = {CF_CLIENT | CF_ARCHIVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"}

Definition at line 299 of file cl_particles.c.

299{CF_CLIENT | CF_ARCHIVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleEffect_Fallback(), CL_ParticleExplosion(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_bulletimpacts

cvar_t cl_particles_bulletimpacts = {CF_CLIENT | CF_ARCHIVE, "cl_particles_bulletimpacts", "1", "enables bulletimpact effects"}

Definition at line 290 of file cl_particles.c.

290{CF_CLIENT | CF_ARCHIVE, "cl_particles_bulletimpacts", "1", "enables bulletimpact effects"};

Referenced by CL_ParticleEffect_Fallback(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_collisions

cvar_t cl_particles_collisions = {CF_CLIENT | CF_ARCHIVE, "cl_particles_collisions", "1", "allow costly collision detection on particles (sparks that bounce, particles not going through walls, blood hitting surfaces, etc)"}

Definition at line 301 of file cl_particles.c.

301{CF_CLIENT | CF_ARCHIVE, "cl_particles_collisions", "1", "allow costly collision detection on particles (sparks that bounce, particles not going through walls, blood hitting surfaces, etc)"};

Referenced by CL_Particles_Init(), and R_DrawParticles().

◆ cl_particles_explosions_shell

cvar_t cl_particles_explosions_shell = {CF_CLIENT | CF_ARCHIVE, "cl_particles_explosions_shell", "0", "enables polygonal shell from explosions"}

Definition at line 292 of file cl_particles.c.

292{CF_CLIENT | CF_ARCHIVE, "cl_particles_explosions_shell", "0", "enables polygonal shell from explosions"};

Referenced by CL_ParticleExplosion(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_explosions_sparks

cvar_t cl_particles_explosions_sparks = {CF_CLIENT | CF_ARCHIVE, "cl_particles_explosions_sparks", "1", "enables sparks from explosions"}

Definition at line 291 of file cl_particles.c.

291{CF_CLIENT | CF_ARCHIVE, "cl_particles_explosions_sparks", "1", "enables sparks from explosions"};

Referenced by CL_ParticleExplosion(), and CL_Particles_Init().

◆ cl_particles_forcetraileffects

cvar_t cl_particles_forcetraileffects = {CF_CLIENT, "cl_particles_forcetraileffects", "0", "force trails to be displayed even if a non-trail draw primitive was used (debug/compat feature)"}

Definition at line 302 of file cl_particles.c.

302{CF_CLIENT, "cl_particles_forcetraileffects", "0", "force trails to be displayed even if a non-trail draw primitive was used (debug/compat feature)"};

Referenced by CL_NewParticlesFromEffectinfo(), and CL_Particles_Init().

◆ cl_particles_quake

cvar_t cl_particles_quake = {CF_CLIENT | CF_ARCHIVE, "cl_particles_quake", "0", "0: Fancy particles; 1: Disc particles like GLQuake; 2: Square particles like software-rendered Quake"}

Definition at line 283 of file cl_particles.c.

283{CF_CLIENT | CF_ARCHIVE, "cl_particles_quake", "0", "0: Fancy particles; 1: Disc particles like GLQuake; 2: Square particles like software-rendered Quake"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_NewQuakeParticle(), CL_ParticleEffect_Fallback(), CL_ParticleExplosion(), CL_ParticleExplosion2(), CL_Particles_Init(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_quality

cvar_t cl_particles_quality = {CF_CLIENT | CF_ARCHIVE, "cl_particles_quality", "1", "multiplies number of particles"}

◆ cl_particles_rain

cvar_t cl_particles_rain = {CF_CLIENT | CF_ARCHIVE, "cl_particles_rain", "1", "enables rain effects"}

Definition at line 293 of file cl_particles.c.

293{CF_CLIENT | CF_ARCHIVE, "cl_particles_rain", "1", "enables rain effects"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleRain(), and CL_Particles_Init().

◆ cl_particles_size

cvar_t cl_particles_size = {CF_CLIENT | CF_ARCHIVE, "cl_particles_size", "1", "multiplies particle size"}

Definition at line 282 of file cl_particles.c.

282{CF_CLIENT | CF_ARCHIVE, "cl_particles_size", "1", "multiplies particle size"};

Referenced by CL_Particles_Init(), and R_DrawParticle_TransparentCallback().

◆ cl_particles_smoke

cvar_t cl_particles_smoke = {CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke", "1", "enables smoke (used by multiple effects)"}

Definition at line 295 of file cl_particles.c.

295{CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke", "1", "enables smoke (used by multiple effects)"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleEffect_Fallback(), CL_Particles_Init(), CL_Smoke(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_smoke_alpha

cvar_t cl_particles_smoke_alpha = {CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke_alpha", "0.5", "smoke brightness"}

Definition at line 296 of file cl_particles.c.

296{CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke_alpha", "0.5", "smoke brightness"};

Referenced by CL_ParticleEffect_Fallback(), and CL_Particles_Init().

◆ cl_particles_smoke_alphafade

cvar_t cl_particles_smoke_alphafade = {CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke_alphafade", "0.55", "brightness fade per second"}

Definition at line 297 of file cl_particles.c.

297{CF_CLIENT | CF_ARCHIVE, "cl_particles_smoke_alphafade", "0.55", "brightness fade per second"};

Referenced by CL_ParticleEffect_Fallback(), and CL_Particles_Init().

◆ cl_particles_snow

cvar_t cl_particles_snow = {CF_CLIENT | CF_ARCHIVE, "cl_particles_snow", "1", "enables snow effects"}

Definition at line 294 of file cl_particles.c.

294{CF_CLIENT | CF_ARCHIVE, "cl_particles_snow", "1", "enables snow effects"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleRain(), and CL_Particles_Init().

◆ cl_particles_sparks

cvar_t cl_particles_sparks = {CF_CLIENT | CF_ARCHIVE, "cl_particles_sparks", "1", "enables sparks (used by multiple effects)"}

Definition at line 298 of file cl_particles.c.

298{CF_CLIENT | CF_ARCHIVE, "cl_particles_sparks", "1", "enables sparks (used by multiple effects)"};

Referenced by CL_NewParticlesFromEffectinfo(), CL_ParticleEffect_Fallback(), CL_ParticleExplosion(), CL_Particles_Init(), CL_Sparks(), M_Menu_Options_Effects_AdjustSliders(), and M_Options_Effects_Draw().

◆ cl_particles_visculling

cvar_t cl_particles_visculling = {CF_CLIENT | CF_ARCHIVE, "cl_particles_visculling", "0", "perform a costly check if each particle is visible before drawing"}

Definition at line 300 of file cl_particles.c.

300{CF_CLIENT | CF_ARCHIVE, "cl_particles_visculling", "0", "perform a costly check if each particle is visible before drawing"};

Referenced by CL_Particles_Init(), and R_DrawParticles().

◆ decalskinframe

skinframe_t* decalskinframe

Definition at line 187 of file cl_particles.c.

Referenced by R_DrawModelDecals_Entity(), R_InitParticleTexture(), and r_part_newmap().

◆ numparticleeffectinfo

int numparticleeffectinfo

Definition at line 131 of file cl_particles.c.

Referenced by CL_Particles_LoadEffectInfo(), and CL_Particles_ParseEffectInfo().

◆ particle_color4f

float particle_color4f[MESHQUEUE_TRANSPARENT_BATCHSIZE *16]

Definition at line 2600 of file cl_particles.c.

Referenced by R_DrawParticle_TransparentCallback().

◆ particle_elements

unsigned short particle_elements[MESHQUEUE_TRANSPARENT_BATCHSIZE *6]

Definition at line 2599 of file cl_particles.c.

Referenced by R_DrawParticle_TransparentCallback(), and R_Particles_Init().

◆ particle_texcoord2f

float particle_texcoord2f[MESHQUEUE_TRANSPARENT_BATCHSIZE *8]

Definition at line 2600 of file cl_particles.c.

Referenced by R_DrawParticle_TransparentCallback().

◆ particle_vertex3f

float particle_vertex3f[MESHQUEUE_TRANSPARENT_BATCHSIZE *12]

Definition at line 2600 of file cl_particles.c.

Referenced by R_DrawParticle_TransparentCallback().

◆ particleeffectinfo

◆ particleeffectname

◆ particlefontcellheight

int particlefontcellheight

Definition at line 2188 of file cl_particles.c.

Referenced by CL_Particle_PixelCoordsForTexnum(), and R_InitParticleTexture().

◆ particlefontcellwidth

int particlefontcellwidth

Definition at line 2188 of file cl_particles.c.

Referenced by CL_Particle_PixelCoordsForTexnum(), and R_InitParticleTexture().

◆ particlefontcols

int particlefontcols

Definition at line 2188 of file cl_particles.c.

Referenced by CL_Particle_PixelCoordsForTexnum(), and R_InitParticleTexture().

◆ particlefontheight

int particlefontheight

Definition at line 2188 of file cl_particles.c.

Referenced by R_InitParticleTexture().

◆ particlefontrows

int particlefontrows

Definition at line 2188 of file cl_particles.c.

Referenced by CL_Particle_PixelCoordsForTexnum(), and R_InitParticleTexture().

◆ particlefonttexture

rtexture_t* particlefonttexture
static

Definition at line 185 of file cl_particles.c.

Referenced by R_InitParticleTexture().

◆ particlefontwidth

int particlefontwidth

Definition at line 2188 of file cl_particles.c.

Referenced by R_InitParticleTexture().

◆ particlepalette

◆ particletexture

◆ particletexturepool

rtexturepool_t* particletexturepool
static

Definition at line 184 of file cl_particles.c.

Referenced by R_InitParticleTexture(), r_part_shutdown(), and r_part_start().

◆ particletype

particletype_t particletype[pt_total]
Initial value:

Definition at line 28 of file cl_particles.c.

29{
30 {PBLEND_INVALID, PARTICLE_INVALID, false}, //pt_dead (should never happen)
31 {PBLEND_ALPHA, PARTICLE_BILLBOARD, false}, //pt_alphastatic
32 {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_static
33 {PBLEND_ADD, PARTICLE_SPARK, false}, //pt_spark
34 {PBLEND_ADD, PARTICLE_HBEAM, false}, //pt_beam
35 {PBLEND_ADD, PARTICLE_SPARK, false}, //pt_rain
36 {PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED, false}, //pt_raindecal
37 {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_snow
38 {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_bubble
39 {PBLEND_INVMOD, PARTICLE_BILLBOARD, false}, //pt_blood
40 {PBLEND_ADD, PARTICLE_BILLBOARD, false}, //pt_smoke
42 {PBLEND_ALPHA, PARTICLE_BILLBOARD, false}, //pt_entityparticle
43};

Referenced by CL_Particles_ParseEffectInfo(), and R_DrawParticle_TransparentCallback().

◆ r_drawdecals

cvar_t r_drawdecals = {CF_CLIENT, "r_drawdecals", "1", "enables drawing of decals"}

Definition at line 2149 of file cl_particles.c.

2149{CF_CLIENT, "r_drawdecals", "1", "enables drawing of decals"};

Referenced by R_DrawModelDecals(), R_Particles_Init(), and R_Water_ProcessPlanes().

◆ r_drawdecals_drawdistance

cvar_t r_drawdecals_drawdistance = {CF_CLIENT | CF_ARCHIVE, "r_drawdecals_drawdistance", "500", "decals further than drawdistance*size will not be drawn"}
static

Definition at line 2150 of file cl_particles.c.

2150{CF_CLIENT | CF_ARCHIVE, "r_drawdecals_drawdistance", "500", "decals further than drawdistance*size will not be drawn"};

Referenced by R_Particles_Init().

◆ r_drawparticles

cvar_t r_drawparticles = {CF_CLIENT, "r_drawparticles", "1", "enables drawing of particles"}

Definition at line 2145 of file cl_particles.c.

2145{CF_CLIENT, "r_drawparticles", "1", "enables drawing of particles"};

Referenced by R_DrawParticles(), R_Particles_Init(), and R_Water_ProcessPlanes().

◆ r_drawparticles_drawdistance

cvar_t r_drawparticles_drawdistance = {CF_CLIENT | CF_ARCHIVE, "r_drawparticles_drawdistance", "2000", "particles further than drawdistance*size will not be drawn"}
static

Definition at line 2146 of file cl_particles.c.

2146{CF_CLIENT | CF_ARCHIVE, "r_drawparticles_drawdistance", "2000", "particles further than drawdistance*size will not be drawn"};

Referenced by R_DrawParticles(), and R_Particles_Init().

◆ r_drawparticles_nearclip_max

cvar_t r_drawparticles_nearclip_max = {CF_CLIENT | CF_ARCHIVE, "r_drawparticles_nearclip_max", "4", "particles closer than drawnearclip_min will be faded"}
static

Definition at line 2148 of file cl_particles.c.

2148{CF_CLIENT | CF_ARCHIVE, "r_drawparticles_nearclip_max", "4", "particles closer than drawnearclip_min will be faded"};

Referenced by R_DrawParticle_TransparentCallback(), and R_Particles_Init().

◆ r_drawparticles_nearclip_min

cvar_t r_drawparticles_nearclip_min = {CF_CLIENT | CF_ARCHIVE, "r_drawparticles_nearclip_min", "4", "particles closer than drawnearclip_min will not be drawn"}
static

Definition at line 2147 of file cl_particles.c.

2147{CF_CLIENT | CF_ARCHIVE, "r_drawparticles_nearclip_min", "4", "particles closer than drawnearclip_min will not be drawn"};

Referenced by R_DrawParticle_TransparentCallback(), R_DrawParticles(), and R_Particles_Init().

◆ ramp1

int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}

Definition at line 170 of file cl_particles.c.

170{0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61};

Referenced by CL_ParticleExplosion(), and R_DrawParticles().

◆ ramp2

int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}

Definition at line 171 of file cl_particles.c.

171{0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66};

Referenced by CL_ParticleExplosion(), and R_DrawParticles().

◆ ramp3

int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}

Definition at line 172 of file cl_particles.c.

172{0x6d, 0x6b, 6, 5, 4, 3};

Referenced by CL_ParticleEffect_Fallback().

◆ standardeffectnames

const char* standardeffectnames[EFFECT_TOTAL]
static

Definition at line 498 of file cl_particles.c.

499{
500 "",
501 "TE_GUNSHOT",
502 "TE_GUNSHOTQUAD",
503 "TE_SPIKE",
504 "TE_SPIKEQUAD",
505 "TE_SUPERSPIKE",
506 "TE_SUPERSPIKEQUAD",
507 "TE_WIZSPIKE",
508 "TE_KNIGHTSPIKE",
509 "TE_EXPLOSION",
510 "TE_EXPLOSIONQUAD",
511 "TE_TAREXPLOSION",
512 "TE_TELEPORT",
513 "TE_LAVASPLASH",
514 "TE_SMALLFLASH",
515 "TE_FLAMEJET",
516 "EF_FLAME",
517 "TE_BLOOD",
518 "TE_SPARK",
519 "TE_PLASMABURN",
520 "TE_TEI_G3",
521 "TE_TEI_SMOKE",
522 "TE_TEI_BIGEXPLOSION",
523 "TE_TEI_PLASMAHIT",
524 "EF_STARDUST",
525 "TR_ROCKET",
526 "TR_GRENADE",
527 "TR_BLOOD",
528 "TR_WIZSPIKE",
529 "TR_SLIGHTBLOOD",
530 "TR_KNIGHTSPIKE",
531 "TR_VORESPIKE",
532 "TR_NEHAHRASMOKE",
533 "TR_NEXUIZPLASMA",
534 "TR_GLOWTRAIL",
535 "SVC_PARTICLE"
536};

Referenced by CL_Particles_LoadEffectInfo().

◆ tex_beam

const int tex_beam = 60
static

◆ tex_blooddecal

const int tex_blooddecal[8] = {16, 17, 18, 19, 20, 21, 22, 23}
static

Definition at line 192 of file cl_particles.c.

192{16, 17, 18, 19, 20, 21, 22, 23};

Referenced by CL_ImmediateBloodStain(), R_DrawParticles(), and R_InitBloodTextures().

◆ tex_bloodparticle

const int tex_bloodparticle[8] = {24, 25, 26, 27, 28, 29, 30, 31}
static

Definition at line 193 of file cl_particles.c.

193{24, 25, 26, 27, 28, 29, 30, 31};

Referenced by CL_ParticleEffect_Fallback(), and R_InitBloodTextures().

◆ tex_bubble

const int tex_bubble = 62
static

◆ tex_bulletdecal

const int tex_bulletdecal[8] = {8, 9, 10, 11, 12, 13, 14, 15}
static

Definition at line 191 of file cl_particles.c.

191{8, 9, 10, 11, 12, 13, 14, 15};

Referenced by CL_ParticleEffect_Fallback(), CL_ParticleExplosion(), and R_InitParticleTexture().

◆ tex_particle

◆ tex_raindrop

const int tex_raindrop = 61
static

Definition at line 198 of file cl_particles.c.

Referenced by R_InitParticleTexture().

◆ tex_rainsplash

const int tex_rainsplash = 32
static

Definition at line 194 of file cl_particles.c.

Referenced by CL_NewParticle(), and R_InitParticleTexture().

◆ tex_smoke

const int tex_smoke[8] = {0, 1, 2, 3, 4, 5, 6, 7}
static

Definition at line 190 of file cl_particles.c.

190{0, 1, 2, 3, 4, 5, 6, 7};

Referenced by CL_ParticleEffect_Fallback(), CL_Smoke(), and R_InitParticleTexture().

◆ tex_square

const int tex_square = 33
static

Definition at line 195 of file cl_particles.c.

Referenced by CL_NewQuakeParticle().