/*====================================================================== LIGHT ENTITIES (used by compiler) ======================================================================*/ float LIGHT_STARTOFF = 1; float LIGHT_NOSOUND = 2; float LIGHT_NOSTATIC = 4; float LIGHT_FLAMEOFF = 2; float LIGHT_CANDLESHADOW = 8; float LIGHT_SWITCHFADE = 16; float LIGHT_NOEFFECTS = 128; // To help reduce signon buffer size, allow for light entities // to be delay spawned (especially light models like candles) // Cannot use target key because compiler uses it for light styles .string lighttarget; //---------------------------------------------------------------------- void() play_light_sound = { if (!self.owner) return; if (self.owner.estate & ESTATE_BLOCK) return; self.think = play_light_sound; self.nextthink = time + self.owner.waitmin; sound (self, CHAN_VOICE, self.owner.noise, self.owner.volume, ATTN_STATIC); }; //---------------------------------------------------------------------- void() setup_light_sound = { if (!self.volume) self.volume = 0.5; if ( !(self.spawnflags & LIGHT_NOSOUND) && self.noise != "" ) { if (self.targetname) { self.attachment = spawn(); self.attachment.owner = self; setorigin(self.attachment, self.origin); self.attachment.nextthink = time + 1; self.attachment.think = play_light_sound; } else { ambientsound (self.origin, self.noise, self.volume, ATTN_QUIET); } } }; //---------------------------------------------------------------------- void() setup_light_static = { // Cannot have static entities and particle emitters! if (query_configflag(SVR_PARTICLES) == SVR_PARTICLES) return; if ( !(self.spawnflags & LIGHT_NOSTATIC) ) makestatic (self); }; //---------------------------------------------------------------------- void(float pe_style) setup_light_particle = { if (self.spawnflags & LIGHT_NOEFFECTS) return; // Spawn particle emitter if particles active and not blocked if (query_configflag(SVR_PARTICLES) == SVR_PARTICLES ) { self.part_active = pe_style; if (self.spawnflags & LIGHT_STARTOFF) self.lip = PARTICLE_START_OFF; else self.lip = PARTICLE_START_ON; self.part_emitter = spawn_pemitter(self, self, self.part_active, self.lip); } }; //---------------------------------------------------------------------- void() light_part_emitter_on = { if (self.part_emitter) { if (ext_dppart && self.part_emitter.state == STATE_OFF) pointparticles(particleeffectnum(DPP_BURSTFLAME), self.origin, '0 0 0', 1); misc_particle_on(self.part_emitter); } if (self.attachment) { self.attachment.think = play_light_sound; self.attachment.nextthink = time + 0.1; } }; //---------------------------------------------------------------------- void() light_on = { self.estate = ESTATE_ON; if (self.mdl) setmodel (self, self.mdl); lightstyle(self.style, "m"); light_part_emitter_on(); }; //---------------------------------------------------------------------- void() light_off = { self.estate = ESTATE_OFF; if (self.mdl) { self.modelindex = 0; self.model = ""; } lightstyle(self.style, "a"); if (self.attachment) sound (self.attachment, CHAN_VOICE, SOUND_EMPTY, 1, ATTN_STATIC); }; /*====================================================================== /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) LIGHTOFF x x x x x x x Non-displayed light -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default style : 0 = normal 1 = flicker (first variety) 2 = slow strong pulse 3 = candle (first variety) 4 = fast strobe 5 = gentle pulse 6 = flicker (second variety) 7 = candle (second variety) 8 = candle (third variety) 9 = slow strobe 10 = flourescent flicker 11 = slow pulse, not fading to black styles 32-62 are assigned by the light program for switchable lights _color : Light color - R/G/B (def='1 1 1') wait : Fade distance multiplier (def=1) delay : Attenuation 0=Linear, 1=inverse, 2=Squared, 3=NoFalloff, 4=Minlight, 5=Good Ambient mangle : Spotlight direction angle : Spotlight cone angle (def=40) _dirt : Dirt map (override) _dirtscale : Dirt scale (override) _deviance : Deviance _samples : No. of Deviance lights (def=16) _surface : Surface light texture name _surface_offset : Surface light offset (def=2) _softangle : Spotlight soft angle (def=0) _anglescale : Light angle scale (def=0.5) -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger -------- NOTES -------- Non-displayed light. If targeted, it will toggle between on or off ======================================================================*/ void() light = { // If no targetname then inert light, safe to remove if (self.targetname == "") { remove(self); return; } if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } }; /*====================================================================== /*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) LIGHTOFF NO_SOUND x x x x x x Non-displayed light. Makes steady fluorescent humming sound -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger NO_SOUND : No ambient sound -------- NOTES -------- Non-displayed light. Makes steady fluorescent humming sound ======================================================================*/ void() light_fluoro = { self.noise = "ambience/fl_hum1.wav"; precache_sound (self.noise); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } setup_light_sound(); }; /*====================================================================== /*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) x NO_SOUND x x x x x x Non-displayed light. Makes sparking, broken fluorescent sound -------- KEYS -------- light : sets brightness, 300 is default -------- SPAWNFLAGS -------- NO_SOUND : No ambient sound -------- NOTES -------- Non-displayed light. Makes sparking, broken fluorescent sound ======================================================================*/ void() light_fluorospark = { self.noise = "ambience/buzz1.wav"; precache_sound (self.noise); if (!self.style) self.style = 10; setup_light_sound(); }; /*====================================================================== /*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) LIGHTOFF x NO_STATIC x x x X x Sphere globe light (sprite) -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger NO_STATIC : Will not turn into static entity -------- NOTES -------- Sphere globe light (sprite) ======================================================================*/ void() light_globe = { self.mdl = "progs/s_light.spr"; precache_model (self.mdl); setmodel (self, self.mdl); setsize (self, VEC_ORIGIN, VEC_ORIGIN); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setup_light_static(); }; /*====================================================================== /*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) LIGHTOFF NO_SOUND NO_STATIC x x x x x Short wall torch -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger NO_SOUND : No ambient sound NO_STATIC : Will not turn into static entity -------- NOTES -------- Short wall torch ======================================================================*/ void() light_torch_on = { self.frame = 0; self.estate = ESTATE_ON; lightstyle(self.style, "m"); light_part_emitter_on(); }; //---------------------------------------------------------------------- void() light_torch_off = { self.frame = 1; self.estate = ESTATE_OFF; lightstyle(self.style, "a"); if (self.attachment) sound (self.attachment, CHAN_VOICE, SOUND_EMPTY, 1, ATTN_STATIC); }; //---------------------------------------------------------------------- void() light_torch_small_walltorch = { self.mdl = "progs/flame.mdl"; precache_model (self.mdl); if (self.noise == "") self.noise = "ambience/fire1.wav"; precache_sound (self.noise); if (!self.waitmin) self.waitmin = 2.165; setmodel (self, self.mdl); setsize (self, VEC_ORIGIN, VEC_ORIGIN); // Setting the angle key in the editor to UP/DOWN = random rotation if (self.angles_y <= 0) self.angles_y = rint(random()*359); setup_light_sound(); setup_light_particle(PARTICLE_STYLE_FLAMET); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_torch_on; self.estate_off = light_torch_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setup_light_static(); }; /*====================================================================== /*QUAKED light_flame_large_yellow (0 1 0) (-8 -8 -8) (8 8 8) LIGHTOFF NO_SOUND NO_STATIC x x x x x Large yellow flame -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger NO_SOUND : No ambient sound NO_STATIC : Will not turn into static entity -------- NOTES -------- Large yellow flame ======================================================================*/ void() light_flame_large_yellow = { self.mdl = "progs/flame2.mdl"; precache_model (self.mdl); if (self.noise == "") self.noise = "ambience/fire1.wav"; precache_sound (self.noise); // The default length of the ambient sound used if (!self.waitmin) self.waitmin = 2.165; // If DP engine active remove candle model shadow if (engine == ENG_DPEXT) self.effects = self.effects + EF_NOSHADOW; setmodel (self, self.mdl); setsize (self, VEC_ORIGIN, VEC_ORIGIN); self.frame = 1; // Switch to frame group 2 (larger flame) if (!self.alpha) self.alpha = 0.8; // Setting the angle key in the editor to UP/DOWN = random rotation if (self.angles_y <= 0) self.angles_y = rint(random()*359); setup_light_sound(); setup_light_particle(PARTICLE_STYLE_FLAMEL); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setup_light_static(); }; /*====================================================================== /*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) LIGHTOFF NO_SOUND NO_STATIC x x x X x Small yellow flames -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger NO_SOUND : No ambient sound NO_STATIC : Will not turn into static entity -------- NOTES -------- Small yellow flames. ======================================================================*/ void() light_flame_small_yellow = { self.mdl = "progs/flame2.mdl"; precache_model (self.mdl); if (self.noise == "") self.noise = "ambience/fire1.wav"; precache_sound (self.noise); self.part_active = PARTICLE_STYLE_FLAMES; if (!self.waitmin) self.waitmin = 2.165; // If DP engine active remove candle model shadow if (engine == ENG_DPEXT) self.effects = self.effects + EF_NOSHADOW; setmodel (self, self.mdl); setsize (self, VEC_ORIGIN, VEC_ORIGIN); if (!self.alpha) self.alpha = 0.8; // Setting the angle key in the editor to UP/DOWN = random rotation if (self.angles_y <= 0) self.angles_y = rint(random()*359); setup_light_sound(); setup_light_particle(PARTICLE_STYLE_FLAMES); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setup_light_static(); }; //Duplicate (small yellow flame) void() light_flame_small_white = { light_flame_small_yellow(); }; /*====================================================================== /*QUAKED light_postlight (0 .5 0) (-10 -10 -20) (10 10 20) LIGHTOFF x x x x x x x light post (from Quoth) -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger -------- NOTES -------- light post (from Quoth) ======================================================================*/ void() light_postlight = { self.mdl = "progs/misc_lightpost.mdl"; precache_model (self.mdl); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setmodel (self, self.mdl); }; /*====================================================================== /*QUAKED light_tubelight (0 .5 0) (-10 -10 -20) (10 10 20) LIGHTOFF x x x x x x x light Tube (from Quoth) -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger -------- NOTES -------- light Tube (from Quoth) ======================================================================*/ void() light_tubelight = { self.mdl = "progs/misc_lighttube.mdl"; precache_model (self.mdl); if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setmodel (self, self.mdl); }; /*====================================================================== /*QUAKED light_fixture1 (0 .5 0) (-10 -10 -20) (10 10 20) LIGHTOFF x x x x x x x light Fixture (from Rubicon) -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) light : sets brightness, 300 is default fixangle : angle the model should be facing; set it to face away from the wall -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger -------- NOTES -------- light Fixture (from Rubicon) ======================================================================*/ void() light_fixture1 = { self.mdl = "progs/misc_fixture1.mdl"; precache_model (self.mdl); self.angles_y = self.fixangle; if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_on; self.estate_off = light_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } else setmodel (self, self.mdl); }; /*====================================================================== /*QUAKED light_candle (0 1 0) (-4 -4 -16) (4 4 16) LIGHTOFF FLAMEOFF x SHADOWS x STATIC x x Wide variety of Candles (from Rogue Software) -------- KEYS -------- targetname : toggle state (use trigger ent for exact state) angle : 0=random angle, 1-360=specific height : size of candle 1=short, 2=medium, 3=regular, -1=random t_width : width of candle 1=regular, 2=fat, 3=thin, -1=random lip : Moves model down to ground plane (default = 16) light : sets brightness, 300 is default -------- SPAWNFLAGS -------- LIGHTOFF : Starts off and waits for trigger FLAMEOFF : The candle is displayed off (no light/flame) SHADOW : Turn on shadows in DP engine STATIC : Turn entity into static upon spawn (frame 0) -------- NOTES -------- Wide variety of Candles (from Rogue Software) ======================================================================*/ void() light_candle_on = { self.estate = ESTATE_ON; self.frame = 1 + (self.t_width-1)*2; lightstyle(self.style, "m"); }; //---------------------------------------------------------------------- void() light_candle_off = { self.estate = ESTATE_OFF; self.frame = (self.t_width-1)*2; lightstyle(self.style, "a"); }; //---------------------------------------------------------------------- void() light_candle_setup = { // Setup model and no world interaction setmodel (self, self.mdl); setsize (self, VEC_ORIGIN, VEC_ORIGIN); // If DP engine active remove candle model shadow if (engine == ENG_DPEXT && !(self.spawnflags & LIGHT_CANDLESHADOW)) self.effects = self.effects + EF_NOSHADOW; // Setting the angle key in the editor to UP/DOWN = random rotation if (self.angles_y <= 0) self.angles_y = rint(random()*359); // Setup light if (self.spawnflags & LIGHT_FLAMEOFF) { self.estate = ESTATE_OFF; self.frame = (self.t_width-1)*2; } // Is switchable light style defined? if (self.style >= 32) { // Setup Entity State functionality if (self.targetname != "") self.use = entity_state_use; self.estate_on = light_candle_on; self.estate_off = light_candle_off; if (self.spawnflags & LIGHT_STARTOFF) self.estate_off(); else self.estate_on(); } // Check for static option, after switchable lights else if (self.spawnflags & ENT_SPNSTATIC) makestatic(self); }; //---------------------------------------------------------------------- void() light_candle = { // Cannot have randomly selected models for prechache // Quickload will re-run all spawn functions and try to select // a different candle model which is not precached precache_model ("progs/misc_candle1.mdl"); precache_model ("progs/misc_candle2.mdl"); precache_model ("progs/misc_candle3.mdl"); // Check for size 1=small, 2=medium, 3=regular (def), -1=random if (self.height < 0) self.height = 1 + rint(random()*2); if (self.height == 1) self.mdl = "progs/misc_candle1.mdl"; else if (self.height == 2) self.mdl = "progs/misc_candle2.mdl"; else self.mdl = "progs/misc_candle3.mdl"; // Check for width 1=regular (def), 2=fat, 3=thin, -1=random // The models are split up into three groups of off/on if (self.t_width < 0) self.t_width = 1 + rint(random()*2); else if (self.t_width == 0 || self.t_width > 3) self.t_width = 1; self.modelindex = 0; self.model = string_null; // hide bmodel surface self.frame = 1 + (self.t_width-1)*2; // Def = on state self.movetype = MOVETYPE_NONE; // Create baseline self.solid = SOLID_NOT; self.nextthink = 0; // The model should not be setup flush to floor because it is a light // source and will look really odd, setup entity 16 units above floor // and the "lip" key will move it back down again if (!self.lip) self.lip = 16; self.origin_z = self.origin_z - self.lip; // Check for static entity option first if (self.spawnflags & ENT_SPNSTATIC) light_candle_setup(); else { // Check for spawn delay on model (signon buffer issues) // Code left so light_candles can be switched on/off if (self.lighttarget != "" && !self.style) { self.targetname = self.lighttarget; // Use the entity state system for max compatibility self.estate = ESTATE_OFF; self.use = entity_state_use; self.estate_on = light_candle_setup; } else light_candle_setup(); } };