X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Ft_plats.qc;h=440e16c5c5193a617ce317f2779d60222d4cba83;hb=3dc59a4b8f4bcbad4d6f0485fb1751c6c65eaa26;hp=a556d6d0bb192dd72d9417d2535a7eafa3e82aac;hpb=737b9aa03c6796ac761630483cb5e9bf5ef56174;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/t_plats.qc b/qcsrc/server/t_plats.qc index a556d6d0b..440e16c5c 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() @@ -78,14 +88,14 @@ void plat_go_down() { sound (self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTN_NORM); self.state = 3; - SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom); + SUB_CalcMove (self.pos2, TSPEED_LINEAR, self.speed, plat_hit_bottom); } void plat_go_up() { sound (self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTN_NORM); self.state = 4; - SUB_CalcMove (self.pos1, self.speed, plat_hit_top); + SUB_CalcMove (self.pos1, TSPEED_LINEAR, self.speed, plat_hit_top); } void plat_center_touch() @@ -172,7 +182,43 @@ void plat_reset() } } -void spawnfunc_path_corner() { } +.float platmovetype_start_default, platmovetype_end_default; +float set_platmovetype(entity e, string s) +{ + // sets platmovetype_start and platmovetype_end based on a string consisting of two values + + float n; + n = tokenize_console(s); + if(n > 0) + e.platmovetype_start = stof(argv(0)); + else + e.platmovetype_start = 0; + + if(n > 1) + e.platmovetype_end = stof(argv(1)); + else + e.platmovetype_end = e.platmovetype_start; + + if(n > 2) + if(argv(2) == "force") + return TRUE; // no checking, return immediately + + if(!cubic_speedfunc_is_sane(e.platmovetype_start, e.platmovetype_end)) + { + objerror("Invalid platform move type; platform would go in reverse, which is not allowed."); + return FALSE; + } + + return TRUE; +} + +void spawnfunc_path_corner() +{ + // setup values for overriding train movement + // if a second value does not exist, both start and end speeds are the single value specified + if(!set_platmovetype(self, self.platmovetype)) + return; +} void spawnfunc_func_plat() { if (self.sounds == 0) @@ -235,21 +281,57 @@ void spawnfunc_func_plat() self.pos2 = self.origin; self.pos2_z = self.origin_z - self.height; - plat_spawn_inside_trigger (); // the "start moving" trigger - self.reset = plat_reset; plat_reset(); -} + plat_spawn_inside_trigger (); // the "start moving" trigger +} +.float train_wait_turning; void() train_next; void train_wait() { + entity oldself; + oldself = self; + self = self.enemy; + SUB_UseTargets(); + self = oldself; + self.enemy = world; + + // if turning is enabled, the train will turn toward the next point while waiting + if(self.platmovetype_turn && !self.train_wait_turning) + { + entity targ, cp; + vector org; + targ = find(world, targetname, self.target); + if((self.spawnflags & 1) && targ.curvetarget) + cp = find(world, targetname, targ.curvetarget); + else + cp = world; + + if(cp) // bezier curves movement + org = cp.origin - (self.origin + self.mins); // use the origin of the control point of the next path_corner + else // linear movement + org = targ.origin - (self.origin + self.mins); // use the origin of the next path_corner + org_z = -org_z; + org = vectoangles(org); + + if(self.wait >= 0) // slow turning + { + SUB_CalcAngleMove(org, TSPEED_TIME, self.ltime - time + self.wait, train_wait); + self.train_wait_turning = TRUE; + return; + } + else // instant turning + self.angles = org; + } + if(self.noise != "") stopsoundto(MSG_BROADCAST, self, CH_TRIGGER_SINGLE); // send this as unreliable only, as the train will resume operation shortly anyway - if(self.wait < 0) + if(self.wait < 0 || self.train_wait_turning) // no waiting or we already waited while turning { + self.train_wait_turning = FALSE; train_next(); } else @@ -257,31 +339,58 @@ void train_wait() self.think = train_next; self.nextthink = self.ltime + self.wait; } - - entity oldself; - oldself = self; - self = self.enemy; - SUB_UseTargets(); - self = oldself; - self.enemy = world; } void train_next() { - entity targ; + entity targ, cp; + vector cp_org; + targ = find(world, targetname, self.target); - self.enemy = targ; self.target = targ.target; + if (self.spawnflags & 1) + { + if(targ.curvetarget) + { + cp = find(world, targetname, targ.curvetarget); // get its second target (the control point) + cp_org = cp.origin - self.mins; // no control point found, assume a straight line to the destination + } + else + cp = world; // no cp + } if (!self.target) objerror("train_next: no next target"); self.wait = targ.wait; if (!self.wait) self.wait = 0.1; + if(targ.platmovetype) + { + // this path_corner contains a movetype overrider, apply it + self.platmovetype_start = targ.platmovetype_start; + self.platmovetype_end = targ.platmovetype_end; + } + else + { + // this path_corner doesn't contain a movetype overrider, use the train's defaults + self.platmovetype_start = self.platmovetype_start_default; + self.platmovetype_end = self.platmovetype_end_default; + } + if (targ.speed) - SUB_CalcMove(targ.origin - self.mins, targ.speed, train_wait); + { + if (cp) + SUB_CalcMove_Bezier(cp_org, targ.origin - self.mins, TSPEED_LINEAR, targ.speed, train_wait); + else + SUB_CalcMove(targ.origin - self.mins, TSPEED_LINEAR, targ.speed, train_wait); + } else - SUB_CalcMove(targ.origin - self.mins, self.speed, train_wait); + { + if (cp) + SUB_CalcMove_Bezier(cp_org, targ.origin - self.mins, TSPEED_LINEAR, self.speed, train_wait); + else + SUB_CalcMove(targ.origin - self.mins, TSPEED_LINEAR, self.speed, train_wait); + } if(self.noise != "") sound(self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTN_IDLE); @@ -313,6 +422,8 @@ void spawnfunc_func_train() objerror("func_train without a target"); if (!self.speed) self.speed = 100; + if (self.spawnflags & 2) + self.platmovetype_turn = TRUE; if not(InitMovingBrushTrigger()) return; @@ -330,6 +441,11 @@ void spawnfunc_func_train() self.dmgtime = 0.25; self.dmgtime2 = time; + if(!set_platmovetype(self, self.platmovetype)) + return; + self.platmovetype_start_default = self.platmovetype_start; + self.platmovetype_end_default = self.platmovetype_end; + // TODO make a reset function for this one } @@ -592,7 +708,7 @@ void button_done() void button_return() { self.state = STATE_DOWN; - SUB_CalcMove (self.pos1, self.speed, button_done); + SUB_CalcMove (self.pos1, TSPEED_LINEAR, self.speed, button_done); self.frame = 0; // use normal textures if (self.health) self.takedamage = DAMAGE_YES; // can be shot again @@ -617,7 +733,7 @@ void button_fire() sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM); self.state = STATE_UP; - SUB_CalcMove (self.pos2, self.speed, button_wait); + SUB_CalcMove (self.pos2, TSPEED_LINEAR, self.speed, button_wait); } void button_reset() @@ -857,7 +973,7 @@ void door_go_down() } self.state = STATE_DOWN; - SUB_CalcMove (self.pos1, self.speed, door_hit_bottom); + SUB_CalcMove (self.pos1, TSPEED_LINEAR, self.speed, door_hit_bottom); } void door_go_up() @@ -874,7 +990,7 @@ void door_go_up() if (self.noise2 != "") sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); self.state = STATE_UP; - SUB_CalcMove (self.pos2, self.speed, door_hit_top); + SUB_CalcMove (self.pos2, TSPEED_LINEAR, self.speed, door_hit_top); string oldmessage; oldmessage = self.message; @@ -1159,7 +1275,7 @@ void door_rotating_go_down() } self.state = STATE_DOWN; - SUB_CalcAngleMove (self.pos1, self.speed, door_rotating_hit_bottom); + SUB_CalcAngleMove (self.pos1, TSPEED_LINEAR, self.speed, door_rotating_hit_bottom); } void door_rotating_go_up() @@ -1175,7 +1291,7 @@ void door_rotating_go_up() if (self.noise2 != "") sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); self.state = STATE_UP; - SUB_CalcAngleMove (self.pos2, self.speed, door_rotating_hit_top); + SUB_CalcAngleMove (self.pos2, TSPEED_LINEAR, self.speed, door_rotating_hit_top); string oldmessage; oldmessage = self.message; @@ -1639,7 +1755,7 @@ void fd_secret_use() self.dest1 = self.origin + v_right * (self.t_width * temp); self.dest2 = self.dest1 + v_forward * self.t_length; - SUB_CalcMove(self.dest1, self.speed, fd_secret_move1); + SUB_CalcMove(self.dest1, TSPEED_LINEAR, self.speed, fd_secret_move1); if (self.noise2 != "") sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); } @@ -1658,7 +1774,7 @@ void fd_secret_move2() { if (self.noise2 != "") sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); - SUB_CalcMove(self.dest2, self.speed, fd_secret_move3); + SUB_CalcMove(self.dest2, TSPEED_LINEAR, self.speed, fd_secret_move3); } // Wait here until time to go back... @@ -1678,7 +1794,7 @@ void fd_secret_move4() { if (self.noise2 != "") sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); - SUB_CalcMove(self.dest1, self.speed, fd_secret_move5); + SUB_CalcMove(self.dest1, TSPEED_LINEAR, self.speed, fd_secret_move5); } // Wait 1 second... @@ -1694,7 +1810,7 @@ void fd_secret_move6() { if (self.noise2 != "") sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM); - SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done); + SUB_CalcMove(self.oldorigin, TSPEED_LINEAR, self.speed, fd_secret_done); } void fd_secret_done() @@ -2065,7 +2181,7 @@ void conveyor_think() if(self.state) { - for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5); e; e = e.chain) + 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)) {