Merge remote-tracking branch 'origin/mirceakitsune/func_train_beizer_curve'
authorRudolf Polzer <divverent@xonotic.org>
Fri, 11 Oct 2013 14:51:19 +0000 (16:51 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Fri, 11 Oct 2013 14:51:19 +0000 (16:51 +0200)
Conflicts:
qcsrc/server/t_plats.qc

1  2 
qcsrc/common/util.qc
qcsrc/server/defs.qh
qcsrc/server/g_subs.qc
qcsrc/server/t_plats.qc

@@@ -2492,241 -2415,26 +2492,263 @@@ float cubic_speedfunc_is_sane(float sta
        // (3, [0..3])
        // (3.5, [0.2..2.3])
        // (4, 1)
+       /*
+          On another note:
+          inflection point is always at (2s + e - 3) / (3s + 3e - 6).
+          s + e - 2 == 0: no inflection
+          s + e > 2:
+          0 < inflection < 1 if:
+          0 < 2s + e - 3 < 3s + 3e - 6
+          2s + e > 3 and 2e + s > 3
+          s + e < 2:
+          0 < inflection < 1 if:
+          0 > 2s + e - 3 > 3s + 3e - 6
+          2s + e < 3 and 2e + s < 3
+          Therefore: there is an inflection point iff:
+          e outside (3 - s)/2 .. 3 - s*2
+          
+          in other words, if (s,e) in triangle (1,1)(0,3)(0,1.5) or in triangle (1,1)(3,0)(1.5,0)
+       */
  }
 +
 +.float FindConnectedComponent_processing;
 +void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass)
 +{
 +      entity queue_start, queue_end;
 +
 +      // we build a queue of to-be-processed entities.
 +      // queue_start is the next entity to be checked for neighbors
 +      // queue_end is the last entity added
 +
 +      if(e.FindConnectedComponent_processing)
 +              error("recursion or broken cleanup");
 +
 +      // start with a 1-element queue
 +      queue_start = queue_end = e;
 +      queue_end.fld = world;
 +      queue_end.FindConnectedComponent_processing = 1;
 +
 +      // for each queued item:
 +      for(; queue_start; queue_start = queue_start.fld)
 +      {
 +              // find all neighbors of queue_start
 +              entity t;
 +              for(t = world; (t = nxt(t, queue_start, pass)); )
 +              {
 +                      if(t.FindConnectedComponent_processing)
 +                              continue;
 +                      if(iscon(t, queue_start, pass))
 +                      {
 +                              // it is connected? ADD IT. It will look for neighbors soon too.
 +                              queue_end.fld = t;
 +                              queue_end = t;
 +                              queue_end.fld = world;
 +                              queue_end.FindConnectedComponent_processing = 1;
 +                      }
 +              }
 +      }
 +
 +      // unmark
 +      for(queue_start = e; queue_start; queue_start = queue_start.fld)
 +              queue_start.FindConnectedComponent_processing = 0;
 +}
 +
 +// todo: this sucks, lets find a better way to do backtraces?
 +#ifndef MENUQC
 +void backtrace(string msg)
 +{
 +      float dev, war;
 +      #ifdef SVQC
 +      dev = autocvar_developer;
 +      war = autocvar_prvm_backtraceforwarnings;
 +      #else
 +      dev = cvar("developer");
 +      war = cvar("prvm_backtraceforwarnings");
 +      #endif
 +      cvar_set("developer", "1");
 +      cvar_set("prvm_backtraceforwarnings", "1");
 +      print("\n");
 +      print("--- CUT HERE ---\nWARNING: ");
 +      print(msg);
 +      print("\n");
 +      remove(world); // isn't there any better way to cause a backtrace?
 +      print("\n--- CUT UNTIL HERE ---\n");
 +      cvar_set("developer", ftos(dev));
 +      cvar_set("prvm_backtraceforwarnings", ftos(war));
 +}
 +#endif
 +
 +// color code replace, place inside of sprintf and parse the string
 +string CCR(string input)
 +{
 +      // See the autocvar declarations in util.qh for default values
 +      
 +      // foreground/normal colors
 +      input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input); 
 +      input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input); 
 +      input = strreplace("^F3", strcat("^", autocvar_hud_colorset_foreground_3), input); 
 +      input = strreplace("^F4", strcat("^", autocvar_hud_colorset_foreground_4), input); 
 +
 +      // "kill" colors
 +      input = strreplace("^K1", strcat("^", autocvar_hud_colorset_kill_1), input);
 +      input = strreplace("^K2", strcat("^", autocvar_hud_colorset_kill_2), input);
 +      input = strreplace("^K3", strcat("^", autocvar_hud_colorset_kill_3), input);
 +
 +      // background colors
 +      input = strreplace("^BG", strcat("^", autocvar_hud_colorset_background), input);
 +      input = strreplace("^N", "^7", input); // "none"-- reset to white...
 +      return input;
 +}
 +
 +vector vec3(float x, float y, float z)
 +{
 +      vector v;
 +      v_x = x;
 +      v_y = y;
 +      v_z = z;
 +      return v;
 +}
 +
 +#ifndef MENUQC
 +vector animfixfps(entity e, vector a, vector b)
 +{
 +      // multi-frame anim: keep as-is
 +      if(a_y == 1)
 +      {
 +              float dur;
 +              dur = frameduration(e.modelindex, a_x);
 +              if(dur <= 0 && b_y)
 +              {
 +                      a = b;
 +                      dur = frameduration(e.modelindex, a_x);
 +              }
 +              if(dur > 0)
 +                      a_z = 1.0 / dur;
 +      }
 +      return a;
 +}
 +#endif
 +
 +#ifdef SVQC
 +void dedicated_print(string input) // print(), but only print if the server is not local
 +{
 +      if(server_is_dedicated) { print(input); }
 +}
 +#endif
 +
 +#ifndef MENUQC
 +float Announcer_PickNumber(float type, float num)
 +{
 +      switch(type)
 +      {
 +              case CNT_GAMESTART:
 +              {
 +                      switch(num)
 +                      {
 +                              case 10: return ANNCE_NUM_GAMESTART_10;
 +                              case 9:  return ANNCE_NUM_GAMESTART_9; 
 +                              case 8:  return ANNCE_NUM_GAMESTART_8; 
 +                              case 7:  return ANNCE_NUM_GAMESTART_7; 
 +                              case 6:  return ANNCE_NUM_GAMESTART_6; 
 +                              case 5:  return ANNCE_NUM_GAMESTART_5; 
 +                              case 4:  return ANNCE_NUM_GAMESTART_4; 
 +                              case 3:  return ANNCE_NUM_GAMESTART_3; 
 +                              case 2:  return ANNCE_NUM_GAMESTART_2; 
 +                              case 1:  return ANNCE_NUM_GAMESTART_1; 
 +                      }
 +                      break;
 +              }
 +              case CNT_IDLE:
 +              {
 +                      switch(num)
 +                      {
 +                              case 10: return ANNCE_NUM_IDLE_10;
 +                              case 9:  return ANNCE_NUM_IDLE_9; 
 +                              case 8:  return ANNCE_NUM_IDLE_8; 
 +                              case 7:  return ANNCE_NUM_IDLE_7; 
 +                              case 6:  return ANNCE_NUM_IDLE_6; 
 +                              case 5:  return ANNCE_NUM_IDLE_5; 
 +                              case 4:  return ANNCE_NUM_IDLE_4; 
 +                              case 3:  return ANNCE_NUM_IDLE_3; 
 +                              case 2:  return ANNCE_NUM_IDLE_2; 
 +                              case 1:  return ANNCE_NUM_IDLE_1; 
 +                      }
 +                      break;
 +              }
 +              case CNT_KILL:
 +              {
 +                      switch(num)
 +                      {
 +                              case 10: return ANNCE_NUM_KILL_10;
 +                              case 9:  return ANNCE_NUM_KILL_9; 
 +                              case 8:  return ANNCE_NUM_KILL_8; 
 +                              case 7:  return ANNCE_NUM_KILL_7; 
 +                              case 6:  return ANNCE_NUM_KILL_6; 
 +                              case 5:  return ANNCE_NUM_KILL_5; 
 +                              case 4:  return ANNCE_NUM_KILL_4; 
 +                              case 3:  return ANNCE_NUM_KILL_3; 
 +                              case 2:  return ANNCE_NUM_KILL_2; 
 +                              case 1:  return ANNCE_NUM_KILL_1; 
 +                      }
 +                      break;
 +              }
 +              case CNT_RESPAWN:
 +              {
 +                      switch(num)
 +                      {
 +                              case 10: return ANNCE_NUM_RESPAWN_10;
 +                              case 9:  return ANNCE_NUM_RESPAWN_9; 
 +                              case 8:  return ANNCE_NUM_RESPAWN_8; 
 +                              case 7:  return ANNCE_NUM_RESPAWN_7; 
 +                              case 6:  return ANNCE_NUM_RESPAWN_6; 
 +                              case 5:  return ANNCE_NUM_RESPAWN_5; 
 +                              case 4:  return ANNCE_NUM_RESPAWN_4; 
 +                              case 3:  return ANNCE_NUM_RESPAWN_3; 
 +                              case 2:  return ANNCE_NUM_RESPAWN_2; 
 +                              case 1:  return ANNCE_NUM_RESPAWN_1; 
 +                      }
 +                      break;
 +              }
 +              case CNT_ROUNDSTART:
 +              {
 +                      switch(num)
 +                      {
 +                              case 10: return ANNCE_NUM_ROUNDSTART_10;
 +                              case 9:  return ANNCE_NUM_ROUNDSTART_9; 
 +                              case 8:  return ANNCE_NUM_ROUNDSTART_8; 
 +                              case 7:  return ANNCE_NUM_ROUNDSTART_7; 
 +                              case 6:  return ANNCE_NUM_ROUNDSTART_6; 
 +                              case 5:  return ANNCE_NUM_ROUNDSTART_5; 
 +                              case 4:  return ANNCE_NUM_ROUNDSTART_4; 
 +                              case 3:  return ANNCE_NUM_ROUNDSTART_3; 
 +                              case 2:  return ANNCE_NUM_ROUNDSTART_2; 
 +                              case 1:  return ANNCE_NUM_ROUNDSTART_1; 
 +                      }
 +                      break;
 +              }
 +              default:
 +              {
 +                      switch(num)
 +                      {
 +                              case 10: return ANNCE_NUM_10;
 +                              case 9:  return ANNCE_NUM_9; 
 +                              case 8:  return ANNCE_NUM_8; 
 +                              case 7:  return ANNCE_NUM_7; 
 +                              case 6:  return ANNCE_NUM_6; 
 +                              case 5:  return ANNCE_NUM_5; 
 +                              case 4:  return ANNCE_NUM_4; 
 +                              case 3:  return ANNCE_NUM_3; 
 +                              case 2:  return ANNCE_NUM_2; 
 +                              case 1:  return ANNCE_NUM_1; 
 +                      }
 +                      break;
 +              }
 +      }
 +      return NOTIF_ABORT; // abort sending if none of these numbers were right
 +}
 +#endif
