// w_misc.qc: various useful brushes /*QUAKED info_null(0 0.5 0) (-4 -4 -4) (4 4 4) Used as a positional target for spotlights, etc. */ void() info_null = { remove(self); }; /*QUAKED info_notnull(0 0.5 0) (-4 -4 -4) (4 4 4) Used as a positional target for lightning. */ void() info_notnull = { }; //============================================================================ void() light_use = { if(self.spawnflags & LIGHT_START_OFF) { light_style(self.style, "m"); self.spawnflags = self.spawnflags - LIGHT_START_OFF; } else { light_style(self.style, "a"); self.spawnflags = self.spawnflags + LIGHT_START_OFF; } }; /*QUAKED light(0 1 0) (-8 -8 -8) (8 8 8) START_OFF Non-displayed light. Default light value is 300 Default style is 0 If targeted, it will toggle between on or off. */ void() light = { if(!self.targetname) { // inert light remove(self); return; } if(self.style >= 32) { self.use = light_use; if(self.spawnflags & LIGHT_START_OFF) { light_style(self.style, "a"); } else { light_style(self.style, "m"); } } }; /*QUAKED light_fluoro(0 1 0) (-8 -8 -8) (8 8 8) START_OFF Non-displayed light. Default light value is 300 Default style is 0 If targeted, it will toggle between on or off. Makes steady fluorescent humming sound */ void() light_fluoro = { if(self.style >= 32) { self.use = light_use; if(self.spawnflags & LIGHT_START_OFF) { light_style(self.style, "a"); } else { light_style(self.style, "m"); } } precache_sound("ambience/fl_hum1.wav"); ambient_sound(self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); }; /*QUAKED light_fluorospark(0 1 0) (-8 -8 -8) (8 8 8) Non-displayed light. Default light value is 300 Default style is 10 Makes sparking, broken fluorescent sound */ void() light_fluorospark = { if(!self.style) { self.style = 10; } precache_sound("ambience/buzz1.wav"); ambient_sound(self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC); }; /*QUAKED light_globe(0 1 0) (-8 -8 -8) (8 8 8) Sphere globe light. Default light value is 300 Default style is 0 */ void() light_globe = { precache_model("progs/s_light.spr"); set_model(self, "progs/s_light.spr"); make_static(self); }; void() fire_ambient = { precache_sound("ambience/fire1.wav"); // attenuate fast ambient_sound(self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC); }; /*QUAKED light_torch_small_walltorch(0 .5 0) (-10 -10 -20) (10 10 20) Short wall torch Default light value is 200 Default style is 0 */ void() light_torch_small_walltorch = { precache_model("progs/flame.mdl"); set_model(self, "progs/flame.mdl"); fire_ambient(); make_static(self); }; /*QUAKED light_flame_large_yellow(0 1 0) (-10 -10 -12) (12 12 18) Large yellow flame ball */ void() light_flame_large_yellow = { precache_model("progs/flame2.mdl"); set_model(self, "progs/flame2.mdl"); self.frame = 1; fire_ambient(); make_static(self); }; /*QUAKED light_flame_small_yellow(0 1 0) (-8 -8 -8) (8 8 8) START_OFF Small yellow flame ball */ void() light_flame_small_yellow = { precache_model("progs/flame2.mdl"); set_model(self, "progs/flame2.mdl"); fire_ambient(); make_static(self); }; /*QUAKED light_flame_small_white(0 1 0) (-10 -10 -40) (10 10 40) START_OFF Small white flame ball */ void() light_flame_small_white = { precache_model("progs/flame2.mdl"); set_model(self, "progs/flame2.mdl"); fire_ambient(); make_static(self); }; //============================================================================ void() fire_fly, fire_touch; /*QUAKED misc_fireball(0 .5 .8) (-8 -8 -8) (8 8 8) Lava Balls */ void() misc_fireball = { precache_model("progs/lavaball.mdl"); self.classname = "fireball"; self.nextthink = time + 0.1 + (random() * 5); self.think = fire_fly; if(!self.speed) { self.speed = 1000; } }; void() fire_fly = { entity fireball; fireball = spawn(); fireball.solid = SOLID_TRIGGER; fireball.movetype = MOVETYPE_TOSS; fireball.velocity = '0 0 1000'; fireball.velocity_x = (random() * 100) - 50; fireball.velocity_y = (random() * 100) - 50; fireball.velocity_z = self.speed + (random() * 200); fireball.classname = "fireball"; set_model(fireball, "progs/lavaball.mdl"); set_size(fireball, VEC_ORIGIN, VEC_ORIGIN); set_origin(fireball, self.origin); fireball.nextthink = time + 5; fireball.think = sub_remove; fireball.touch = fire_touch; self.nextthink = time + (random() * 5) + 3; self.think = fire_fly; }; void() fire_touch = { ent_damage(other, self, self, 20); remove(self); }; //============================================================================ void() barrel_damage = { ent_radius_damage(self, self, 160, world); sound(self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); particle(self.origin, VEC_ORIGIN, 75, 255); self.origin_z = self.origin_z + 32; become_explosion(); }; void() barrel_explode = { self.takedamage = DAMAGE_NO; self.classname = "explo_box"; self.nextthink = time + 0.1; self.think = barrel_damage; }; /*QUAKED misc_explobox(0 .5 .8) (0 0 0) (32 32 64) TESTING THING */ void() misc_explobox = { float oldz; self.solid = SOLID_BBOX; self.movetype = MOVETYPE_NONE; precache_model("maps/b_explob.bsp"); set_model(self, "maps/b_explob.bsp"); precache_sound("weapons/r_exp3.wav"); self.health = 20; self.th_die = barrel_explode; self.takedamage = DAMAGE_AIM; self.origin_z = self.origin_z + 2; oldz = self.origin_z; drop_to_floor(); if(oldz - self.origin_z > 250) { print_dbg("item fell out of level at ", vtos(self.origin), "\n"); remove(self); } }; /*QUAKED misc_explobox2(0 .5 .8) (0 0 0) (32 32 64) Smaller exploding box, REGISTERED ONLY */ void() misc_explobox2 = { float oldz; self.solid = SOLID_BBOX; self.movetype = MOVETYPE_NONE; precache_model2("maps/b_exbox2.bsp"); set_model(self, "maps/b_exbox2.bsp"); precache_sound("weapons/r_exp3.wav"); self.health = 20; self.th_die = barrel_explode; self.takedamage = DAMAGE_AIM; self.origin_z = self.origin_z + 2; oldz = self.origin_z; drop_to_floor(); if(oldz - self.origin_z > 250) { print_dbg("item fell out of level at ", vtos(self.origin), "\n"); remove(self); } }; //============================================================================ void() spikeshooter_use = { if(self.spawnflags & SPIKESHOOTER_LASER) { sound(self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM); launch_laser(self.origin, self.movedir); } else { sound(self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM); launch_spike(self.origin, self.movedir); newmis.velocity = self.movedir * 500; if(self.spawnflags & SPIKESHOOTER_SUPER) { newmis.touch = superspike_touch; } } }; void() shooter_think = { spikeshooter_use(); self.nextthink = time + self.wait; newmis.velocity = self.movedir * 500; }; /*QUAKED trap_spikeshooter(0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser When triggered, fires a spike in the direction set in QuakeEd. Laser is only for REGISTERED. */ void() trap_spikeshooter = { set_move_dir(); self.use = spikeshooter_use; if(self.spawnflags & SPIKESHOOTER_LASER) { precache_model2("progs/laser.mdl"); precache_sound2("enforcer/enfire.wav"); precache_sound2("enforcer/enfstop.wav"); } else { precache_sound("weapons/spike2.wav"); } }; /*QUAKED trap_shooter(0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser Continuously fires spikes. "wait" time between spike(1.0 default) "nextthink" delay before firing first spike, so multiple shooters can be stagered. */ void() trap_shooter = { trap_spikeshooter(); if(self.wait == 0) { self.wait = 1; } self.nextthink = self.nextthink + self.wait + self.ltime; self.think = shooter_think; }; /* =============================================================================== =============================================================================== */ void() bubble_remove, make_bubbles; /*QUAKED air_bubbles(0 .5 .8) (-8 -8 -8) (8 8 8) testing air bubbles */ void() air_bubbles = { if(deathmatch) { remove(self); return; } precache_model("progs/s_bubble.spr"); self.nextthink = time + 1; self.think = make_bubbles; }; void() make_bubbles = { entity bubble; bubble = spawn(); set_model(bubble, "progs/s_bubble.spr"); set_origin(bubble, self.origin); bubble.movetype = MOVETYPE_NOCLIP; bubble.solid = SOLID_NOT; bubble.velocity = '0 0 15'; bubble.nextthink = time + 0.5; bubble.think = bubble_bob; bubble.touch = bubble_remove; bubble.classname = "bubble"; bubble.frame = 0; bubble.cnt = 0; set_size(bubble, '-8 -8 -8', '8 8 8'); self.nextthink = time + random() + 0.5; self.think = make_bubbles; }; void() bubble_split = { entity bubble; bubble = spawn(); set_model(bubble, "progs/s_bubble.spr"); set_origin(bubble, self.origin); bubble.movetype = MOVETYPE_NOCLIP; bubble.solid = SOLID_NOT; bubble.velocity = self.velocity; bubble.nextthink = time + 0.5; bubble.think = bubble_bob; bubble.touch = bubble_remove; bubble.classname = "bubble"; bubble.frame = 1; bubble.cnt = 10; set_size(bubble, '-8 -8 -8', '8 8 8'); self.frame = 1; self.cnt = 10; if(self.waterlevel != 3) { remove(self); } }; void() bubble_remove = { if(other.classname == self.classname) { // print_dbg("bump"); return; } remove(self); }; void() bubble_bob = { float rnd1, rnd2, rnd3; vector vtmp1, modi; self.cnt = self.cnt + 1; if(self.cnt == 4) { bubble_split(); } if(self.cnt == 20) { remove(self); } rnd1 = self.velocity_x + (-10 + (random() * 20)); rnd2 = self.velocity_y + (-10 + (random() * 20)); rnd3 = self.velocity_z + 10 + random() * 10; if(rnd1 > 10) { rnd1 = 5; } if(rnd1 < -10) { rnd1 = -5; } if(rnd2 > 10) { rnd2 = 5; } if(rnd2 < -10) { rnd2 = -5; } if(rnd3 < 10) { rnd3 = 15; } if(rnd3 > 30) { rnd3 = 25; } self.velocity_x = rnd1; self.velocity_y = rnd2; self.velocity_z = rnd3; self.nextthink = time + 0.5; self.think = bubble_bob; }; /*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~> ~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/ /*QUAKED viewthing(0 .5 .8) (-8 -8 -8) (8 8 8) Just for the debugging level. Don't use */ void() viewthing = { self.movetype = MOVETYPE_NONE; self.solid = SOLID_NOT; precache_model("progs/player.mdl"); set_model(self, "progs/player.mdl"); }; /* ============================================================================== SIMPLE BMODELS ============================================================================== */ void() func_wall_use = { // change to alternate textures self.frame = 1 - self.frame; }; /*QUAKED func_wall(0 .5 .8) ? This is just a solid wall if not inhibitted */ void() func_wall = { self.angles = VEC_ORIGIN; self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything self.solid = SOLID_BSP; self.use = func_wall_use; set_model(self, self.model); }; /*QUAKED func_illusionary(0 .5 .8) ? A simple entity that looks solid but lets you walk through it. */ void() func_illusionary = { self.angles = VEC_ORIGIN; self.movetype = MOVETYPE_NONE; self.solid = SOLID_NOT; set_model(self, self.model); make_static(self); }; /*QUAKED func_episodegate(0 .5 .8) ? E1 E2 E3 E4 This bmodel will appear if the episode has allready been completed, so players can't reenter it. */ void() func_episodegate = { if(!(serverflags & self.spawnflags)) { return; // can still enter episode } self.angles = VEC_ORIGIN; self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything self.solid = SOLID_BSP; self.use = func_wall_use; set_model(self, self.model); }; /*QUAKED func_bossgate(0 .5 .8) ? This bmodel appears unless players have all of the episode sigils. */ void() func_bossgate = { if((serverflags & 15) == 15) { return; // all episodes completed } self.angles = VEC_ORIGIN; self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything self.solid = SOLID_BSP; self.use = func_wall_use; set_model(self, self.model); }; //============================================================================ /*QUAKED ambient_suck_wind(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_suck_wind = { precache_sound("ambience/suck1.wav"); ambient_sound(self.origin, "ambience/suck1.wav", 1, ATTN_STATIC); }; /*QUAKED ambient_drone(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_drone = { precache_sound("ambience/drone6.wav"); ambient_sound(self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC); }; /*QUAKED ambient_flouro_buzz(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_flouro_buzz = { precache_sound("ambience/buzz1.wav"); ambient_sound(self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC); }; /*QUAKED ambient_drip(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_drip = { precache_sound("ambience/drip1.wav"); ambient_sound(self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC); }; /*QUAKED ambient_comp_hum(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_comp_hum = { precache_sound("ambience/comp1.wav"); ambient_sound(self.origin, "ambience/comp1.wav", 1, ATTN_STATIC); }; /*QUAKED ambient_thunder(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_thunder = { precache_sound("ambience/thunder1.wav"); ambient_sound(self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC); }; /*QUAKED ambient_light_buzz(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_light_buzz = { precache_sound("ambience/fl_hum1.wav"); ambient_sound(self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC); }; /*QUAKED ambient_swamp1(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_swamp1 = { precache_sound("ambience/swamp1.wav"); ambient_sound(self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC); }; /*QUAKED ambient_swamp2(0.3 0.1 0.6) (-10 -10 -8) (10 10 8) */ void() ambient_swamp2 = { precache_sound("ambience/swamp2.wav"); ambient_sound(self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC); }; //============================================================================ void() noise_think = { self.nextthink = time + 0.5; sound(self, 1, "enforcer/enfire.wav", 1, ATTN_NORM); sound(self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM); sound(self, 3, "enforcer/sight1.wav", 1, ATTN_NORM); sound(self, 4, "enforcer/sight2.wav", 1, ATTN_NORM); sound(self, 5, "enforcer/sight3.wav", 1, ATTN_NORM); sound(self, 6, "enforcer/sight4.wav", 1, ATTN_NORM); sound(self, 7, "enforcer/pain1.wav", 1, ATTN_NORM); }; /*QUAKED misc_noisemaker(1 0.5 0) (-10 -10 -10) (10 10 10) For optimzation testing, starts a lot of sounds. */ void() misc_noisemaker = { precache_sound2("enforcer/enfire.wav"); precache_sound2("enforcer/enfstop.wav"); precache_sound2("enforcer/sight1.wav"); precache_sound2("enforcer/sight2.wav"); precache_sound2("enforcer/sight3.wav"); precache_sound2("enforcer/sight4.wav"); precache_sound2("enforcer/pain1.wav"); precache_sound2("enforcer/pain2.wav"); precache_sound2("enforcer/death1.wav"); precache_sound2("enforcer/idle1.wav"); self.nextthink = time + 0.1 + random(); self.think = noise_think; };