So I've tried now the following:

1) (During runtime) created a block-shaped model-entity in front of the player (taking into account his angles of course)
2) Traced downwards from the block position using "USE_BOX" with the "me" flag set to the block
3) moving the player using the "target"-vector minus the current player position as the absolute movement distance

Well, works. ALLMOST. I use a straight rail for testing purposes and at one certain point the player just stops, in other words: gets stuck somehow. Ive been looking at my code for hours now and I just can't figure out why the hell he gets stuck halfway on the rail for no visible reason whatsoever.

Here's my current code, it is being called once per frame:

Code:
ENTITY* grindblock;
ENTITY* current_rail;
VECTOR* grindtrace = {x=0; y=0; z=0;}
VECTOR* grindheight = {x=0; y=0; z=0;}
VECTOR* grindtest = {x=0; y=0; z=0;}  

[...]


void movement_state_grind()
{
   
   if(grindblock == NULL)    // has the block already been created? If not, create it
   {
      grindblock = ent_create("grindblock.mdl", nullvector, NULL);
      set(grindblock, TRANSLUCENT);
      set(grindblock, PASSABLE);
      grindblock.alpha = 0;
   }
   vec_set(grindblock.x, nullvector);
   grindblock.x = 1;
   vec_rotate(grindblock.x, player.pan);   // take into account the player's angles
   vec_normalize(grindblock.x, 3);         // place it 3 quants in front of him (speed = 3 quants per frame for testing)
   vec_add(grindblock.x, player.x);        // the final position of the block
   vec_set(grindblock.pan, player.pan);    // to make sure the block and the player are facing into the same direction
   vec_set(grindtrace, nullvector);
   grindtrace.z = -1;                      // trace downwards
   vec_rotate(grindtrace, grindblock.pan); // "downwards" is relative - rotate it and align the angle to the player angle
   vec_normalize(grindtrace, 100);         // trace 100 quants downwards (should always be enough to hit the rail)
   vec_add(grindtrace, grindblock.x);      // final position of the trace target
   me = grindblock;
   you = player;
   c_trace(grindblock.x, grindtrace, IGNORE_ME|IGNORE_YOU|IGNORE_PASSABLE|USE_BOX);  // ignore the grindblock itself and the player
   vec_set(grindtest, target);
   if(you == current_rail)
   {
      if is(your, FLAG3)
      {
         vec_set(grindheight, nullvector);
         grindheight.z = -1;
         vec_rotate(grindheight, player.pan); 
         vec_normalize(grindheight, -47);       // go up 47 quants from the target vector to get the new position of the player model
         vec_set(move_reldist, nullvector);     // no relative movement
         vec_diff(move_absdist, target, player.x); // absolute movement is the difference between current and new absolute position
         vec_to_angle(player.pan, move_absdist);   // force the player to look into that direction
         vec_add(move_absdist, grindheight);       // add in the 47 quants for player hight
      }
   }
   else
   {
      player_movement = falling;        // if the rail was NOT hit, the end of the rail has been reached (most likely ^^')
   }
   
}




The c_move itself is done in the player-action main loop, but it's very simple:

Code:
c_move(player, move_reldist, move_absdist, IGNORE_PASSABLE|GLIDE);



... with move_reldist being equal to the nullvector while grinding. There's really nothing (much) else going on, I even tried to completely switch off gravity during grinding, didn't change anything about the result so there HAS to be some problem with my code above... The code is very well documented and easy to understand, I hope, however, I can't find the mistake...