X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Ftriggers%2Ftriggers.qc;h=4493138d08dca032f149aaba09a4f8e5f2817f53;hb=42e255d014f2c6a1871177ea511f630624cdfb57;hp=e8131b47b71e024ed5fa9a4da4f9ffec94cfb0bb;hpb=22a37c4431f80ece25aeff28c18bc67dd183a352;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/triggers/triggers.qc b/qcsrc/common/triggers/triggers.qc index e8131b47b..4493138d0 100644 --- a/qcsrc/common/triggers/triggers.qc +++ b/qcsrc/common/triggers/triggers.qc @@ -1,12 +1,11 @@ -void SUB_DontUseTargets() { } +void SUB_DontUseTargets(entity this, entity actor, entity trigger) { } -void() SUB_UseTargets; +void SUB_UseTargets(entity this, entity actor, entity trigger); void DelayThink() -{ - activator = self.enemy; - SUB_UseTargets (); - remove(self); +{SELFPARAM(); + SUB_UseTargets (this, this.enemy, NULL); + remove(this); } void FixSize(entity e) @@ -20,6 +19,151 @@ void FixSize(entity e) e.maxs_z = rint(e.maxs_z); } +#ifdef SVQC + +void trigger_init(entity this) +{ + string m = this.model; + WITHSELF(this, WarpZoneLib_ExactTrigger_Init()); + if(m != "") + { + precache_model(m); + _setmodel(this, m); // no precision needed + } + setorigin(this, this.origin); + if(this.scale) + setsize(this, this.mins * this.scale, this.maxs * this.scale); + else + setsize(this, this.mins, this.maxs); + + BITSET_ASSIGN(this.effects, EF_NODEPTHTEST); +} + +void trigger_link(entity this, bool(entity this, entity to, int sendflags) sendfunc) +{ + this.SendEntity = SendEntity_self; + this.SendEntity3 = sendfunc; + this.SendFlags = 0xFFFFFF; +} + +void trigger_common_write(entity this, bool withtarget) +{ + int f = 0; + if(this.warpzone_isboxy) + BITSET_ASSIGN(f, 1); + if(this.origin != '0 0 0') + BITSET_ASSIGN(f, 4); + WriteByte(MSG_ENTITY, f); + + if(withtarget) + { + WriteString(MSG_ENTITY, this.target); + WriteString(MSG_ENTITY, this.target2); + WriteString(MSG_ENTITY, this.target3); + WriteString(MSG_ENTITY, this.target4); + WriteString(MSG_ENTITY, this.targetname); + WriteString(MSG_ENTITY, this.killtarget); + } + + if(f & 4) + { + WriteCoord(MSG_ENTITY, this.origin.x); + WriteCoord(MSG_ENTITY, this.origin.y); + WriteCoord(MSG_ENTITY, this.origin.z); + } + + WriteShort(MSG_ENTITY, this.modelindex); + WriteCoord(MSG_ENTITY, this.mins.x); + WriteCoord(MSG_ENTITY, this.mins.y); + WriteCoord(MSG_ENTITY, this.mins.z); + WriteCoord(MSG_ENTITY, this.maxs.x); + WriteCoord(MSG_ENTITY, this.maxs.y); + WriteCoord(MSG_ENTITY, this.maxs.z); + WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255)); + + WriteCoord(MSG_ENTITY, this.movedir_x); + WriteCoord(MSG_ENTITY, this.movedir_y); + WriteCoord(MSG_ENTITY, this.movedir_z); + + WriteCoord(MSG_ENTITY, this.angles_x); + WriteCoord(MSG_ENTITY, this.angles_y); + WriteCoord(MSG_ENTITY, this.angles_z); +} + +#elif defined(CSQC) + +void trigger_common_read(bool withtarget) +{SELFPARAM(); + int f = ReadByte(); + this.warpzone_isboxy = (f & 1); + + if(withtarget) + { + if(this.target) { strunzone(this.target); } + this.target = strzone(ReadString()); + if(this.target2) { strunzone(this.target2); } + this.target2 = strzone(ReadString()); + if(this.target3) { strunzone(this.target3); } + this.target3 = strzone(ReadString()); + if(this.target4) { strunzone(this.target4); } + this.target4 = strzone(ReadString()); + if(this.targetname) { strunzone(this.targetname); } + this.targetname = strzone(ReadString()); + if(this.killtarget) { strunzone(this.killtarget); } + this.killtarget = strzone(ReadString()); + } + + if(f & 4) + { + this.origin_x = ReadCoord(); + this.origin_y = ReadCoord(); + this.origin_z = ReadCoord(); + } + else + this.origin = '0 0 0'; + setorigin(this, this.origin); + + this.modelindex = ReadShort(); + this.mins_x = ReadCoord(); + this.mins_y = ReadCoord(); + this.mins_z = ReadCoord(); + this.maxs_x = ReadCoord(); + this.maxs_y = ReadCoord(); + this.maxs_z = ReadCoord(); + this.scale = ReadByte() / 16; + setsize(this, this.mins, this.maxs); + + this.movedir_x = ReadCoord(); + this.movedir_y = ReadCoord(); + this.movedir_z = ReadCoord(); + + this.angles_x = ReadCoord(); + this.angles_y = ReadCoord(); + this.angles_z = ReadCoord(); +} + +void trigger_remove_generic(entity this) +{ + if(this.target) { strunzone(this.target); } + this.target = string_null; + + if(this.target2) { strunzone(this.target2); } + this.target2 = string_null; + + if(this.target3) { strunzone(this.target3); } + this.target3 = string_null; + + if(this.target4) { strunzone(this.target4); } + this.target4 = string_null; + + if(this.targetname) { strunzone(this.targetname); } + this.target = string_null; + + if(this.killtarget) { strunzone(this.killtarget); } + this.killtarget = string_null; +} +#endif + /* ============================== SUB_UseTargets @@ -39,53 +183,49 @@ match (string)self.target and call their .use function ============================== */ -void SUB_UseTargets() +void SUB_UseTargets(entity this, entity actor, entity trigger) { - entity t, stemp, otemp, act; - string s; - float i; - // // check for a delay // - if (self.delay) + if (this.delay) { // create a temp object to fire at a later time - t = spawn(); - t.classname = "DelayedUse"; - t.nextthink = time + self.delay; + entity t = new(DelayedUse); + t.nextthink = time + this.delay; t.think = DelayThink; - t.enemy = activator; - t.message = self.message; - t.killtarget = self.killtarget; - t.target = self.target; - t.target2 = self.target2; - t.target3 = self.target3; - t.target4 = self.target4; + t.enemy = actor; + t.message = this.message; + t.killtarget = this.killtarget; + t.target = this.target; + t.target2 = this.target2; + t.target3 = this.target3; + t.target4 = this.target4; return; } + string s; // // print the message // #ifdef SVQC - if(self) - if(IS_PLAYER(activator) && self.message != "") - if(IS_REAL_CLIENT(activator)) + if(this) + if(IS_PLAYER(actor) && this.message != "") + if(IS_REAL_CLIENT(actor)) { - centerprint(activator, self.message); - if (self.noise == "") - play2(activator, "misc/talk.wav"); + centerprint(actor, this.message); + if (this.noise == "") + play2(actor, SND(TALK)); } // // kill the killtagets // - s = self.killtarget; + s = this.killtarget; if (s != "") { - for(t = world; (t = find(t, targetname, s)); ) + for(entity t = world; (t = find(t, targetname, s)); ) remove(t); } #endif @@ -93,83 +233,81 @@ void SUB_UseTargets() // // fire targets // - act = activator; - stemp = self; - otemp = other; - if(stemp.target_random) + if(this.target_random) RandomSelection_Init(); - for(i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) { switch(i) { default: - case 0: s = stemp.target; break; - case 1: s = stemp.target2; break; - case 2: s = stemp.target3; break; - case 3: s = stemp.target4; break; + case 0: s = this.target; break; + case 1: s = this.target2; break; + case 2: s = this.target3; break; + case 3: s = this.target4; break; } if (s != "") { - for(t = world; (t = find(t, targetname, s)); ) - if(t.use) + // Flag to set func_clientwall state + // 1 == deactivate, 2 == activate, 0 == do nothing + int aw_flag = this.antiwall_flag; + for(entity t = world; (t = find(t, targetname, s)); ) { - if(stemp.target_random) + if(t.use) { - RandomSelection_Add(t, 0, string_null, 1, 0); - } - else - { - self = t; - other = stemp; - activator = act; - self.use(); + if(this.target_random) + { + RandomSelection_Add(t, 0, string_null, 1, 0); + } + else + { + if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary") + t.antiwall_flag = aw_flag; + + t.use(t, actor, this); + } } } } } - if(stemp.target_random && RandomSelection_chosen_ent) - { - self = RandomSelection_chosen_ent; - other = stemp; - activator = act; - self.use(); - } + if(this.target_random && RandomSelection_chosen_ent) + RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this); +} - activator = act; - self = stemp; - other = otemp; +void SUB_UseTargets_self() +{SELFPARAM(); + SUB_UseTargets(this, NULL, NULL); } #ifdef CSQC -void trigger_touch_generic(void() touchfunc) +void trigger_touch_generic(entity this, void() touchfunc) { entity e; - for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain) - if(e.isplayermodel) + for(e = findradius((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1); e; e = e.chain) + if(e.classname == "csqcprojectile") { vector emin = e.absmin, emax = e.absmax; - if(self.solid == SOLID_BSP) + if(this.solid == SOLID_BSP) { emin -= '1 1 1'; emax += '1 1 1'; } - if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick - if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate + if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick + if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, e)) // accurate { other = e; - touchfunc(); + WITHSELF(this, touchfunc()); } } } -void trigger_draw_generic() +void trigger_draw_generic(entity this) { - float dt = time - self.move_time; - self.move_time = time; + float dt = time - this.move_time; + this.move_time = time; if(dt <= 0) { return; } - if(self.trigger_touch) { trigger_touch_generic(self.trigger_touch); } + if(this.trigger_touch) { trigger_touch_generic(this, this.trigger_touch); } } #endif