/*====================================================================== 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 ======================================================================*/