]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/t_plats.qc
Use the proper time offset for turning. The train still won't turn in the right direc...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / t_plats.qc
index ab121045b005392bdac38cfe20aacf5f953b5dd2..6ac02df66f04e0433885853cd845909aca1eb757 100644 (file)
@@ -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()
@@ -175,11 +185,6 @@ 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;
 
@@ -231,26 +236,49 @@ 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
+}
 
+.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 using bezier curves and turning is enabled, the train will turn toward the next point while waiting
+       if(!self.train_wait_turning)
+       if(self.spawnflags & 1 && self.bezier_turn && self.wait >= 0)
+       {
+               entity targ;
+               targ = find(world, targetname, self.target);
+               SUB_CalcAngleMove(targ.origin, TSPEED_TIME, self.ltime - time + self.wait, train_wait);
+               self.train_wait_turning = TRUE;
+               return;
+       }
+
        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
@@ -258,21 +286,24 @@ 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)
+       {
+               cp = find(world, target, targ.targetname); // get the previous corner first
+               cp = find(world, targetname, cp.curve); // now get its second target (the control point)
+               if(cp.targetname == "")
+                       cp_org = targ.origin - self.mins; // no control point found, assume a straight line to the destination
+               else
+                       cp_org = cp.origin - self.mins;
+       }
        if (!self.target)
                objerror("train_next: no next target");
        self.wait = targ.wait;
@@ -280,9 +311,19 @@ void train_next()
                self.wait = 0.1;
 
        if (targ.speed)
-               SUB_CalcMove(targ.origin - self.mins, targ.speed, train_wait);
+       {
+               if (self.spawnflags & 1)
+                       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 (self.spawnflags & 1)
+                       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);
@@ -314,6 +355,8 @@ void spawnfunc_func_train()
                objerror("func_train without a target");
        if (!self.speed)
                self.speed = 100;
+       if (self.spawnflags & 2)
+               self.bezier_turn = TRUE;
 
        if not(InitMovingBrushTrigger())
                return;
@@ -593,7 +636,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
@@ -618,7 +661,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()
@@ -858,7 +901,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()
@@ -875,7 +918,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;
@@ -1160,7 +1203,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()
@@ -1176,7 +1219,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;
@@ -1640,7 +1683,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);
 }
@@ -1659,7 +1702,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...
@@ -1679,7 +1722,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...
@@ -1695,7 +1738,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()
@@ -2058,54 +2101,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(!WarpZoneLib_BoxTouchesBrush(other.absmin + '0 0 -1', other.absmax + '0 0 -1', self, other))
-               {
-                       other.flags &~= FL_ONGROUND;
-                       continue;
-               }
-               tracebox(other.origin, other.mins, other.maxs, other.origin + self.movedir * (self.speed * sys_frametime), MOVE_NORMAL, other);
-               if(trace_fraction > 0)
+               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;
+                               }
+
+               for(e = world; (e = findentity(e, conveyor, self)); )
                {
-                       if(other.flags & FL_CLIENT) // doing it via velocity has quite some advantages
-                       {
-                               float f = 1 - frametime * autocvar_sv_friction;
-                               if(f > 0)
-                                       other.velocity += self.movedir * self.speed * (1 / f - 1);
-                       }
-                       else
-                               setorigin(other, trace_endpos);
+                       if(e.flags & FL_CLIENT) // 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;
@@ -2113,5 +2169,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();
 }