Simple merge
@@@ -1,6 -1,7 +1,5 @@@
 -void SUB_Null() {}
 -float SUB_True() { return 1; }
 -float SUB_False() { return 0; }
 +void SUB_NullThink(void) { }
  
- void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
  void()  SUB_CalcMoveDone;
  void() SUB_CalcAngleMoveDone;
  //void() SUB_UseTargets;
@@@ -81,16 -86,16 +81,16 @@@ void plat_hit_bottom(
  
  void plat_go_down()
  {
 -      sound (self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTN_NORM);
 +      sound (self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTEN_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);
 +      sound (self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTEN_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()
@@@ -273,23 -341,57 +336,57 @@@ void train_wait(
  
  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.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.view_ofs; // 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.view_ofs, TSPEED_LINEAR, targ.speed, train_wait);
+               else
+                       SUB_CalcMove(targ.origin - self.view_ofs, 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.view_ofs, TSPEED_LINEAR, self.speed, train_wait);
+               else
+                       SUB_CalcMove(targ.origin - self.view_ofs, TSPEED_LINEAR, self.speed, train_wait);
+       }
  
        if(self.noise != "")
 -              sound(self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTN_IDLE);
 +              sound(self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTEN_IDLE);
  }
  
  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);
+       setorigin(self, targ.origin - self.view_ofs);
        self.nextthink = self.ltime + 1;
        self.think = train_next;
  }
