X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_triggers.qc;h=4a66f229380ea9c505962ae4e5aa0abe9674d171;hb=162a91bc68d7b8e58c92cb0af873871129e386a9;hp=33f1a562499c4aa133265f00404cc16d11979d88;hpb=b1c6d40e1d8e9d5a83cb78ef7334aab3b0ce1f6f;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/g_triggers.qc b/qcsrc/server/g_triggers.qc index 33f1a5624..4a66f2293 100644 --- a/qcsrc/server/g_triggers.qc +++ b/qcsrc/server/g_triggers.qc @@ -413,6 +413,13 @@ void spawnfunc_trigger_counter() .float triggerhurttime; void trigger_hurt_touch() { + if (self.active != ACTIVE_ACTIVE) + return; + + if(self.team) + if((self.spawnflags & 4 == 0) == (self.team != other.team)) + return; + // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu) if (other.iscreature) { @@ -455,6 +462,7 @@ entity trigger_hurt_first; void spawnfunc_trigger_hurt() { EXACTTRIGGER_INIT; + self.active = ACTIVE_ACTIVE; self.touch = trigger_hurt_touch; if (!self.dmg) self.dmg = 1000; @@ -462,6 +470,7 @@ void spawnfunc_trigger_hurt() self.message = "was in the wrong place"; if (!self.message2) self.message2 = "was thrown into a world of hurt by"; + // self.message = "someone like %s always gets wrongplaced"; if(!trigger_hurt_first) trigger_hurt_first = self; @@ -492,6 +501,9 @@ float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end) .float triggerhealtime; void trigger_heal_touch() { + if (self.active != ACTIVE_ACTIVE) + return; + // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu) if (other.iscreature) { @@ -513,6 +525,8 @@ void trigger_heal_touch() void spawnfunc_trigger_heal() { + self.active = ACTIVE_ACTIVE; + EXACTTRIGGER_INIT; self.touch = trigger_heal_touch; if (!self.health) @@ -533,61 +547,113 @@ void spawnfunc_trigger_heal() // ////////////////////////////////////////////////////////////// -.float triggergravity, triggergravitytime, oldgravity; .entity trigger_gravity_check; +void trigger_gravity_remove(entity own) +{ + if(own.trigger_gravity_check.owner == own) + { + UpdateCSQCProjectile(own); + own.gravity = own.trigger_gravity_check.gravity; + remove(own.trigger_gravity_check); + } + else + backtrace("Removing a trigger_gravity_check with no valid owner"); + own.trigger_gravity_check = world; +} void trigger_gravity_check_think() { - // Entity that spawns when you enter a gravity zone, and checks if you left it - if(self.owner.triggergravitytime < time - 0.1) // need to figure out a correct formula here + // This spawns when a player enters the gravity zone and checks if he left. + // Each frame, self.count is set to 2 by trigger_gravity_touch() and decreased by 1 here. + // It the player has left the gravity trigger, this will be allowed to reach 0 and indicate that. + if(self.count <= 0) { - dprint("XXXXXXXXXXXXXXXXXXXXXXXXXX "); - self.owner.gravity = self.owner.oldgravity; - self.owner.triggergravity = 0; - remove(self); + if(self.owner.trigger_gravity_check == self) + trigger_gravity_remove(self.owner); + else + remove(self); + return; } else + { + self.count -= 1; self.nextthink = time; -} + } +}; + +void trigger_gravity_use() +{ + self.state = !self.state; +}; void trigger_gravity_touch() { - if(sv_gravity != 800) + float g; + + if(self.state != TRUE) return; - // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu) - if (other.triggergravitytime < time) - { - EXACTTRIGGER_TOUCH; - other.triggergravitytime = time + 0.1; - if(!other.triggergravity) - { - other.triggergravity = 1; - other.trigger_gravity_check = spawn(); - other.trigger_gravity_check.owner = other; - other.trigger_gravity_check.think = trigger_gravity_check_think; - other.trigger_gravity_check.nextthink = time; - } + EXACTTRIGGER_TOUCH; - if (other.gravity != self.gravity) + g = self.gravity; + + if not(self.spawnflags & 1) + { + if(other.trigger_gravity_check) { - other.oldgravity = other.gravity; - other.gravity = self.gravity; - if(self.noise != "") - sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM); + if(self == other.trigger_gravity_check.enemy) + { + // same? + other.trigger_gravity_check.count = 2; // gravity one more frame... + return; + } + + // compare prio + if(self.cnt > other.trigger_gravity_check.enemy.cnt) + trigger_gravity_remove(other); + else + return; } + other.trigger_gravity_check = spawn(); + other.trigger_gravity_check.enemy = self; + other.trigger_gravity_check.owner = other; + other.trigger_gravity_check.gravity = other.gravity; + other.trigger_gravity_check.think = trigger_gravity_check_think; + other.trigger_gravity_check.nextthink = time; + other.trigger_gravity_check.count = 2; + if(other.gravity) + g *= other.gravity; + } + + if (other.gravity != g) + { + other.gravity = g; + if(self.noise != "") + sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM); + UpdateCSQCProjectile(self.owner); } }; void spawnfunc_trigger_gravity() { - if(!self.gravity) + if(self.gravity == 1) return; + EXACTTRIGGER_INIT; self.touch = trigger_gravity_touch; if(self.noise != "") precache_sound(self.noise); + + self.state = TRUE; + IFTARGETED + { + self.use = trigger_gravity_use; + if(self.spawnflags & 2) + self.state = FALSE; + } }; +//============================================================================= + // TODO add a way to do looped sounds with sound(); then complete this entity .float volume, atten; void target_speaker_use() {sound(self, CHAN_TRIGGER, self.noise, VOL_BASE * self.volume, self.atten);} @@ -766,7 +832,7 @@ void spawnfunc_func_pointparticles() if(!self.cnt) self.cnt = particleeffectnum(self.mdl); - Net_LinkEntity(self, FALSE, 0, pointparticles_SendEntity); + Net_LinkEntity(self, (self.spawnflags & 4), 0, pointparticles_SendEntity); IFTARGETED { @@ -950,6 +1016,8 @@ void misc_laser_think() { vector o; entity oldself; + entity hitent; + vector hitloc; self.nextthink = time; @@ -970,20 +1038,18 @@ void misc_laser_think() o = self.origin + v_forward * 32768; } - if(self.dmg) + if(self.dmg || self.enemy.target != "") { - if(self.dmg < 0) - FireRailgunBullet(self.origin, o, 100000, 0, 0, 0, 0, 0, DEATH_HURTTRIGGER); - else - FireRailgunBullet(self.origin, o, self.dmg * frametime, 0, 0, 0, 0, 0, DEATH_HURTTRIGGER); + traceline(self.origin, o, MOVE_NORMAL, self); } + hitent = trace_ent; + hitloc = trace_endpos; if(self.enemy.target != "") // DETECTOR laser { - traceline(self.origin, o, MOVE_NORMAL, self); if(trace_ent.iscreature) { - self.pusher = trace_ent; + self.pusher = hitent; if(!self.count) { self.count = 1; @@ -1009,18 +1075,29 @@ void misc_laser_think() } } } + + if(self.dmg) + { + if(self.team) + if((self.spawnflags & 8 == 0) == (self.team != hitent.team)) + return; + if(hitent.takedamage) + Damage(hitent, self, self, ((self.dmg < 0) ? 100000 : (self.dmg * frametime)), DEATH_HURTTRIGGER, hitloc, '0 0 0'); + } } float laser_SendEntity(entity to, float fl) { WriteByte(MSG_ENTITY, ENT_CLIENT_LASER); - fl = fl - (fl & 0xE0); // use that bit to indicate finite length laser + fl = fl - (fl & 0xF0); // use that bit to indicate finite length laser if(self.spawnflags & 2) fl |= 0x80; if(self.alpha) fl |= 0x40; if(self.scale != 1 || self.modelscale != 1) fl |= 0x20; + if(self.spawnflags & 4) + fl |= 0x10; WriteByte(MSG_ENTITY, fl); if(fl & 1) { @@ -1040,7 +1117,8 @@ float laser_SendEntity(entity to, float fl) WriteByte(MSG_ENTITY, bound(0, self.scale * 16.0, 255)); WriteByte(MSG_ENTITY, bound(0, self.modelscale * 16.0, 255)); } - WriteShort(MSG_ENTITY, self.cnt + 1); + if((fl & 0x80) || !(fl & 0x10)) // effect doesn't need sending if the laser is infinite and has collision testing turned off + WriteShort(MSG_ENTITY, self.cnt + 1); } if(fl & 2) { @@ -1123,6 +1201,8 @@ void spawnfunc_misc_laser() self.scale = 1; if(!self.modelscale) self.modelscale = 1; + else if(self.modelscale < 0) + self.modelscale = 0; self.think = misc_laser_think; self.nextthink = time; InitializeEntity(self, misc_laser_init, INITPRIO_FINDTARGET); @@ -1154,6 +1234,9 @@ void trigger_impulse_touch1() float pushdeltatime; float str; + if (self.active != ACTIVE_ACTIVE) + return; + // FIXME: Better checking for what to push and not. if not(other.iscreature) if (other.classname != "corpse") @@ -1197,7 +1280,8 @@ void trigger_impulse_touch1() if(!pushdeltatime) return; other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime; - other.flags &~= FL_ONGROUND; + other.flags &~= FL_ONGROUND; + UpdateCSQCProjectile(other); } // Directionless (accelerator/decelerator) mode @@ -1205,6 +1289,9 @@ void trigger_impulse_touch2() { float pushdeltatime; + if (self.active != ACTIVE_ACTIVE) + return; + // FIXME: Better checking for what to push and not. if not(other.iscreature) if (other.classname != "corpse") @@ -1234,6 +1321,7 @@ void trigger_impulse_touch2() // div0: ticrate independent, 1 = identity (not 20) other.velocity = other.velocity * pow(self.strength, pushdeltatime); + UpdateCSQCProjectile(other); } // Spherical (gravity/repulsor) mode @@ -1242,6 +1330,9 @@ void trigger_impulse_touch3() float pushdeltatime; float str; + if (self.active != ACTIVE_ACTIVE) + return; + // FIXME: Better checking for what to push and not. if not(other.iscreature) if (other.classname != "corpse") @@ -1281,6 +1372,7 @@ void trigger_impulse_touch3() str = self.strength; other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime; + UpdateCSQCProjectile(other); } /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ? @@ -1303,6 +1395,8 @@ in directional and sperical mode. For damper/accelerator mode this is not nesses void spawnfunc_trigger_impulse() { + self.active = ACTIVE_ACTIVE; + EXACTTRIGGER_INIT; if(self.radius) { @@ -1879,3 +1973,64 @@ void spawnfunc_trigger_magicear() // target: // what to trigger } + +void relay_activators_use() +{ + entity trg, os; + + os = self; + + for(trg = world; (trg = find(trg, targetname, os.target)); ) + { + self = trg; + if (trg.setactive) + trg.setactive(os.cnt); + else + { + //bprint("Not using setactive\n"); + if(os.cnt == ACTIVE_TOGGLE) + if(trg.active == ACTIVE_ACTIVE) + trg.active = ACTIVE_NOT; + else + trg.active = ACTIVE_ACTIVE; + else + trg.active = os.cnt; + } + } + self = os; +} + +void spawnfunc_relay_activate() +{ + self.cnt = ACTIVE_ACTIVE; + self.use = relay_activators_use; +} + +void spawnfunc_relay_deactivate() +{ + self.cnt = ACTIVE_NOT; + self.use = relay_activators_use; +} + +void spawnfunc_relay_activatetoggle() +{ + self.cnt = ACTIVE_TOGGLE; + self.use = relay_activators_use; +} + +.string chmap, gametype; +void spawnfunc_target_changelevel_use() +{ + if(self.gametype != "") + MapInfo_SwitchGameType(MapInfo_Type_FromString(self.gametype)); + + if (self.chmap == "") + localcmd("endmatch\n"); + else + localcmd(strcat("changelevel ", self.chmap, "\n")); +}; + +void spawnfunc_target_changelevel() +{ + self.use = spawnfunc_target_changelevel_use; +};