From 8f14c8bffa45f026434522d3e716947aa5c3cd43 Mon Sep 17 00:00:00 2001 From: div0 Date: Tue, 26 Aug 2008 13:15:18 +0000 Subject: [PATCH] misc_laser: optimization and bugfix, and documentation; trigger_flipflop and trigger_monoflop git-svn-id: svn://svn.icculus.org/nexuiz/trunk@4198 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/client/laser.qc | 15 ++-- data/qcsrc/server/g_triggers.qc | 121 +++++++++++++++++++++++--------- data/scripts/entities.def | 39 +++++++--- 3 files changed, 129 insertions(+), 46 deletions(-) diff --git a/data/qcsrc/client/laser.qc b/data/qcsrc/client/laser.qc index 9956bda5b..e4249ab75 100644 --- a/data/qcsrc/client/laser.qc +++ b/data/qcsrc/client/laser.qc @@ -1,12 +1,16 @@ -// a laser goes from origin in direction velocity +// a laser goes from origin in direction angles // it has color 'colormod' // and stops when something is in the way .float cnt; // end effect .vector colormod; +.float state; // on-off void Draw_Laser() { - traceline(self.origin, self.origin + self.velocity, 0, self); + if(!self.state) + return; + makevectors(self.angles); + traceline(self.origin, self.origin + v_forward * 32768, 0, self); Draw_CylindricLine(self.origin, trace_endpos, 4, "particles/laserbeam", 1, self.colormod, DRAWFLAG_ADDITIVE); // TODO make a texture to make the laser look smoother pointparticles(self.cnt, trace_endpos, trace_plane_normal, 256 * drawframetime); } @@ -28,9 +32,10 @@ void Ent_Laser() } if(f & 2) { - self.velocity_x = ReadCoord(); - self.velocity_y = ReadCoord(); - self.velocity_z = ReadCoord(); + self.angles_x = ReadCoord(); + self.angles_y = ReadCoord(); } + if(f & 4) + self.state = ReadByte(); self.draw = Draw_Laser; } diff --git a/data/qcsrc/server/g_triggers.qc b/data/qcsrc/server/g_triggers.qc index b17921c1f..f683d0e1d 100644 --- a/data/qcsrc/server/g_triggers.qc +++ b/data/qcsrc/server/g_triggers.qc @@ -520,20 +520,6 @@ float pointparticles_SendEntity(entity to, float fl) } void pointparticles_use() -{ - if(self.wait && time < self.nextthink) - { - self.nextthink = time + self.wait; // extend the time - return; - } - - if(self.wait) - self.nextthink = time + self.wait; // toggle back after a delay - self.state = !self.state; - self.SendFlags |= 2; -} - -void pointparticles_think() { self.state = !self.state; self.SendFlags |= 2; @@ -561,7 +547,6 @@ void spawnfunc_func_pointparticles() self.state = 1; else self.state = 0; - self.think = pointparticles_think; } else self.state = 1; @@ -696,30 +681,38 @@ void spawnfunc_func_snow() void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, float deathtype); -void misc_laser_think() + +void misc_laser_aim() { - vector o, a; - if(!self.state) - { - self.enemy = find(world, targetname, self.target); - self.state = 1; - } + vector a; if(self.enemy) { - o = self.enemy.origin; - a = vectoangles(o - self.origin); + a = vectoangles(self.enemy.origin - self.origin); if(a != self.angles) { self.angles = a; - self.Version += 1; + self.SendFlags |= 2; } } - else +} + +void misc_laser_think() +{ + vector o; + if(!self.count) { - makevectors(self.angles); - o = self.origin + v_forward * MAX_SHOT_DISTANCE; + self.enemy = find(world, targetname, self.target); + self.count = 1; } + if(!self.state) + return; + + misc_laser_aim(); + + makevectors(self.angles); + o = self.origin + 32768 * v_forward; + if(self.dmg) { if(self.dmg < 0) @@ -744,14 +737,15 @@ float laser_SendEntity(entity to, float fl) } if(fl & 2) { - WriteCoord(MSG_ENTITY, self.velocity_x); - WriteCoord(MSG_ENTITY, self.velocity_y); - WriteCoord(MSG_ENTITY, self.velocity_z); + WriteCoord(MSG_ENTITY, self.angles_x); + WriteCoord(MSG_ENTITY, self.angles_y); } + if(fl & 4) + WriteByte(MSG_ENTITY, self.state); return 1; } -/*QUAKED spawnfunc_misc_laser (.5 .5 .5) ? +/*QUAKED spawnfunc_misc_laser (.5 .5 .5) ? START_ON Any object touching the beam will be hurt Keys: "target" @@ -763,6 +757,13 @@ Keys: "dmg" damage per second (-1 for a laser that kills immediately) */ +void laser_use() +{ + self.state = !self.state; + self.SendFlags |= 4; + misc_laser_aim(); +} + void spawnfunc_misc_laser() { if(self.mdl) @@ -784,9 +785,20 @@ void spawnfunc_misc_laser() self.effects = EF_NODEPTHTEST; self.SendEntity = laser_SendEntity; - self.SendFlags = 3; + self.SendFlags = 7; self.modelindex = 1; self.model = "net_entity"; + + if(self.targetname != "") + { + self.use = laser_use; + if(self.spawnflags & 1) + self.state = 1; + else + self.state = 0; + } + else + self.state = 1; } // tZorks trigger impulse / gravity @@ -966,3 +978,46 @@ void spawnfunc_trigger_impulse() } } +/*QUAKED spawnfunc_trigger_flipflop (.5 .5 .5) (-8 -8 -8) (8 8 8) START_ENABLED +"Flip-flop" trigger gate... lets only every second trigger event through +*/ +void flipflop_use() +{ + self.state = !self.state; + if(self.state) + SUB_UseTargets(); +} + +void spawnfunc_trigger_flipflop() +{ + if(self.spawnflags & 1) + self.state = 1; + self.use = flipflop_use; +} + +/*QUAKED spawnfunc_trigger_monoflop (.5 .5 .5) (-8 -8 -8) (8 8 8) +"Mono-flop" trigger gate... turns one trigger event into one "on" and one "off" event, separated by a delay of "wait" +*/ +void monoflop_use() +{ + self.nextthink = time + self.wait; + if(self.state) + return; + self.state = 1; + SUB_UseTargets(); +} + +void monoflop_think() +{ + self.state = 0; + SUB_UseTargets(); +} + +void spawnfunc_trigger_monoflop() +{ + if(!self.wait) + self.wait = 1; + self.use = monoflop_use; + self.think = monoflop_think; + self.state = 0; +} diff --git a/data/scripts/entities.def b/data/scripts/entities.def index 1f0269424..6262b0d8a 100644 --- a/data/scripts/entities.def +++ b/data/scripts/entities.def @@ -496,13 +496,18 @@ LINEAR: Use a linear falloff. Default is inverse distance squared (more realisti NOANGLE: Ignore angle attenuation. */ -/*QUAKED misc_laser (.5 .5 .5) (-8 -8 -8) (8 8 8) +/*QUAKED misc_laser (.5 .5 .5) (-8 -8 -8) (8 8 8) START_ON Laser beam emitter -------- KEYS -------- target: target_position the laser targets (may be another entity, the laser will then target its origin. Use origin brushes, that is!) mdl: name of particle effect for the beam end point (see effectinfo.txt; default is misc_laser_beam_end) colormod: color of the laser beam (default: red, that is, 1 0 0) dmg: damage inflicted by the beam per second, or -1 for an instant-death ray +targetname: name to target this (then its state is toggled) +-------- SPAWNFLAGS -------- +START_ON: when targeted, the laser will start switched on +-------- NOTES -------- +Use trigger_monoflop if you want the laser to turn off for a while, then turn back on */ /*QUAKED misc_model (1 .5 .25) (-16 -16 -16) (16 16 16) - SOLID - EXTRUDE_NORMALS EXTRUDE_TERRAIN @@ -659,7 +664,7 @@ After the counter has been triggered "count" times, it will fire all of its targ -------- KEYS -------- count: how many times this needs to be triggered to activate its targets target: trigger all entities with this targetname when triggered -targetname: name that identifies this entity so ti can be triggered +targetname: name that identifies this entity so it can be triggered delay: delay the triggering by the given time message: print this message to the player who activated the trigger killtarget: remove all entities with this targetname when triggered @@ -672,7 +677,7 @@ Trigger that delays triggering by a given amount of time. Only one action can be -------- KEYS -------- wait: delay the triggering by the given time target: trigger all entities with this targetname when triggered -targetname: name that identifies this entity so ti can be triggered +targetname: name that identifies this entity so it can be triggered message: print this message to the player who activated the trigger killtarget: remove all entities with this targetname when triggered */ @@ -706,7 +711,7 @@ wait: prevent triggering again for this amount of time sounds: 1 to play misc/secret.wav, 2 to play misc/talk.wav, 3 to play misc/trigger1.wav noise: path to sound file, if you want to play something else target: trigger all entities with this targetname when triggered -targetname: name that identifies this entity so ti can be triggered +targetname: name that identifies this entity so it can be triggered delay: delay the triggering by the given time message: print this message to the player who activated the trigger killtarget: remove all entities with this targetname when triggered @@ -722,7 +727,7 @@ health: amount of damage that has to be dealt to the trigger to activate (it the sounds: 1 to play misc/secret.wav, 2 to play misc/talk.wav, 3 to play misc/trigger1.wav noise: path to sound file, if you want to play something else target: trigger all entities with this targetname when triggered -targetname: name that identifies this entity so ti can be triggered +targetname: name that identifies this entity so it can be triggered delay: delay the triggering by the given time message: print this message to the player who activated the trigger killtarget: remove all entities with this targetname when triggered @@ -750,7 +755,7 @@ One possible use is to trigger entities with more than one targetname on an acti More than one "trigger event" can be delayed at once, as opposed to trigger_delay. -------- KEYS -------- target: trigger all entities with this targetname when triggered -targetname: name that identifies this entity so ti can be triggered +targetname: name that identifies this entity so it can be triggered delay: delay the triggering by the given time message: print this message to the player who activated the trigger killtarget: remove all entities with this targetname when triggered @@ -918,8 +923,26 @@ count: particle count multiplier (per spawned particle) movedir: when set, trace direction (particles will then be emitted from the surface the trace hits); the length of the vector is used as strength of taking the normal of the trace into account glow_color: particle palette color noise: sound to play when the particle is emitted -targetname: name to target this -wait: when set and targeted, it will enable when triggered, and disable after a delay; otherwise, it will disable when triggered again +targetname: name to target this (then its state is toggled) -------- SPAWNFLAGS -------- START_ON: when targeted, the particle emitter will start switched on +-------- NOTES -------- +Use trigger_monoflop if you want the particles to turn off for a while, then turn back on +*/ + +/*QUAKED trigger_flipflop (.5 .5 .5) (-8 -8 -8) (8 8 8) START_ON +"Flip-flop" trigger gate... lets only every second trigger event through +-------- KEYS -------- +target: trigger all entities with this targetname when triggered +targetname: name that identifies this entity so it can be triggered +-------- SPAWNFLAGS -------- +START_ON: assume it is already turned on (so the first event is NOT passed through) +*/ + +/*QUAKED trigger_monoflop (.5 .5 .5) (-8 -8 -8) (8 8 8) +"Mono-flop" trigger gate... turns trigger events into pairs of events +-------- KEYS -------- +target: trigger all entities with this targetname when triggered +targetname: name that identifies this entity so it can be triggered +wait: time to wait until the "off" event is fired (when it is triggered again in the meantime, the "off" delay is extended and no new "on" event is fired) */ -- 2.39.2