@@@ -619,10 -734,10 +729,10 @@@ void button_fire(
                return;
  
        if (self.noise != "")
 -              sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM);
 +              sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_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()
@@@ -861,9 -992,9 +971,9 @@@ void door_go_up(
        }
  
        if (self.noise2 != "")
 -              sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM);
 +              sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_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;
@@@ -1162,9 -1293,9 +1272,9 @@@ void door_rotating_go_up(
                return;
        }
        if (self.noise2 != "")
 -              sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM);
 +              sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_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,14 -1759,9 +1749,14 @@@ 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);
 +              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
 +}
 +
 +void fd_secret_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      fd_secret_use();
  }
  
  // Wait after first movement...
@@@ -1662,8 -1777,8 +1772,8 @@@ void fd_secret_move1(
  void fd_secret_move2()
  {
        if (self.noise2 != "")
 -              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM);
 +              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_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...
@@@ -1682,8 -1797,8 +1792,8 @@@ void fd_secret_move3(
  void fd_secret_move4()
  {
        if (self.noise2 != "")
 -              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM);
 +              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
-       SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
+       SUB_CalcMove(self.dest1, TSPEED_LINEAR, self.speed, fd_secret_move5);
  }
  
  // Wait 1 second...
@@@ -1698,8 -1813,8 +1808,8 @@@ void fd_secret_move5(
  void fd_secret_move6()
  {
        if (self.noise2 != "")
 -              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTN_NORM);
 +              sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_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()