Files
quakemapping/mod_xj19/my_progs/part_emitter.qc
2020-01-01 23:35:17 +01:00

1469 lines
66 KiB
Plaintext

/*======================================================================
Particle EMITTER functions
======================================================================*/
float(entity pe_ent) misc_particle_style =
{
pe_ent.start_delay = 1 + (random()*2); // Particle emitter start delay (default)
pe_ent.spr_frame = 1; // Use all sprite frames (Light/Dark)
pe_ent.dpp_name = ""; // DP particle effect name
pe_ent.dpp_wait = 0.1; // Defautlt timer
pe_ent.dpp_rnd = 1; // Random time multiplier
pe_ent.dpp_vel = '0 0 0'; // Velocity direction of particles
pe_ent.part_movetype = MOVETYPE_NOCLIP;
//----------------------------------------------------------------------
// Portal Gate
//----------------------------------------------------------------------
if (pe_ent.part_style == PARTICLE_STYLE_PORTAL) {
pe_ent.spr_name1 = PART_DOTMED_GREY;
pe_ent.spr_name2 = PART_DOTSML_WHITE;
pe_ent.spr_name3 = PART_DOTSML_WHITE;
pe_ent.spr_frame = 3; // Dark frames
pe_ent.part_limit = 100; // High Amount of particles
pe_ent.part_life = 3; // Long life time
pe_ent.part_ofs = '0 0 0'; // No change
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL;
// If the angle is up or down then it is a special case
if (pe_ent.angles_y == -1) {
pe_ent.part_vel = '0 0 20'; // UP direction
pe_ent.dpp_name = DPP_PORTALUP; // particles flying up
}
else if (pe_ent.angles_y == -2) {
pe_ent.part_vel = '0 0 -20'; // DOWN direction
pe_ent.dpp_name = DPP_PORTALDOWN; // smoke falling down
}
else {
// Setup DP portal effects volume size based on initial emitter angle
if (pe_ent.angles_y == 90 || pe_ent.angles_y == 270) {
if (!pe_ent.part_vol) pe_ent.part_vol = '32 0 48'; // Volume (X/Y/Z)
pe_ent.dpp_name = DPP_PORTALSIDE;
}
else {
if (!pe_ent.part_vol) pe_ent.part_vol = '0 32 48'; // Volume (X/Y/Z)
pe_ent.dpp_name = DPP_PORTALFRONT; // default direction
}
// The angle of the particle entity is using the ANGLE key
makevectors(pe_ent.angles);
pe_ent.part_vel = v_forward * 20; // Slow speed away from portal
}
if (!pe_ent.part_velrand) pe_ent.part_velrand = '10 10 4'; // More X/Y wobble
if (!pe_ent.wakeup_dist) pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 4; // High timer (runs all the time)
if (!pe_ent.spawn_base) pe_ent.spawn_base = 0.1; // Fast Spawn rate
if (!pe_ent.spawn_rand) pe_ent.spawn_rand = 0.1; // Spawn rate randomness
pe_ent.dpp_vel = normalize(pe_ent.part_vel); // Particle direction
}
//----------------------------------------------------------------------
// Spiral Jumppad pattern
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_JUMPPAD) {
pe_ent.spr_name1 = PART_DOTMED_GREY;
pe_ent.spr_name2 = PART_DOTSML_WHITE;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 100; // High Amount of particles
pe_ent.part_life = 3; // Long life time
pe_ent.part_ofs = '0 0 0'; // Start below emitter origin
pe_ent.part_velbase = '0 0 12'; // Always go upwards
pe_ent.part_vel = '0 0 32'; // UP direction
pe_ent.part_velrand = '8 8 0'; // Slight wobble
pe_ent.part_vol = '24 24 0'; // Volume around circle pad
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // inside circle volume
pe_ent.wakeup_dist = 1024; // Long range distance
pe_ent.wakeup_timer = 2; // High timer (runs all the time)
pe_ent.spawn_base = 0.05; // Average Spawn rate
pe_ent.spawn_rand = 0.05; // Spawn rate randomness
pe_ent.dpp_name = DPP_JUMPPAD; // streaming up
}
//----------------------------------------------------------------------
// Circular floor pattern (triggered)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_FCIRCLE) {
pe_ent.spr_name1 = PART_TORCH1;
pe_ent.spr_name2 = PART_TORCH2;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 64; // High Amount of particles
pe_ent.part_life = 5; // Long life time
pe_ent.part_ofs = '0 0 1'; // Slightly off floor
pe_ent.part_vel = '0 0 12'; // Slowly move upwards
pe_ent.part_velrand = '4 4 0'; // Slight wobble
// Circle radius/rotation degrees
if (CheckZeroVector(pe_ent.pemit_source.part_vol)) pe_ent.part_vol = '56 17 0';
pe_ent.part_veltype = PARTICLE_ORIGIN_RANDCIRCLE;
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 0.5; // 4x timer
// Fast spawn rate and randomness
if (!pe_ent.pemit_source.spawn_base) pe_ent.spawn_base = 0.1; // Fast Spawn rate
if (!pe_ent.pemit_source.spawn_rand) pe_ent.spawn_rand = 0.2; // Spawn rate randomness
pe_ent.dpp_name = DPP_FCIRCLE; // Circular floor pattern
pe_ent.dpp_rnd = 0.2; // Random time multiplier
}
//----------------------------------------------------------------------
// Forcefield
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_FFIELD) {
if (pe_ent.pemit_source.spr_frame == PARTICLE_BURST_YELLOW) {
pe_ent.spr_name1 = PART_DOTSML_GOLD;
pe_ent.spr_name2 = PART_DOTSML_YELLOW;
pe_ent.spr_name3 = PART_DOTMED_YELLOW;
pe_ent.dpp_name = DPP_FFIELDPARTY;
}
else if (pe_ent.pemit_source.spr_frame == PARTICLE_BURST_GREEN) {
pe_ent.spr_name1 = PART_DOTSML_LGREEN;
pe_ent.spr_name2 = PART_DOTSML_GREEN;
pe_ent.spr_name3 = PART_DOTMED_GREEN;
pe_ent.dpp_name = DPP_FFIELDPARTG;
}
else if (pe_ent.pemit_source.spr_frame == PARTICLE_BURST_RED) {
pe_ent.spr_name1 = PART_DOTSML_GREY;
pe_ent.spr_name2 = PART_DOTSML_RED;
pe_ent.spr_name3 = PART_DOTMED_RED;
pe_ent.dpp_name = DPP_FFIELDPARTR;
}
else if (pe_ent.pemit_source.spr_frame == PARTICLE_BURST_BLUE) {
pe_ent.spr_name1 = PART_DOTSML_BLUE;
pe_ent.spr_name2 = PART_DOTSML_GREY;
pe_ent.spr_name3 = PART_DOTMED_BLUE;
pe_ent.dpp_name = DPP_FFIELDPARTB;
}
else if (pe_ent.pemit_source.spr_frame == PARTICLE_BURST_PURPLE) {
pe_ent.spr_name1 = PART_DOTSML_PURP;
pe_ent.spr_name2 = PART_DOTSML_GREY;
pe_ent.spr_name3 = PART_DOTMED_PURP;
pe_ent.dpp_name = DPP_FFIELDPARTP;
}
else if (pe_ent.pemit_source.spr_frame == PARTICLE_BURST_FIRE) {
pe_ent.spr_name1 = PART_TORCH1;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTMED_GREY;
pe_ent.dpp_name = DPP_FFIELDPARTY;
}
else {
pe_ent.spr_name1 = PART_DOTSML_WHITE;
pe_ent.spr_name2 = PART_DOTSML_GREY;
pe_ent.spr_name3 = PART_DOTMED_GREY;
pe_ent.dpp_name = DPP_FFIELDPARTW;
}
// reset particle sprite frame range to all
pe_ent.spr_frame = 0;
// Particle quantity should be low, allow customization for volume size
if (!pe_ent.pemit_source.part_limit) pe_ent.part_limit = 25;
else pe_ent.part_limit = pe_ent.pemit_source.part_limit;
if (!pe_ent.pemit_source.part_life) pe_ent.part_life = 2;
else pe_ent.part_life = pe_ent.pemit_source.part_life;
if (!pe_ent.pemit_source.part_ofs) pe_ent.part_ofs = '0 0 0';
else pe_ent.part_ofs = pe_ent.pemit_source.part_ofs;
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL;
if (!pe_ent.part_velrand) pe_ent.part_velrand = '4 4 4';
// The volume and direction really need to be set before the
// emitter is setup because the volume maybe switched off
if (CheckZeroVector(pe_ent.pemit_source.part_vol)) pe_ent.part_vol = '8 8 8';
else pe_ent.part_vol = pe_ent.pemit_source.part_vol;
if (CheckZeroVector(pe_ent.pemit_source.part_vel)) pe_ent.part_vel = '0 0 4';
else pe_ent.part_vel = pe_ent.pemit_source.part_vel;
if (!pe_ent.pemit_source.wakeup_dist) pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 4; // High timer (runs all the time)
if (!pe_ent.pemit_source.spawn_base) pe_ent.spawn_base = 0.05; // Fast Spawn rate
if (pe_ent.spawn_base < 0.01) pe_ent.spawn_base = 0.01; // Need minimum
if (!pe_ent.pemit_source.spawn_rand) pe_ent.spawn_rand = 0.1; // Spawn rate randomness
pe_ent.dpp_vel = pe_ent.part_vel;
pe_ent.dpp_wait = 0.01;
pe_ent.dpp_rnd = 0.1;
}
//======================================================================
// Book Phase 1 - closed
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_BOOK) {
pe_ent.spr_name1 = PART_BOOKRUNE1;
pe_ent.spr_name2 = PART_BOOKRUNE2;
if (random()<0.5) pe_ent.spr_name3 = PART_BOOKRUNE1;
else pe_ent.spr_name3 = PART_BOOKRUNE2;
pe_ent.part_limit = 3; // Very Low
pe_ent.part_life = 7; // Long Life
pe_ent.part_ofs = '0 0 10'; // Top of Book
pe_ent.part_vel = '0 0 10'; // Fly up
pe_ent.part_velrand = '4 4 0'; // Slight wobble
pe_ent.part_velrot = 45; // Velocity rotation - y + random(y)
pe_ent.part_vol = '1 1 0'; // Volume (X/Y/Z)
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Close range distance
pe_ent.wakeup_timer = 8; // High timer
pe_ent.spawn_base = 2; // Slow (runs all the time)
pe_ent.spawn_rand = 1; // Spawn rate randomness
if (pe_ent.pemit_source.style == MISCBOOK_BLUE) pe_ent.dpp_name = DPP_BOOKBLUE;
else if (pe_ent.pemit_source.style == MISCBOOK_RED) pe_ent.dpp_name = DPP_BOOKRED;
else pe_ent.dpp_name = DPP_BOOKGOLD;
pe_ent.dpp_wait = 1; // Slow timer
pe_ent.dpp_rnd = 2; // Long pause
}
//----------------------------------------------------------------------
// Book Phase 2 - open
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_OPENBOOK) {
if (random()<0.5) pe_ent.spr_name1 = PART_BOOKRUNE1;
else pe_ent.spr_name1 = PART_BOOKRUNE2;
// Setup particle colour based on book type
if (pe_ent.pemit_source.style == MISCBOOK_BLUE) {
if (random() < 0.5) pe_ent.spr_name2 = PART_DOTMED_BLUE;
else pe_ent.spr_name2 = PART_DOTSML_BLUE;
pe_ent.spr_name3 = PART_DOTSML_WHITE;
pe_ent.dpp_name = DPP_OPENBOOKBLUE;
}
else if (pe_ent.pemit_source.style == MISCBOOK_RED) {
if (random() < 0.5) pe_ent.spr_name2 = PART_DOTMED_RED;
else pe_ent.spr_name2 = PART_DOTSML_RED;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.dpp_name = DPP_OPENBOOKRED;
}
else {
if (random() < 0.5) pe_ent.spr_name2 = PART_DOTMED_YELLOW;
else pe_ent.spr_name2 = PART_DOTSML_YELLOW;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.dpp_name = DPP_OPENBOOKGOLD;
}
pe_ent.part_limit = 30; // Average
pe_ent.part_life = 7; // Long Life
pe_ent.part_ofs = '0 0 4'; // Pages of Book
pe_ent.part_vel = '0 0 10'; // Fly up
pe_ent.part_velrand = '4 4 0'; // Slight wobble
pe_ent.part_velrot = 45; // Velocity rotation - y + random(y)
pe_ent.part_vol = '8 8 0'; // Volume (X/Y/Z)
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Close range distance
pe_ent.wakeup_timer = 4; // High timer
pe_ent.spawn_base = 0.1; // Fast (particles)
pe_ent.spawn_rand = 0.3; // Spawn rate randomness
pe_ent.dpp_wait = 0.5; // Fast timer
pe_ent.dpp_rnd = 2; // Long pause
}
//======================================================================
// Electric Beam Particle Stream (code triggered)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_ELECTRIC) {
pe_ent.spr_name1 = PART_DOTMED_BLUE;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_BLUE;
pe_ent.part_limit = 100; // Maximum particles
pe_ent.part_life = 1; // Short Lifetime
pe_ent.part_ofs = '0 0 0'; // center of target object
pe_ent.part_vel = '50 0 0'; // Speed of particles
pe_ent.part_velrand = '0 0 16'; // Vertical wobble
pe_ent.part_vol = '8 8 8'; // Volume (X/Y/Z)
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Long range distance
pe_ent.wakeup_timer = 0.2; // Small change on distance timer
pe_ent.spawn_base = 0.01; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_ELECTRIC; // directional particle stream
pe_ent.dpp_rnd = 0; // NO Random time multiplier
}
//----------------------------------------------------------------------
// Torches Flames (slow start)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_FLAMET) {
pe_ent.start_delay = 3 + (random()*8);
pe_ent.spr_name1 = PART_TORCH1; // Embers - Red/Yellow
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.part_limit = 8; // Minimal amount of particles
pe_ent.part_life = 2; // Short Life
pe_ent.part_ofs = '0 0 12'; // Top of wood
pe_ent.part_vel = '0 0 10'; // Fly up
pe_ent.part_velrand = '4 4 0'; // Slight wobble
pe_ent.part_vol = '1 1 0'; // Volume (X/Y/Z)
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
if (pe_ent.pemit_source.wakeup_dist < 1) pe_ent.wakeup_dist = 384;
else pe_ent.wakeup_dist = pe_ent.pemit_source.wakeup_dist;
if (pe_ent.pemit_source.wakeup_timer < 1) pe_ent.wakeup_timer = 8;
else pe_ent.wakeup_timer = pe_ent.pemit_source.wakeup_timer;
pe_ent.spawn_base = 0.25; // Spawn rate base (runs all the time)
pe_ent.spawn_rand = 0.25; // Spawn rate randomness
pe_ent.dpp_name = DPP_FLAMET; // smoke and particles floating up
pe_ent.dpp_wait = 1; // Slow timer
}
//----------------------------------------------------------------------
// Small Flames (slow start)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_FLAMES) {
pe_ent.start_delay = 3 + (random()*8);
pe_ent.spr_name1 = PART_TORCH1; // Embers - Red/Yellow
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.part_limit = 8; // Minimal amount of particles
pe_ent.part_life = 2; // Short Life
pe_ent.part_ofs = '0 0 0'; // Bottom of flame
pe_ent.part_vel = '0 0 10'; // Fly up
pe_ent.part_velrand = '4 4 0'; // Slight wobble
pe_ent.part_vol = '1 1 0'; // Volume (X/Y/Z)
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
if (pe_ent.pemit_source.wakeup_dist < 1) pe_ent.wakeup_dist = 384;
else pe_ent.wakeup_dist = pe_ent.pemit_source.wakeup_dist;
if (pe_ent.pemit_source.wakeup_timer < 1) pe_ent.wakeup_timer = 6;
else pe_ent.wakeup_timer = pe_ent.pemit_source.wakeup_timer;
pe_ent.spawn_base = 0.25; // Spawn rate base (runs all the time)
pe_ent.spawn_rand = 0.25; // Spawn rate randomness
pe_ent.dpp_name = DPP_FLAMES; // smoke and particles floating up
pe_ent.dpp_wait = 1; // Slow timer
}
//----------------------------------------------------------------------
// Large Flames (high particle count)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_FLAMEL) {
pe_ent.spr_name1 = PART_TORCH1;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.part_limit = 100; // Large amount of active particles
if (pe_ent.pemit_source.part_life < 1) pe_ent.part_life = 8;
else pe_ent.part_life = pe_ent.pemit_source.part_life;
pe_ent.part_ofs = '0 0 0'; // Bottom of flame
pe_ent.part_vel = '0 0 12'; // Fly up
pe_ent.part_velrand = '4 4 0'; // Slight wobble
pe_ent.part_vol = '4 4 0'; // Volume (X/Y/Z)
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
if (pe_ent.pemit_source.wakeup_dist < 1) pe_ent.wakeup_dist = 768;
else pe_ent.wakeup_dist = pe_ent.pemit_source.wakeup_dist;
if (pe_ent.pemit_source.wakeup_timer < 1) pe_ent.wakeup_timer = 1;
else pe_ent.wakeup_timer = pe_ent.pemit_source.wakeup_timer;
pe_ent.spawn_base = 0.05; // Frequent (runs all the time)
pe_ent.spawn_rand = 0.1; // Spawn rate randomness
pe_ent.dpp_name = DPP_FLAMEL; // smoke and particles floating up
}
//----------------------------------------------------------------------
// Skill Particle Stream (Designed for 4 sides of pillar)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_SKILL) {
pe_ent.spr_name1 = PART_DOTMED_RED;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_RED;
pe_ent.part_limit = 35; // Maximum particles
pe_ent.part_life = 2; // Long life
pe_ent.part_ofs = '0 0 0'; // center of target object
// The angle of the particle entity is using the ANGLE key
makevectors(pe_ent.pemit_source.angles);
pe_ent.part_vel = v_forward * 10; // Slow speed away from skill column
pe_ent.part_vol = '4 4 4'; // Volume (X/Y/Z)
pe_ent.part_velrand = '4 4 8'; // Volume wobble
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Long range distance
pe_ent.wakeup_timer = 1; // Small change on distance timer
pe_ent.spawn_base = 0.01; // Fast Spawn rate
pe_ent.spawn_rand = 0.2; // Spawn rate randomness
pe_ent.dpp_name = DPP_SKILLPILLAR; // Directional particle stream
pe_ent.dpp_rnd = 0; // NO Random time multiplier
pe_ent.dpp_vel = normalize(v_forward); // Particle direction
}
//----------------------------------------------------------------------
// Skill Particle Stream (Designed for Silver Key Doors)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_BSKILL) {
pe_ent.spr_name1 = PART_DOTMED_BLUE;
pe_ent.spr_name2 = PART_DOTSML_GREY;
pe_ent.spr_name3 = PART_DOTSML_BLUE;
pe_ent.part_limit = 35; // Maximum particles
pe_ent.part_life = 2; // Long life
pe_ent.part_ofs = '0 0 0'; // center of target object
// The angle of the particle entity is using the ANGLE key
makevectors(pe_ent.pemit_source.angles);
pe_ent.part_vel = v_forward * 10; // Slow speed away from skill column
pe_ent.part_vol = '4 4 4'; // Volume (X/Y/Z)
pe_ent.part_velrand = '4 4 8'; // Volume wobble
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Long range distance
pe_ent.wakeup_timer = 1; // Small change on distance timer
pe_ent.spawn_base = 0.01; // Fast Spawn rate
pe_ent.spawn_rand = 0.2; // Spawn rate randomness
pe_ent.dpp_name = DPP_BSKILLPILLAR; // Directional particle stream
pe_ent.dpp_rnd = 0; // NO Random time multiplier
pe_ent.dpp_vel = normalize(v_forward); // Particle direction
}
//----------------------------------------------------------------------
// Skill Particle Stream (Designed for Green Key Doors)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_GSKILL) {
pe_ent.spr_name1 = PART_DOTSML_GREEN;
pe_ent.spr_name2 = PART_DOTMED_GREEN;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.part_limit = 35; // Maximum particles
pe_ent.part_life = 2; // Long life
pe_ent.part_ofs = '0 0 0'; // center of target object
// The angle of the particle entity is using the ANGLE key
makevectors(pe_ent.pemit_source.angles);
pe_ent.part_vel = v_forward * 10; // Slow speed away from skill column
pe_ent.part_vol = '4 4 4'; // Volume (X/Y/Z)
pe_ent.part_velrand = '4 4 8'; // Volume wobble
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Long range distance
pe_ent.wakeup_timer = 1; // Small change on distance timer
pe_ent.spawn_base = 0.01; // Fast Spawn rate
pe_ent.spawn_rand = 0.2; // Spawn rate randomness
pe_ent.dpp_name = DPP_GSKILLPILLAR; // Directional particle stream
pe_ent.dpp_rnd = 0; // NO Random time multiplier
pe_ent.dpp_vel = normalize(v_forward); // Particle direction
}
//----------------------------------------------------------------------
// Skill Particle Stream (Designed for Purple Key Doors)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_PSKILL) {
pe_ent.spr_name1 = PART_DOTSML_PURP;
pe_ent.spr_name2 = PART_DOTMED_PURP;
pe_ent.spr_name3 = PART_DOTSML_PURP;
pe_ent.part_limit = 35; // Maximum particles
pe_ent.part_life = 2; // Long life
pe_ent.part_ofs = '0 0 0'; // center of target object
// The angle of the particle entity is using the ANGLE key
makevectors(pe_ent.pemit_source.angles);
pe_ent.part_vel = v_forward * 10; // Slow speed away from skill column
pe_ent.part_vol = '4 4 4'; // Volume (X/Y/Z)
pe_ent.part_velrand = '4 4 8'; // Volume wobble
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Long range distance
pe_ent.wakeup_timer = 1; // Small change on distance timer
pe_ent.spawn_base = 0.01; // Fast Spawn rate
pe_ent.spawn_rand = 0.2; // Spawn rate randomness
pe_ent.dpp_name = DPP_PSKILLPILLAR; // Directional particle stream
pe_ent.dpp_rnd = 0; // NO Random time multiplier
pe_ent.dpp_vel = normalize(v_forward); // Particle direction
}
//----------------------------------------------------------------------
// Particles raising up around an altar
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_ALTAR) {
if (pe_ent.pemit_source.cnt == 1) {
pe_ent.spr_name1 = PART_DOTMED_GREY;
pe_ent.spr_name2 = PART_DOTSML_WHITE;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.dpp_name = DPP_ALTARGREY; // floating upwards
}
else {
pe_ent.spr_name1 = PART_DOTMED_RED;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_RED;
pe_ent.dpp_name = DPP_ALTARRED; // floating upwards
}
pe_ent.part_limit = 100; // Maximum particles
pe_ent.part_life = 5; // Long life
pe_ent.part_ofs = '0 0 0'; // center of target object
if (CheckZeroVector(pe_ent.pemit_source.part_vel)) pe_ent.part_vel = '0 0 12';
pe_ent.part_velrand = '4 4 12'; // Slight wobble
pe_ent.part_vol = '64 64 0'; // Volume (X/Y/Z)
if (pe_ent.pemit_source.t_length > 0)
pe_ent.part_vol_x = pe_ent.pemit_source.t_length;
if (pe_ent.pemit_source.t_width > 0)
pe_ent.part_vol_y = pe_ent.pemit_source.t_width;
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Close range distance
pe_ent.wakeup_timer = 4; // High timer
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0.1; // Spawn rate randomness
}
//----------------------------------------------------------------------
// DP ONLY - velocity directional smoke
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_SMOKE) {
pe_ent.dpp_only = TRUE;
if (pe_ent.pemit_source.exactskin == 0) pe_ent.dpp_name = DPP_VELSMOKEGREY1;
else if (pe_ent.pemit_source.exactskin == 1) pe_ent.dpp_name = DPP_VELSMOKEGREY2;
else if (pe_ent.pemit_source.exactskin == 2) pe_ent.dpp_name = DPP_VELSMOKEWHITE;
else if (pe_ent.pemit_source.exactskin == 3) pe_ent.dpp_name = DPP_VELSMOKETOXIC;
else if (pe_ent.pemit_source.exactskin == 4) pe_ent.dpp_name = DPP_VELSMOKEGREEN;
else if (pe_ent.pemit_source.exactskin == 5) pe_ent.dpp_name = DPP_VELSMOKEPURPLE;
else if (pe_ent.pemit_source.exactskin == 6) pe_ent.dpp_name = DPP_VELSMOKERED;
else if (pe_ent.pemit_source.exactskin == 7) pe_ent.dpp_name = DPP_VELSMOKEFIRE;
pe_ent.dpp_rnd = pe_ent.pemit_source.delay;
pe_ent.dpp_wait = pe_ent.pemit_source.wait;
pe_ent.dpp_vel = pe_ent.pemit_source.movedir * pe_ent.pemit_source.height;
}
//======================================================================
// Items
//======================================================================
else if (pe_ent.part_style == PARTICLE_STYLE_RESPAWN) {
pe_ent.start_delay = 0.1; // Particle emitter start delay
pe_ent.spr_name1 = PART_DOTSML_YELLOW;
pe_ent.spr_name2 = PART_DOTSML_GREY;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 25; // Variable, depends on spawn rate
pe_ent.part_life = 1; // Short life time
pe_ent.part_ofs = '0 0 1'; // Custom for each item
pe_ent.part_vel = '0 0 10'; // Slowly move upwards
pe_ent.part_vol = '16 16 0'; // Flat base of model
pe_ent.part_velrand = '4 4 6'; // Slight wobble
pe_ent.part_veltype = PARTICLE_ORIGIN_VOL; // Inside volume
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.05; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_RESPAWN; // Particles floating up, starts slow
pe_ent.dpp_rnd = 0; // NO Random time multiplier
}
//----------------------------------------------------------------------
// Items - Mega Health
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_MEGAH) {
pe_ent.spr_name1 = PART_DOTSML_WHITE;
pe_ent.spr_name2 = PART_DOTMED_RED;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 3.5; // Short life time
pe_ent.part_ofs = '0 0 16'; // Move up to the top of the key
pe_ent.part_vel = '12 12 4'; // Speed of particles outwards
pe_ent.part_velrand = '0 0 8'; // Slight wobble
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.05; // Fast Spawn rate
pe_ent.spawn_rand = 0.1; // Spawn rate randomness
pe_ent.dpp_name = DPP_MEGAH; // Particles drifting out from center
}
//----------------------------------------------------------------------
// Item - Armor (Green/Yellow/Red)
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_ARMOR) {
if (pe_ent.pemit_source.items & IT_ARMOR1) {
pe_ent.spr_name1 = PART_DOTSML_LGREEN;
pe_ent.spr_name2 = PART_DOTMED_LGREEN;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.dpp_name = DPP_ARMOR1; // Green particles + smoke
}
else if (pe_ent.pemit_source.items & IT_ARMOR2) {
if (pe_ent.pemit_source.spawnflags & ARMOR_BLUE) {
pe_ent.spr_name1 = PART_DOTSML_BLUE;
pe_ent.spr_name2 = PART_DOTMED_BLUE;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.dpp_name = DPP_ARMOR2BLUE;// Blue particles + smoke
}
else {
pe_ent.spr_name1 = PART_DOTSML_YELLOW;
pe_ent.spr_name2 = PART_DOTMED_YELLOW;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.dpp_name = DPP_ARMOR2; // Yellow particles + smoke
}
}
else {
pe_ent.spr_name1 = PART_DOTSML_RED;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTMED_RED;
pe_ent.dpp_name = DPP_ARMOR3; // Red particles + smoke
}
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2.75; // Short life time
pe_ent.part_ofs = '0 0 24'; // Move up to middle of Suit
pe_ent.part_vel = '6 6 4'; // Speed of particles outwards
pe_ent.part_velbase = '0 0 12'; // Move upwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0.2; // Spawn rate randomness
}
//----------------------------------------------------------------------
// Item - Silver Key
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_KEYSILVER) {
pe_ent.spr_name1 = PART_DOTSML_BLUE;
pe_ent.spr_name2 = PART_DOTSML_BLUE;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 20'; // Move up to the top of the key
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_KEYSILVER; // Blue particles from top of key
}
//----------------------------------------------------------------------
// Item - Gold Key
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_KEYGOLD) {
pe_ent.spr_name1 = PART_DOTSML_GOLD;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 20'; // Move up to the top of the key
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_KEYGOLD; // Yellow particles from top of key
}
//----------------------------------------------------------------------
// Item - Generic Red Key
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_KEYRED) {
pe_ent.spr_name1 = PART_DOTSML_RED;
pe_ent.spr_name2 = PART_DOTMED_RED;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 20'; // Move up to the top of the key
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_KEYRED; // Red particles from top of key
}
//----------------------------------------------------------------------
// Item - Generic Green Key
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_KEYGREEN) {
pe_ent.spr_name1 = PART_DOTSML_GREEN;
pe_ent.spr_name2 = PART_DOTMED_GREEN;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 20'; // Move up to the top of the key
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_KEYGREEN; // Green particles from top of key
}
//----------------------------------------------------------------------
// Item - Generic Purple Key
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_KEYPURPLE) {
pe_ent.spr_name1 = PART_DOTSML_PURP;
pe_ent.spr_name2 = PART_DOTMED_PURP;
pe_ent.spr_name3 = PART_DOTSML_PURP;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 20'; // Move up to the top of the key
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_KEYPURPLE; // Purple particles from top of key
}
//----------------------------------------------------------------------
// Item - Generic White Key
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_KEYWHITE) {
pe_ent.spr_name1 = PART_DOTSML_GREY;
pe_ent.spr_name2 = PART_DOTMED_GREY;
pe_ent.spr_name3 = PART_DOTSML_WHITE;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 20'; // Move up to the top of the key
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_KEYWHITE; // White particles from top of key
}
//----------------------------------------------------------------------
// Item - Sigil / Rune
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_SIGIL) {
pe_ent.spr_name1 = PART_DOTMED_PURP;
pe_ent.spr_name2 = PART_DOTSML_PURP;
pe_ent.spr_name3 = PART_DOTSML_PURP;
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 1.5; // Short life time
pe_ent.part_ofs = '0 0 16'; // Move up to center of sigil
pe_ent.part_vel = '8 8 16'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_SIGIL; // Purple particles from center
}
//----------------------------------------------------------------------
// Item - Custom Backpack
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_BACKPACK) {
if (pe_ent.pemit_source.exactskin == 1) {
pe_ent.spr_name1 = PART_DOTSML_GREEN;
pe_ent.spr_name2 = PART_DOTMED_GREEN;
pe_ent.spr_name3 = PART_DOTSML_GREEN;
pe_ent.dpp_name = DPP_BACKPACKG; // Green
}
else if (pe_ent.pemit_source.exactskin == 2) {
pe_ent.spr_name1 = PART_DOTSML_BLUE;
pe_ent.spr_name2 = PART_DOTMED_BLUE;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.dpp_name = DPP_BACKPACKB; // Blue
}
else if (pe_ent.pemit_source.exactskin == 3) {
pe_ent.spr_name1 = PART_DOTSML_RED;
pe_ent.spr_name2 = PART_DOTMED_RED;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.dpp_name = DPP_BACKPACKR; // Red
}
else if (pe_ent.pemit_source.exactskin == 4) {
pe_ent.spr_name1 = PART_DOTSML_GOLD;
pe_ent.spr_name2 = PART_DOTSML_GOLD;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.dpp_name = DPP_BACKPACKY; // Yellow
}
else if (pe_ent.pemit_source.exactskin == 5) {
pe_ent.spr_name1 = PART_DOTSML_GREEN;
pe_ent.spr_name2 = PART_DOTMED_GREEN;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.dpp_name = DPP_BACKPACKG; // Green
}
else {
pe_ent.spr_name1 = PART_DOTMED_GREY;
pe_ent.spr_name2 = PART_DOTSML_WHITE;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.dpp_name = DPP_BACKPACK; // Default Grey/White
}
pe_ent.part_limit = 50; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 12'; // Middle of pack
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
}
//======================================================================
// Artifacts
//======================================================================
//----------------------------------------------------------------------
// Artifact - Environmental Suit
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_SUIT) {
pe_ent.spr_name1 = PART_DOTSML_GREEN;
pe_ent.spr_name2 = PART_DOTMED_GREEN;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 2.75; // Short life time
pe_ent.part_ofs = '0 0 28'; // Move up to belt of Suit (chest=32)
pe_ent.part_vel = '8 8 3'; // Speed of particles outwards
pe_ent.part_velbase = '0 0 12'; // Move upwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_SUIT; // Green/Yellow particles from center
pe_ent.dpp_wait = 0.5; // Slow timer
}
//----------------------------------------------------------------------
// Artifact - Pentagram
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_PENT) {
pe_ent.spr_name1 = PART_DOTSML_RED;
pe_ent.spr_name2 = PART_DOTMED_RED;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 2.5; // Short life time
pe_ent.part_ofs = '0 0 16'; // Move up to center of Pent
pe_ent.part_vel = '12 12 12'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_PENT; // Red/Gold particles from center
pe_ent.dpp_wait = 1; // Slow timer
}
//----------------------------------------------------------------------
// Artifact - Shadow Ring
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_SRING) {
pe_ent.spr_name1 = PART_DOTSML_YELLOW;
pe_ent.spr_name2 = PART_DOTSML_WHITE;
pe_ent.spr_name3 = PART_DOTSML_GOLD;
pe_ent.part_limit = 35; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 6'; // Move up to the top of the amulet
pe_ent.part_vel = '8 8 3'; // Speed of particles outwards
pe_ent.part_velbase = '0 0 -12'; // Move downwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0.1; // Spawn rate randomness
pe_ent.dpp_name = DPP_SRING; // White/Gold particles from center
}
//----------------------------------------------------------------------
// Artifact - Quad Damage
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_QUAD) {
pe_ent.spr_name1 = PART_DOTMED_BLUE;
pe_ent.spr_name2 = PART_DOTSML_WHITE;
pe_ent.spr_name3 = PART_DOTSML_BLUE;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 1.5; // Short life time
pe_ent.part_ofs = '0 0 16'; // Move up to center of quad
pe_ent.part_vel = '10 10 16'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_QUAD; // Blue/White particles from center
}
//----------------------------------------------------------------------
// Artifact - Tome of Power
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_TOMEOFP) {
pe_ent.spr_name1 = PART_DOTSML_GOLD;
pe_ent.spr_name2 = PART_DOTSML_YELLOW;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 2; // Short life time
pe_ent.part_ofs = '0 0 16'; // Lower part of book
pe_ent.part_vel = '16 16 8'; // Speed of particles outwards
pe_ent.part_velbase = '0 0 -4'; // Move downward
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.05; // Fast Spawn rate
pe_ent.spawn_rand = 0.05; // Spawn rate randomness
pe_ent.dpp_name = DPP_TOMEOFP; // Yellow particles
pe_ent.dpp_wait = 0.5; // Slow timer
}
//----------------------------------------------------------------------
// Artifact - Sharp Shooter
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_SHARP) {
if (pe_ent.pemit_source.exactskin == 1) {
pe_ent.spr_name1 = PART_DOTSML_GREEN;
pe_ent.spr_name2 = PART_DOTMED_GREEN;
pe_ent.spr_name3 = PART_DOTSML_YELLOW;
pe_ent.dpp_name = DPP_SHARPG; // Green particles from center
}
else {
pe_ent.spr_name1 = PART_DOTMED_PURP;
pe_ent.spr_name2 = PART_DOTSML_PURP;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.dpp_name = DPP_SHARP; // Purple particles from center
}
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 1.5; // Short life time
pe_ent.part_ofs = '0 0 16'; // Move up to center
pe_ent.part_vel = '10 10 16'; // Speed of particles outwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
}
//----------------------------------------------------------------------
// Artifact - Nail Piercer
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_PIERCE) {
pe_ent.spr_name1 = PART_DOTMED_PURP;
pe_ent.spr_name2 = PART_DOTSML_PURP;
pe_ent.spr_name3 = PART_DOTSML_GREY;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 1.5; // Short life time
pe_ent.part_ofs = '0 0 16'; // Move up to center
pe_ent.part_vel = '8 8 4'; // Speed of particles outwards
pe_ent.part_velbase = '0 0 12'; // Move upwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_PIERCE; // Purple particles from center
}
//----------------------------------------------------------------------
// Artifact - Wet Suit
//----------------------------------------------------------------------
else if (pe_ent.part_style == PARTICLE_STYLE_WETSUIT) {
pe_ent.spr_name1 = PART_DOTSML_BLUE;
pe_ent.spr_name2 = PART_DOTMED_BLUE;
pe_ent.spr_name3 = PART_DOTSML_WHITE;
pe_ent.part_limit = 75; // High Amount of particles
pe_ent.part_life = 2.75; // Short life time
pe_ent.part_ofs = '0 0 28'; // Move up to belt of Suit (chest=32)
pe_ent.part_vel = '8 8 3'; // Speed of particles outwards
pe_ent.part_velbase = '0 0 12'; // Move upwards
pe_ent.part_veltype = PARTICLE_ORIGIN_CENTER; // Explosion
pe_ent.wakeup_dist = 768; // Mid range distance
pe_ent.wakeup_timer = 1; // Medium timer (runs all the time)
pe_ent.spawn_base = 0.1; // Fast Spawn rate
pe_ent.spawn_rand = 0; // Spawn rate randomness
pe_ent.dpp_name = DPP_WETSUIT; // Blue/White particles raising up
pe_ent.dpp_wait = 0.5; // Slow timer
}
//======================================================================
// Weather System
//======================================================================
else if (pe_ent.part_style == PARTICLE_STYLE_WEATHER) {
pe_ent.part_limit = pe_ent.pemit_source.count;
pe_ent.part_vel = '0 0 0';
pe_ent.part_vel_z = pe_ent.pemit_source.speed;
pe_ent.part_velrand = pe_ent.pemit_source.v_angle;
pe_ent.wakeup_dist = pe_ent.pemit_source.wakeup_dist;
pe_ent.wakeup_timer = pe_ent.pemit_source.wakeup_timer;
pe_ent.spawn_base = 0.1; // Default timer
pe_ent.spawn_rand = 0; // No spawn rate randomness
}
//----------------------------------------------------------------------
// No style defined - ERROR!!!!!
//----------------------------------------------------------------------
else {
dprint("\b[PEMITTER]\b Style no ("); dprint(ftos(pe_ent.part_style));
dprint(") not valid!!!");
pe_ent.part_style = PARTICLE_STYLE_EMPTY; // empty definition
spawn_marker(pe_ent.origin, SPNMARK_YELLOW);// Visual problem
}
// return any error conditions; 0=ERROR
return pe_ent.part_style;
};
//----------------------------------------------------------------------
void(entity pe_ent) misc_particle_off =
{
// Double check dealing with a particle emitter?
if (pe_ent.classtype != CT_PARTICLEEMIT) return;
if (pe_ent.state == STATE_OFF) return;
// The particle emitter is still being setup, remember state for later
if (pe_ent.state == STATE_SETUP) {
pe_ent.spawnflags = PARTICLE_START_OFF;
return;
}
pe_ent.state = STATE_OFF;
pe_ent.estate = ESTATE_OFF;
// Setup a particle explosion on floor circles when they are triggered off
if (pe_ent.part_style == PARTICLE_STYLE_FCIRCLE) {
particle_ring(pe_ent.origin, '0 0 4', '4 4 16', pe_ent.part_vol_x+8, pe_ent.part_limit, pe_ent.part_life, 4 );
particle_ring(pe_ent.origin, '0 0 4', '0 0 12', pe_ent.part_vol_x-4, pe_ent.part_limit, pe_ent.part_life, 1 );
}
};
//----------------------------------------------------------------------
void() misc_particle_use =
{
// Have particles been enabled via serverflags?
if (query_configflag(SVR_PARTICLES) != SVR_PARTICLES) return;
// If particle still not setup toggle spawnflags instead
if (self.state == STATE_SETUP) {
if (self.spawnflags & PARTICLE_START_ON) self.spawnflags = PARTICLE_START_OFF;
else self.spawnflags = PARTICLE_START_ON;
return;
}
// Double check for particle style setup correctly
if (self.part_style == PARTICLE_STYLE_EMPTY) return;
// Toggle shooter on/off
if (self.state == STATE_OFF) {
self.state = STATE_ON;
self.estate = ESTATE_ON;
// Is DP particles active?)
if ((ext_dppart || self.dpp_only) && query_configflag(SVR_SPRPARTON) == FALSE && world.sprite_particles == FALSE) {
// decide between particle types
if (self.part_style == PARTICLE_STYLE_FCIRCLE) emitdpp_fcircle();
else if (self.part_style == PARTICLE_STYLE_WEATHER) {
// Check if particle effects are available from the engine
if (!ext_dpsnow || !ext_dprain) return;
emitepp_weather();
}
else emitdpp_particle();
}
// Pixel goodness particles
else {
// Weather effects not supported on Fitz/QS engines
if (self.part_style == PARTICLE_STYLE_WEATHER) return;
else emit_particle();
}
}
else misc_particle_off(self);
};
//----------------------------------------------------------------------
void(entity pe_ent) misc_particle_on =
{
// Double check dealing with a particle emitter?
if (pe_ent.classtype != CT_PARTICLEEMIT) return;
if (pe_ent.state == STATE_ON) return;
// The particle emitter is still being setup, remember state for later
if (pe_ent.state == STATE_SETUP) {
pe_ent.spawnflags = PARTICLE_START_ON;
return;
}
pe_ent.state = STATE_OFF;
pe_ent.think = misc_particle_use;
pe_ent.nextthink = time + TIME_MINTICK;
};
//----------------------------------------------------------------------
void(entity pe_ent, float partemit_style) misc_particle_update =
{
// Double check dealing with a particle emitter?
if (pe_ent.classtype != CT_PARTICLEEMIT) return;
if (pe_ent.state == STATE_SETUP) return;
if (pe_ent.part_style == PARTICLE_STYLE_EMPTY) return;
pe_ent.part_style = partemit_style;
if (misc_particle_style(pe_ent) == FALSE)
dprint("\b[MISC_PARTICLE]\b Error updating emitter!");
};
//----------------------------------------------------------------------
void() misc_particle_switch_on = { misc_particle_on(self); };
void() misc_particle_switch_off = { misc_particle_off(self); };
void() misc_particle_switch_disable = { self.state = STATE_OFF; };
//----------------------------------------------------------------------
void() misc_particle_finishsetup =
{
// Was the particle emitter setup correctly?
if (self.part_style != PARTICLE_STYLE_EMPTY) {
self.circular_angle = 0; // Starting circular angle
self.state = STATE_OFF; // Initial state
self.estate = ESTATE_OFF;
// Setup entity state wrapper if targetname exists
if (self.targetname != "") self.use = entity_state_use;
else self.use = misc_particle_use;
self.estate_on = misc_particle_switch_on;
self.estate_off = misc_particle_switch_off;
self.estate_disable = misc_particle_switch_disable;
self.estate_use = misc_particle_use;
// Delay start of particle emitter so if it needs to be switched off
// other functions can catch it and save switching states quickly
if (self.spawnflags & PARTICLE_START_ON) misc_particle_use();
}
};
//----------------------------------------------------------------------
void() misc_particle_delay =
{
// If target setup, find it and store entity
if (self.target != "") self.pemit_target = find(world, targetname, self.target);
if (!self.pemit_target) self.target = "";
if (!self.start_delay) self.start_delay = 1 + (random()*2);
self.nextthink = time + self.start_delay;
self.think = misc_particle_finishsetup;
};
//----------------------------------------------------------------------
void() misc_particletemplate = {
self.classtype = CT_PARTICLETEMP;
// make sure any sprite assets used are pre-cached ready
if (self.spr_name1 != "") precache_model(self.spr_name1);
if (self.spr_name2 != "") precache_model(self.spr_name2);
if (self.spr_name3 != "") precache_model(self.spr_name3);
};
//----------------------------------------------------------------------
void() misc_particle_copytemplate =
{
local entity fdest;
// Cycle through list for TARGET2 template
fdest = find (world, targetname, self.target2);
while(fdest) {
if (fdest.classtype == CT_PARTICLETEMP) {
self.owner = fdest;
fdest = world;
}
else fdest = find(fdest, targetname, self.target2);
}
// Is the particle template missing?
if (!self.owner) {
dprint("\b[MISC_PARTICLE]\b Missing target template!\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
return;
}
// Custom particle setup defined in map
self.part_style = PARTICLE_STYLE_CUSTOM;
// Copy over all the DEFINED data from the template
// Fill in any gaps with default data (based on quad)
if (self.owner.spr_name1) self.spr_name1 = self.owner.spr_name1;
else self.spr_name1 = PART_DOTMED_BLUE;
if (self.owner.spr_name2) self.spr_name2 = self.owner.spr_name2;
else self.spr_name2 = PART_DOTSML_WHITE;
if (self.owner.spr_name3) self.spr_name3 = self.owner.spr_name3;
else self.spr_name3 = PART_DOTSML_BLUE;
// Particle quantity, life, direction, rotation and volume
if (self.owner.part_movetype) self.part_movetype = self.owner.part_movetype;
else self.part_movetype = MOVETYPE_NOCLIP;
if (self.owner.part_limit) self.part_limit = self.owner.part_limit;
else self.part_limit = 25;
if (self.owner.part_life) self.part_life = self.owner.part_life;
else self.part_life = 1;
if (self.owner.part_ofs) self.part_ofs = self.owner.part_ofs;
else self.part_ofs = '0 0 0';
if (self.owner.part_veltype) self.part_veltype = self.owner.part_veltype;
else self.part_veltype = PARTICLE_ORIGIN_CENTER;
if (self.owner.part_vel) self.part_vel = self.owner.part_vel;
if (self.owner.part_velbase) self.part_velbase = self.owner.part_velbase;
if (self.owner.part_velrand) self.part_velrand = self.owner.part_velrand;
if (self.owner.part_velrot) self.part_velrot = self.owner.part_velrot;
if (self.owner.part_vol) self.part_vol = self.owner.part_vol;
// Particle spawn timing and wakeup distance
if (self.owner.wakeup_dist) self.wakeup_dist = self.owner.wakeup_dist;
else self.wakeup_dist = 1024;
if (self.owner.wakeup_timer) self.wakeup_timer = self.owner.wakeup_timer;
else self.wakeup_timer = 1;
if (self.wakeup_timer < TIME_MINTICK) self.wakeup_timer = TIME_MINTICK;
if (self.owner.spawn_base) self.spawn_base = self.owner.spawn_base;
else self.spawn_base = 0.1;
if (self.spawn_base < TIME_MINTICK) self.spawn_base = TIME_MINTICK;
if (self.owner.spawn_rand) self.spawn_rand = self.owner.spawn_rand;
else self.spawn_rand = 0;
// Particle setup for DarkPlaces
if (self.owner.dpp_name) self.dpp_name = self.owner.dpp_name;
else self.dpp_name = "";
if (self.owner.dpp_wait) self.dpp_wait = self.owner.dpp_wait;
else self.dpp_wait = 0.1;
if (self.dpp_wait < TIME_MINTICK) self.dpp_wait = TIME_MINTICK;
if (self.owner.dpp_rnd) self.dpp_rnd = self.owner.dpp_rnd;
else self.dpp_rnd = 0;
if (self.owner.dpp_vel) self.dpp_vel = self.owner.dpp_vel;
else self.dpp_vel = '0 0 0';
// Setup particle states
misc_particle_delay();
};
//----------------------------------------------------------------------
void() misc_particle_setup =
{
// Setup Particle styles (pre-defined)
if (misc_particle_style(self) != PARTICLE_STYLE_EMPTY)
misc_particle_delay();
};
//----------------------------------------------------------------------
// Entry point for code to spawn particle emitter
// source - starting point for particles
// target - destination (can be self/world to spawn at origin)
// style - type of particle to create (check styles above)
// spawnf - spawnflag values (startoff)
//----------------------------------------------------------------------
entity(entity pe_source, entity pe_target, float pe_style, float pe_spawnf) spawn_pemitter =
{
local entity new_pe;
new_pe = spawn();
new_pe.classtype = CT_PARTICLEEMIT;
new_pe.state = STATE_SETUP;
new_pe.pemit_source = pe_source;
if (pe_source != pe_target) new_pe.pemit_target = pe_target;
// Setup a random number on source entity for linking
// If the source entity is deleted this number will change
gen_unique_no(self);
new_pe.entno_unique = self.entno_unique;
// Check for bmodel origin first
if (pe_source.bsporigin) new_pe.origin = bmodel_origin(pe_source);
else new_pe.origin = pe_source.origin;
// Move Particle emitter to source origin
setorigin(new_pe, new_pe.origin);
new_pe.part_style = pe_style; // must use global defs
new_pe.spawnflags = pe_spawnf; // spawnflags are parameters
new_pe.angles = pe_source.angles; // Copy over any angle params
// Back through emitter function
new_pe.think = misc_particle_setup;
new_pe.nextthink = time + 0.1 + random();
return new_pe;
};
//----------------------------------------------------------------------
void() misc_particle =
{
if (self.spawnflags & ENT_STARTOFF) self.spawnflags = PARTICLE_START_OFF;
else self.spawnflags = PARTICLE_START_ON;
// Default setup for any particle emitter
self.classtype = CT_PARTICLEEMIT;
self.pemit_source = self;
gen_unique_no(self);
self.state = STATE_SETUP;
// Let state of particle emitter change before finishing setup
if (self.targetname != "") self.use = misc_particle_use;
// Custom particle setup using template?
if (self.target2 != "") {
self.nextthink = time + 0.1 + random();
self.think = misc_particle_copytemplate;
return;
}
// Setup any pre-defined particle types
if (self.message == "ARMOR1") { self.part_style = PARTICLE_STYLE_ARMOR; self.items = IT_ARMOR1; }
else if (self.message == "ARMOR2") { self.part_style = PARTICLE_STYLE_ARMOR; self.items = IT_ARMOR2; }
else if (self.message == "ARMOR3") { self.part_style = PARTICLE_STYLE_ARMOR; self.items = IT_ARMOR3; }
else if (self.message == "BOOK") self.part_style = PARTICLE_STYLE_BOOK;
else if (self.message == "ELECTRIC") self.part_style = PARTICLE_STYLE_ELECTRIC;
else if (self.message == "FCIRCLE") self.part_style = PARTICLE_STYLE_FCIRCLE;
else if (self.message == "FLAMES") self.part_style = PARTICLE_STYLE_FLAMES;
else if (self.message == "FLAMEL") self.part_style = PARTICLE_STYLE_FLAMEL;
else if (self.message == "KEYGOLD") self.part_style = PARTICLE_STYLE_KEYGOLD;
else if (self.message == "KEYSILVER") self.part_style = PARTICLE_STYLE_KEYSILVER;
else if (self.message == "KEYRED") self.part_style = PARTICLE_STYLE_KEYRED;
else if (self.message == "KEYGREEN") self.part_style = PARTICLE_STYLE_KEYGREEN;
else if (self.message == "KEYPURPLE") self.part_style = PARTICLE_STYLE_KEYPURPLE;
else if (self.message == "KEYWHITE") self.part_style = PARTICLE_STYLE_KEYWHITE;
else if (self.message == "MEGAH") self.part_style = PARTICLE_STYLE_MEGAH;
else if (self.message == "PENT") self.part_style = PARTICLE_STYLE_PENT;
else if (self.message == "PORTAL") self.part_style = PARTICLE_STYLE_PORTAL;
else if (self.message == "JUMPPAD") self.part_style = PARTICLE_STYLE_JUMPPAD;
else if (self.message == "QUAD") self.part_style = PARTICLE_STYLE_QUAD;
else if (self.message == "SIGIL") self.part_style = PARTICLE_STYLE_SIGIL;
else if (self.message == "ALTAR") self.part_style = PARTICLE_STYLE_ALTAR;
else if (self.message == "SKILL") self.part_style = PARTICLE_STYLE_SKILL;
else if (self.message == "BSKILL") self.part_style = PARTICLE_STYLE_BSKILL;
else if (self.message == "GSKILL") self.part_style = PARTICLE_STYLE_GSKILL;
else if (self.message == "PSKILL") self.part_style = PARTICLE_STYLE_PSKILL;
else if (self.message == "SRING") self.part_style = PARTICLE_STYLE_SRING;
else if (self.message == "SUIT") self.part_style = PARTICLE_STYLE_SUIT;
else {
dprint("\b[MISC_PARTICLE]\b Missing particle style!\n");
spawn_marker(self.origin, SPNMARK_YELLOW);
return;
}
// Back through emitter function
self.nextthink = time + 0.1 + random();
self.think = misc_particle_setup;
};
//----------------------------------------------------------------------
void() misc_particle_burst_use =
{
particle_explode(self.origin+self.part_ofs, self.count, self.part_life, self.part_style, self.part_movetype);
// Check for temporary continuous mode
if (self.waitmin > 0) {
if (self.pausetime == 0) {
if (!self.waitmin2) self.waitmin2 = 0.1;
self.pausetime = time + self.waitmin;
}
if (self.pausetime > time) {
self.think = misc_particle_burst_use;
self.nextthink = time + self.waitmin2;
}
else self.pausetime = 0;
}
};
//----------------------------------------------------------------------
// This is also used by item_custom in items.qc
//----------------------------------------------------------------------
void() misc_particle_burst_setup =
{
// Read tcount from entity, but it cannot be used for constant emitters
// The finish particle system will decrease the tcount directly!
if (!self.pemit_tcount) self.count = 20;
if (!self.part_life) self.part_life = 2;
if (CheckZeroVector(self.part_ofs)) self.part_ofs = '0 0 0';
if (self.part_style == 1) self.part_style = PARTICLE_BURST_YELLOW;
else if (self.part_style == 2) self.part_style = PARTICLE_BURST_GREEN;
else if (self.part_style == 3) self.part_style = PARTICLE_BURST_RED;
else if (self.part_style == 4) self.part_style = PARTICLE_BURST_BLUE;
else if (self.part_style == 5) self.part_style = PARTICLE_BURST_PURPLE;
else if (self.part_style == 6) self.part_style = PARTICLE_BURST_FIRE;
else self.part_style = PARTICLE_BURST_WHITE;
if (self.part_movetype == 3) self.part_movetype = PARTICLE_BURST_UPWARD;
else if (self.part_movetype == 4) self.part_movetype = PARTICLE_BURST_SHOCKWAVE;
else if (self.part_movetype == 5) self.part_movetype = PARTICLE_BURST_SKULLUP;
else if (self.part_movetype == 6) self.part_movetype = PARTICLE_BURST_LOSTUP;
else if (self.part_movetype == 7) self.part_movetype = PARTICLE_BURST_MINOTAUR;
else self.part_movetype = PARTICLE_BURST_CENTER;
};
//----------------------------------------------------------------------
void() misc_particle_burst =
{
// Default setup for any particle emitter
self.classtype = CT_PARTICLEEMIT;
self.pemit_source = self;
self.health = LARGE_TIMER;
misc_particle_burst_setup();
self.use = misc_particle_burst_use;
};
//----------------------------------------------------------------------
void() misc_weather =
{
// Setup particle emitter to start on/off
if (self.spawnflags & ENT_STARTOFF)
self.spawnflags = self.spawnflags | PARTICLE_START_OFF;
else self.spawnflags = self.spawnflags | PARTICLE_START_ON;
// Default setup for any particle emitter
self.classtype = CT_PARTICLEEMIT;
self.part_style = PARTICLE_STYLE_WEATHER;
self.pemit_source = self;
gen_unique_no(self);
self.state = STATE_SETUP;
// Find out size of volume brush
InitTrigger();
// Save the brush bounding box for later
self.bbmins = self.mins;
self.bbmaxs = self.maxs;
self.oldorigin = bmodel_origin(self);
spawn_marker(self.oldorigin,0);
// hide volume, no longer needed
self.solid = SOLID_NOT;
// Setup default particle count based on volume
// - 10% of the volume size as particle count
if (!self.count)
self.count = rint((vlen(self.bbmaxs - self.bbmins)*0.1));
// Change for variable wind change
if (!self.speed) self.speed = 30;
self.attack_speed = time + self.speed + (random()*self.speed);
// Setup default wind (X/Y) and vertical velocity
if (self.spawnflags & PARTICLE_WEATHER_SNOW) {
if (CheckZeroVector(self.pos1)) self.pos1 = '8 15 0'; // Mostly white
if (CheckZeroVector(self.pos2)) self.pos2 = '100 100 -100';
}
else {
if (CheckZeroVector(self.pos1)) self.pos1 = '1 15 0'; // grey->white
if (CheckZeroVector(self.pos2)) self.pos2 = '100 100 -500';
}
// Particle colour range - Make sure Y > X
if (self.pos1_x > self.pos1_y) {
self.pos1_z = self.pos1_x;
self.pos1_x = self.pos1_y;
self.pos1_y = self.pos1_z;
}
// Work out range of colour
self.pos1_z = rint(self.pos1_y - self.pos1_x);
if (self.pos1_z < 1) self.pos1_z = 1;
// Create initial wind direction
self.pos3_x = crandom() * self.pos2_x;
self.pos3_y = crandom() * self.pos2_y;
self.pos3_z = self.pos2_z;
// Back through emitter function
self.nextthink = time + 0.1 + random();
self.think = misc_particle_setup;
};
/*======================================================================
/*QUAKED misc_particle (0 0.5 0.75) (-8 -8 -8) (8 8 8) x x x x x x STARTOFF x
A particle emitter which can be turned on/off (use function)
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
target : destination of effect (self -> target)
target2 : name of a particle template
message : Particle style string (upper case) leave blank for custom
ALTAR, ARMOR1, ARMOR2, ARMOR3, BOOK, ELECTRIC,
FCIRCLE, FLAMES, FLAMEL, JUMPPAD,
KEYGOLD, KEYSILVER, KEYRED, KEYGREEN, KEYPURPLE, KEYWHITE,
MEGAH, PENT, PORTAL, QUAD, SIGIL, SRING, SUIT,
SKILL, BSKILL, GSKILL, PSKILL
-------- SPAWNFLAGS --------
STARTOFF : Always Starts off and waits for trigger
-------- NOTES --------
A particle emitter which can be turned on/off (use function)
//-----------------------------------------------------------------------------
/*QUAKED misc_particletemplate (0 0.5 0.75) (-8 -8 -8) (8 8 8) x
A particle emitter template
-------- KEYS --------
targetname : target name reference for misc_particle entities
start_delay : Particle emitter start delay
spr_name1 : sprite name (progs\s_bubble_blue1.spr)
spr_name2 : sprite name (progs\s_bubble_wht.spr)
spr_name3 : sprite name (progs\s_dotmed_grey.spr)
part_movetype: Movetype of particle (def.qc for movetypes)
part_limit : Maximum amount of particles to emit at once
part_life : Life time particle is active (seconds)
part_ofs : Offset from emitter (XYZ)
part_veltype : Velocity type 1=random, 2=circular
part_vel : Velocity direction (XYZ)
part_velrand : Extra random velocity (need vel type 1)
part_velrot : Velocity rotation (Y axis only)
part_vol : Spawning volume around emitter (XYZ)
cirular_angle: Circular rotation angle
wakeup_dist : Wake up distance for particle emitter
wakeup_timer : How often to check distance check
spawn_base : Spawn rate - base value (seconds)
spawn_rand : Spawn rate - random adjustment (seconds)
dpp_name : DP particle effect name in effectinfo.txt file
dpp_wait : DP particle re-trigger timer
dpp_rnd : DP particle random multiplier for time
dpp_vel : Direction of DP particles to move towards (XYZ)
-------- SPAWNFLAGS --------
-------- NOTES --------
A particle emitter template
//-----------------------------------------------------------------------------
/*QUAKED misc_particle_burst (0 0.5 0.75) (-8 -8 -8) (8 8 8) x
A particle emitter that fires a burst
-------- KEYS --------
targetname : Trigger Particle Emitter
part_ofs : Particle Origin Offset (def='0 0 0')
part_tcount : Particle Quantity (def=20)
part_life : Particle Life Time (def=2s)
part_style : 1=yellow, 2=green, 3=red, 4=blue, 5=purple, 6=fire, 7=white
part_movetype : 2=center, 3=up, 4=shockwave, 5=skull, 6=lost, 7=minotaur
-------- SPAWNFLAGS --------
-------- NOTES --------
A particle emitter that fires a burst
//-----------------------------------------------------------------------------
/*QUAKED misc_weather (0 0.5 0.75) ? x x SILENT SNOW BLOOD SLIME STARTOFF x
A particle emitter which produces weather effects
-------- KEYS --------
targetname : toggle state (use trigger ent for exact state)
count : Quantity of particles for volume
speed : Downward velocity (def=300)
v_angle : Random velocity adjustment (def=8 8 150)
wakeup_dist : how close the player needs to be for the weather to work
wakeup_timer : time to keep checking when in standby mode
-------- SPAWNFLAGS --------
SILENT : Don't make any drip sound (good for multiple drips)
SNOW : White wispy flakes falling
BLOOD : Blood red rain
SLIME : Slime green rain
STARTOFF : Always Starts off and waits for trigger
-------- NOTES --------
A particle emitter which produces weather effects
======================================================================*/