c_move(ENTITY* entity,VECTOR* reldist,VECTOR* absdist,var mode)

Moves an entity over a certain distance while performing collision detection, triggering collision events, and gliding along obstacles.

The first vector reldist gives a relative distance and direction in rotated entity coordinates, i.e. the direction that the entity is facing. The second vector absdist gives an absolute distance and direction in world coordinates. The resulting movement is a combination of both distances. Normally the first vector is used for the propelling speed of the entity, and the second one for external forces, like gravity and drift. To zero one of these vectors, the predefined nullvector can be given.

The function returns the amount of distance covered. If the entity could not move at all due to being blocked by obstacles, it returns a negative value or 0. If collision events are enabled, they are triggered for the entity as well as for the obstacle. During a collision event, several predefined variables are set to indicate the type of collision (see below). They can be evaluated in the event function for setting collision or ricocheting behavior of any kind.

Parameters:

entity Entity to be moved.
reldist Move distance vector in entity coordinates
absdist Move distance vector in world coordinates
mode Collision mode, see below.

The following mode flags can be combined:

IGNORE_YOU Ignores the you entity on collision detection (see remark).
IGNORE_FLAG2  A7.05  Ignores all entities with FLAG2 set.
IGNORE_PASSABLE Ignores all passable blocks and entities, including all water entities.
IGNORE_PASSENTS Ignores passable model and sprite entities, but still detects water entities (rectangular passable maps, or passable terrain). It sets the predefined flags in_passable and on_passable . The predefined passable_ent pointer is set to the detected water entity. This can be used, for example, to switch the player behavior to swimming.
IGNORE_WORLD Ignores all level blocks and terrains.
IGNORE_MAPS Ignores all map entities.
IGNORE_MODELS Ignores all models.
IGNORE_SPRITES Ignores all sprites.
IGNORE_PUSH Ignores all entities with lower push values than the given entity, and triggers the EVENT_PUSH collision event on those entities.
IGNORE_CONTENT Ignores the content of the move origin. The function is faster, but water entities (see above) are not detected.
ACTIVATE_TRIGGER Enables EVENT_TRIGGER during the motion. Can be slow.
ACTIVATE_PUSH  A7.05  Triggers the EVENT_PUSH collision event on the hit entity, regardless of the push value. If the event function returns 1, the hit entity is considered an obstacle; if the event function returns 0, it is ignored. This way individual collision groups can be defined.
ACTIVATE_SHOOT  A7.07  Enables EVENT_SHOOT triggering of the hit entity, and prevents all other collision events. This flag lets c_move behave similar to c_trace.
ACTIVATE_SONAR  A7.07  Enables EVENT_SONAR triggering of the hit entity, and prevents all other collision events. This flag lets c_move behave similar to c_trace.
USE_AABB Uses an axis aligned bounding box (AABB) for collision, rather than an oriented bounding box (OBB). The AABB system is faster, but ignores the entity orientation on USE_BOX, treats models and sprites as boxes, and requires a BSP level. See collision for the difference between both systems.
GLIDE Glides along walls and entities on impact.

Depends on:

move_friction Friction factor for gliding along walls.
move_min_z Maximum step height (OBB only).
disable_z_glide Disables gliding up slopes (OBB only).

Returns:

> 0 Distance covered.
<= 0 Entity was blocked.

Modified:

target Position of the collision contact.
normal Normal vector of the colliding surface.
bounce Bounce off direction vector.
trace_hit Set to nonzero when something was hit.
in_passable
Set to nonzero when the starting or ending point is inside a water entity.
on_passable Set to nonzero when the hit target is a water entity.
passable_ent When in_passable or on_passable is set, this pointer is set to the detected water terrain (OBB system only).
event_type Type of event when one was triggered.

Remarks:

Speed:

Slow

Example (lite-C):

// simple function for walking over ground
// control the player with the WASD keys
// player origin must be at the model center
// bounding box must be smaller than the player!
action player_walk()
{ 
// if necessary, adjust the bounding box to give the entity 'floor room' (see remarks) 
// my.min_z *= 0.5;

   var speed_down = 0;   // downward speed by gravity
   var anim_percent = 0; // animation percentage
   VECTOR vFeet;
   vec_for_min(vFeet,me); // vFeet.z = distance from player origin to lowest vertex

   while (1)
   {
// rotate the player using the [A] and [D] keys      
      my.pan += 5*(key_a-key_d)*time_step; 

// determine the ground distance by a downwards trace
      var dist_down; 
      if (c_trace(my.x,vector(my.x,my.y,my.z-5000),IGNORE_ME | IGNORE_PASSABLE | USE_BOX) > 0)
         dist_down = my.z + vFeet.z - target.z; // get distance between player's feet and the ground
      else
         dist_down = 0;

// apply gravity when the player is in the air
      if (dist_down > 0)  // above floor, fall down with increasing speed
         dist_down = clamp(dist_down,0,accelerate(speed_down,5,0.1));
      else                // on or below floor, set downward speed to zero
         speed_down = 0;

// move the player using the [W] and [S] keys      
      var dist_ahead = 5*(key_w-key_s)*time_step;
      dist_ahead = sign(dist_ahead)*(abs(dist_ahead) + 0.5*dist_down); // adapt the speed on slopes
      c_move(me,vector(dist_ahead,0,0),vector(0,0,-dist_down),IGNORE_PASSABLE | GLIDE); // move the player

// animate the player according to its moved distance
      if (dist_ahead != 0) // player is moving ahead
      {
         anim_percent += 1.3*dist_ahead; // 1.3 = walk cycle percentage per quant
         ent_animate(me,"walk",anim_percent,ANM_CYCLE); // play the "walk" animation
      }
      else // player stands still
      { 
         anim_percent += 5*time_step; 
         ent_animate(me,"stand",anim_percent,ANM_CYCLE); // play the "stand" animation
      }
      wait(1);
   }
}

See also:

c_rotate, c_trace, move_min_z, move_friction, collisions

► latest version online