X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Ft_plats.qc;h=300cbd940bb3f8b741b4c8450be4268759a6a21a;hp=8af076ce2af89fdc8f4ce7c6f545a632e649c43f;hb=e14bb786305e05541496fb5b28c090e0ff1b5783;hpb=4b15b999e2716d2ddc35075f75910b330a6cbf5c diff --git a/qcsrc/server/t_plats.qc b/qcsrc/server/t_plats.qc index 8af076ce2..300cbd940 100644 --- a/qcsrc/server/t_plats.qc +++ b/qcsrc/server/t_plats.qc @@ -57,7 +57,17 @@ void plat_spawn_inside_trigger() tmax_y = tmin_y + 1; } - setsize (trigger, tmin, tmax); + if(tmin_x < tmax_x) + if(tmin_y < tmax_y) + if(tmin_z < tmax_z) + { + setsize (trigger, tmin, tmax); + return; + } + + // otherwise, something is fishy... + remove(trigger); + objerror("plat_spawn_inside_trigger: platform has odd size or lip, can't spawn"); } void plat_hit_top() @@ -148,7 +158,7 @@ void plat_crush() void plat_use() { - self.use = SUB_Null; + self.use = func_null; if (self.state != 4) objerror ("plat_use: not in up state"); plat_go_down(); @@ -175,20 +185,15 @@ void plat_reset() void spawnfunc_path_corner() { } void spawnfunc_func_plat() { - if (!self.t_length) - self.t_length = 80; - if (!self.t_width) - self.t_width = 10; - if (self.sounds == 0) self.sounds = 2; if(self.spawnflags & 4) self.dmg = 10000; - if(self.dmg && (!self.message)) + if(self.dmg && (self.message == "")) self.message = "was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if (self.sounds == 1) @@ -231,15 +236,19 @@ void spawnfunc_func_plat() if (!self.speed) self.speed = 150; + if (!self.lip) + self.lip = 16; + if (!self.height) + self.height = self.size_z - self.lip; self.pos1 = self.origin; self.pos2 = self.origin; - self.pos2_z = self.origin_z - self.size_z + 8; - - plat_spawn_inside_trigger (); // the "start moving" trigger + self.pos2_z = self.origin_z - self.height; self.reset = plat_reset; plat_reset(); + + plat_spawn_inside_trigger (); // the "start moving" trigger } @@ -273,7 +282,7 @@ void train_next() targ = find(world, targetname, self.target); self.enemy = targ; self.target = targ.target; - if (!self.target) + if (self.target == "") objerror("train_next: no next target"); self.wait = targ.wait; if (!self.wait) @@ -293,7 +302,7 @@ void func_train_find() entity targ; targ = find(world, targetname, self.target); self.target = targ.target; - if (!self.target) + if (self.target == "") objerror("func_train_find: no next target"); setorigin(self, targ.origin - self.mins); self.nextthink = self.ltime + 1; @@ -310,7 +319,7 @@ void spawnfunc_func_train() if (self.noise != "") precache_sound(self.noise); - if (!self.target) + if (self.target == "") objerror("func_train without a target"); if (!self.speed) self.speed = 100; @@ -323,9 +332,9 @@ void spawnfunc_func_train() InitializeEntity(self, func_train_find, INITPRIO_SETLOCATION); self.blocked = generic_plat_blocked; - if(self.dmg & (!self.message)) + if(self.dmg && (self.message == "")) self.message = " was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if(self.dmg && (!self.dmgtime)) self.dmgtime = 0.25; @@ -386,9 +395,9 @@ void spawnfunc_func_rotating() self.pos1 = self.avelocity; - if(self.dmg & (!self.message)) + if(self.dmg && (self.message == "")) self.message = " was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; @@ -405,7 +414,7 @@ void spawnfunc_func_rotating() // wait for targets to spawn self.nextthink = self.ltime + 999999999; - self.think = SUB_Null; + self.think = SUB_NullThink; // for PushMove // TODO make a reset function for this one } @@ -460,9 +469,9 @@ void spawnfunc_func_bobbing() // damage when blocked self.blocked = generic_plat_blocked; - if(self.dmg & (!self.message)) + if(self.dmg && (self.message == "")) self.message = " was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if(self.dmg && (!self.dmgtime)) self.dmgtime = 0.25; @@ -486,7 +495,7 @@ void spawnfunc_func_bobbing() controller.nextthink = time + 1; controller.think = func_bobbing_controller_think; self.nextthink = self.ltime + 999999999; - self.think = SUB_Null; + self.think = SUB_NullThink; // for PushMove // Savage: Reduce bandwith, critical on e.g. nexdm02 self.effects |= EF_LOWPRECISION; @@ -533,9 +542,9 @@ void spawnfunc_func_pendulum() self.speed = 30; // not initializing self.dmg to 2, to allow damageless pendulum - if(self.dmg & (!self.message)) + if(self.dmg && (self.message == "")) self.message = " was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if(self.dmg && (!self.dmgtime)) self.dmgtime = 0.25; @@ -563,7 +572,7 @@ void spawnfunc_func_pendulum() controller.nextthink = time + 1; controller.think = func_pendulum_controller_think; self.nextthink = self.ltime + 999999999; - self.think = SUB_Null; + self.think = SUB_NullThink; // for PushMove //self.effects |= EF_LOWPRECISION; @@ -633,12 +642,6 @@ void button_reset() void button_use() { -// if (activator.classname != "player") -// { -// dprint(activator.classname); -// dprint(" triggered a button\n"); -// } - if not (self.active == ACTIVE_ACTIVE) return; @@ -648,11 +651,6 @@ void button_use() void button_touch() { -// if (activator.classname != "player") -// { -// dprint(activator.classname); -// dprint(" touched a button\n"); -// } if (!other) return; if not(other.iscreature) @@ -673,11 +671,6 @@ void button_damage(entity inflictor, entity attacker, float damage, float deatht self.health = self.health - damage; if (self.health <= 0) { - // if (activator.classname != "player") - // { - // dprint(activator.classname); - // dprint(" killed a button\n"); - // } self.enemy = damage_attacker; button_fire (); } @@ -909,7 +902,7 @@ float door_check_keys(void) { // this door require a key // only a player can have a key - if (other.classname != "player") + if not(IS_PLAYER(other)) return FALSE; if (item_keys_usekey(door, other)) { @@ -1070,7 +1063,7 @@ Prints messages */ void door_touch() { - if(other.classname != "player") + if not(IS_PLAYER(other)) return; if (self.owner.attack_finished_single > time) return; @@ -1079,7 +1072,7 @@ void door_touch() if (!(self.owner.dmg) && (self.owner.message != "")) { - if (other.flags & FL_CLIENT) + if (IS_CLIENT(other)) centerprint (other, self.owner.message); play2(other, "misc/talk.wav"); } @@ -1216,24 +1209,32 @@ entity spawn_field(vector fmins, vector fmaxs) } -float EntitiesTouching(entity e1, entity e2) +entity LinkDoors_nextent(entity cur, entity near, entity pass) +{ + while((cur = find(cur, classname, self.classname)) && ((cur.spawnflags & 4) || cur.enemy)) + { + } + return cur; +} + +float LinkDoors_isconnected(entity e1, entity e2, entity pass) { - if (e1.absmin_x > e2.absmax_x) + float DELTA = 4; + if (e1.absmin_x > e2.absmax_x + DELTA) return FALSE; - if (e1.absmin_y > e2.absmax_y) + if (e1.absmin_y > e2.absmax_y + DELTA) return FALSE; - if (e1.absmin_z > e2.absmax_z) + if (e1.absmin_z > e2.absmax_z + DELTA) return FALSE; - if (e1.absmax_x < e2.absmin_x) + if (e2.absmin_x > e1.absmax_x + DELTA) return FALSE; - if (e1.absmax_y < e2.absmin_y) + if (e2.absmin_y > e1.absmax_y + DELTA) return FALSE; - if (e1.absmax_z < e2.absmin_z) + if (e2.absmin_z > e1.absmax_z + DELTA) return FALSE; return TRUE; } - /* ============= LinkDoors @@ -1243,7 +1244,7 @@ LinkDoors */ void LinkDoors() { - entity t, starte; + entity t; vector cmins, cmaxs; if (self.enemy) @@ -1263,68 +1264,70 @@ void LinkDoors() return; // don't want to link this door } - cmins = self.absmin; - cmaxs = self.absmax; + FindConnectedComponent(self, enemy, LinkDoors_nextent, LinkDoors_isconnected, world); - starte = self; - t = self; - - do + // set owner, and make a loop of the chain + dprint("LinkDoors: linking doors:"); + for(t = self; ; t = t.enemy) { - self.owner = starte; // master door - - if (self.health) - starte.health = self.health; - IFTARGETED - starte.targetname = self.targetname; - if (self.message != "") - starte.message = self.message; - - t = find(t, classname, self.classname); - if (!t) + dprint(" ", etos(t)); + t.owner = self; + if(t.enemy == world) { - self.enemy = starte; // make the chain a loop - - // shootable, or triggered doors just needed the owner/enemy links, - // they don't spawn a field - - self = self.owner; + t.enemy = self; + break; + } + } + dprint("\n"); - if (self.health) - return; - IFTARGETED - return; - if (self.items) - return; + // collect health, targetname, message, size + cmins = self.absmin; + cmaxs = self.absmax; + for(t = self; ; t = t.enemy) + { + if(t.health && !self.health) + self.health = t.health; + if((t.targetname != "") && (self.targetname == "")) + self.targetname = t.targetname; + if((t.message != "") && (self.message == "")) + self.message = t.message; + if (t.absmin_x < cmins_x) + cmins_x = t.absmin_x; + if (t.absmin_y < cmins_y) + cmins_y = t.absmin_y; + if (t.absmin_z < cmins_z) + cmins_z = t.absmin_z; + if (t.absmax_x > cmaxs_x) + cmaxs_x = t.absmax_x; + if (t.absmax_y > cmaxs_y) + cmaxs_y = t.absmax_y; + if (t.absmax_z > cmaxs_z) + cmaxs_z = t.absmax_z; + if(t.enemy == self) + break; + } - self.owner.trigger_field = spawn_field(cmins, cmaxs); + // distribute health, targetname, message + for(t = self; t; t = t.enemy) + { + t.health = self.health; + t.targetname = self.targetname; + t.message = self.message; + if(t.enemy == self) + break; + } - return; - } + // shootable, or triggered doors just needed the owner/enemy links, + // they don't spawn a field - if (EntitiesTouching(self,t)) - { - if (t.enemy) - objerror ("cross connected doors"); - - self.enemy = t; - self = t; - - if (t.absmin_x < cmins_x) - cmins_x = t.absmin_x; - if (t.absmin_y < cmins_y) - cmins_y = t.absmin_y; - if (t.absmin_z < cmins_z) - cmins_z = t.absmin_z; - if (t.absmax_x > cmaxs_x) - cmaxs_x = t.absmax_x; - if (t.absmax_y > cmaxs_y) - cmaxs_y = t.absmax_y; - if (t.absmax_z > cmaxs_z) - cmaxs_z = t.absmax_z; - } - } while (1 ); + if (self.health) + return; + IFTARGETED + return; + if (self.items) + return; + self.trigger_field = spawn_field(cmins, cmaxs); } @@ -1369,7 +1372,8 @@ void door_reset() setorigin(self, self.pos1); self.velocity = '0 0 0'; self.state = STATE_BOTTOM; - self.think = SUB_Null; + self.think = func_null; + self.nextthink = 0; } // spawnflags require key (for now only func_door) @@ -1400,9 +1404,9 @@ void spawnfunc_func_door() // if(self.spawnflags & 8) // self.dmg = 10000; - if(self.dmg && (!self.message)) + if(self.dmg && (self.message == "")) self.message = "was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if (self.sounds > 0) @@ -1481,7 +1485,8 @@ void door_rotating_reset() self.angles = self.pos1; self.avelocity = '0 0 0'; self.state = STATE_BOTTOM; - self.think = SUB_Null; + self.think = func_null; + self.nextthink = 0; } void door_rotating_init_startopen() @@ -1525,9 +1530,9 @@ void spawnfunc_func_door_rotating() if(self.spawnflags & 8) self.dmg = 10000; - if(self.dmg && (!self.message)) + if(self.dmg && (self.message == "")) self.message = "was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if (self.sounds > 0) @@ -1594,7 +1599,6 @@ float SECRET_1ST_DOWN = 4; // 1st move is down from arrow float SECRET_NO_SHOOT = 8; // only opened by trigger float SECRET_YES_SHOOT = 16; // shootable even if targeted - void fd_secret_use() { float temp; @@ -1645,6 +1649,11 @@ void fd_secret_use() sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); } +void fd_secret_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) +{ + fd_secret_use(); +} + // Wait after first movement... void fd_secret_move1() { @@ -1736,7 +1745,7 @@ void secret_touch() if (self.message) { - if (other.flags & FL_CLIENT) + if (IS_CLIENT(other)) centerprint (other, self.message); play2(other, "misc/talk.wav"); } @@ -1750,7 +1759,8 @@ void secret_reset() self.takedamage = DAMAGE_YES; } setorigin(self, self.oldorigin); - self.think = SUB_Null; + self.think = func_null; + self.nextthink = 0; } /*QUAKED spawnfunc_func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot @@ -1800,7 +1810,7 @@ void spawnfunc_func_door_secret() { self.health = 10000; self.takedamage = DAMAGE_YES; - self.event_damage = fd_secret_use; + self.event_damage = fd_secret_damage; } self.oldorigin = self.origin; if (!self.wait) @@ -1867,9 +1877,9 @@ void spawnfunc_func_fourier() self.cnt = 360 / self.speed; self.blocked = generic_plat_blocked; - if(self.dmg & (!self.message)) + if(self.dmg && (self.message == "")) self.message = " was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message2 == "")) self.message2 = "was squished by"; if(self.dmg && (!self.dmgtime)) self.dmgtime = 0.25; @@ -1890,7 +1900,7 @@ void spawnfunc_func_fourier() controller.nextthink = time + 1; controller.think = func_fourier_controller_think; self.nextthink = self.ltime + 999999999; - self.think = SUB_Null; + self.think = SUB_NullThink; // for PushMove // Savage: Reduce bandwith, critical on e.g. nexdm02 self.effects |= EF_LOWPRECISION; @@ -1987,7 +1997,7 @@ void func_vectormamamam_findtarget() if(!self.wp00 && !self.wp01 && !self.wp02 && !self.wp03) objerror("No reference entity found, so there is nothing to move. Aborting."); - self.destvec = self.origin - func_vectormamamam_origin(self.owner, 0); + self.destvec = self.origin - func_vectormamamam_origin(self, 0); entity controller; controller = spawn(); @@ -2030,9 +2040,9 @@ void spawnfunc_func_vectormamamam() self.target4normal = normalize(self.target4normal); self.blocked = generic_plat_blocked; - if(self.dmg & (!self.message)) + if(self.dmg && (self.message == "")) self.message = " was squished"; - if(self.dmg && (!self.message2)) + if(self.dmg && (self.message == "")) self.message2 = "was squished by"; if(self.dmg && (!self.dmgtime)) self.dmgtime = 0.25; @@ -2046,7 +2056,7 @@ void spawnfunc_func_vectormamamam() // wait for targets to spawn self.nextthink = self.ltime + 999999999; - self.think = SUB_Null; + self.think = SUB_NullThink; // for PushMove // Savage: Reduce bandwith, critical on e.g. nexdm02 self.effects |= EF_LOWPRECISION; @@ -2058,45 +2068,67 @@ void spawnfunc_func_vectormamamam() void conveyor_think() { - for(other = world; (other = findentity(other, groundentity, self)); ) + entity e; + + // set myself as current conveyor where possible + for(e = world; (e = findentity(e, conveyor, self)); ) + e.conveyor = world; + + if(self.state) { - if(other.flags & FL_CLIENT) // doing it via velocity has quite some advantages - continue; // done in SV_PlayerPhysics + for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain) + if(!e.conveyor.state) + if(isPushable(e)) + { + vector emin = e.absmin; + vector emax = e.absmax; + if(self.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 + e.conveyor = self; + } - // stupid conveyor code - tracebox(other.origin, other.mins, other.maxs, other.origin + self.movedir * sys_frametime, MOVE_NORMAL, other); - if(trace_fraction > 0) - setorigin(other, trace_endpos); + for(e = world; (e = findentity(e, conveyor, self)); ) + { + if(IS_CLIENT(e)) // doing it via velocity has quite some advantages + continue; // done in SV_PlayerPhysics + + setorigin(e, e.origin + self.movedir * sys_frametime); + move_out_of_solid(e); + UpdateCSQCProjectile(e); + /* + // stupid conveyor code + tracebox(e.origin, e.mins, e.maxs, e.origin + self.movedir * sys_frametime, MOVE_NORMAL, e); + if(trace_fraction > 0) + setorigin(e, trace_endpos); + */ + } } + self.nextthink = time; } void conveyor_use() { - if(self.nextthink) - self.nextthink = 0; - else - self.nextthink = time; + self.state = !self.state; } void conveyor_reset() { - if(self.spawnflags & 1) - self.nextthink = time; - else - self.nextthink = 0; + self.state = (self.spawnflags & 1); } -void spawnfunc_func_conveyor() +void conveyor_init() { - SetMovedir (); - if not(InitMovingBrushTrigger()) - return; - self.movetype = MOVETYPE_NONE; if (!self.speed) self.speed = 200; self.movedir = self.movedir * self.speed; self.think = conveyor_think; + self.nextthink = time; IFTARGETED { self.use = conveyor_use; @@ -2104,5 +2136,20 @@ void spawnfunc_func_conveyor() conveyor_reset(); } else - self.nextthink = time; + self.state = 1; +} + +void spawnfunc_trigger_conveyor() +{ + SetMovedir(); + EXACTTRIGGER_INIT; + conveyor_init(); +} + +void spawnfunc_func_conveyor() +{ + SetMovedir(); + InitMovingBrushTrigger(); + self.movetype = MOVETYPE_NONE; + conveyor_init(); }