Beispiel #1
0
  public static int SV_FlyMove(edict_t ent, float time, int mask) {
    edict_t hit;
    int bumpcount, numbumps;
    float[] dir = {0.0f, 0.0f, 0.0f};
    float d;
    int numplanes;
    float[][] planes = new float[MAX_CLIP_PLANES][3];
    float[] primal_velocity = {0.0f, 0.0f, 0.0f};
    float[] original_velocity = {0.0f, 0.0f, 0.0f};
    float[] new_velocity = {0.0f, 0.0f, 0.0f};
    int i, j;
    trace_t trace;
    float[] end = {0.0f, 0.0f, 0.0f};
    float time_left;
    int blocked;

    numbumps = 4;

    blocked = 0;
    Math3D.VectorCopy(ent.velocity, original_velocity);
    Math3D.VectorCopy(ent.velocity, primal_velocity);
    numplanes = 0;

    time_left = time;

    ent.groundentity = null;
    for (bumpcount = 0; bumpcount < numbumps; bumpcount++) {
      for (i = 0; i < 3; i++) end[i] = ent.s.origin[i] + time_left * ent.velocity[i];

      trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, end, ent, mask);

      if (trace.allsolid) { // entity is trapped in another solid
        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
        return 3;
      }

      if (trace.fraction > 0) { // actually covered some distance
        Math3D.VectorCopy(trace.endpos, ent.s.origin);
        Math3D.VectorCopy(ent.velocity, original_velocity);
        numplanes = 0;
      }

      if (trace.fraction == 1) break; // moved the entire distance

      hit = trace.ent;

      if (trace.plane.normal[2] > 0.7) {
        blocked |= 1; // floor
        if (hit.solid == Defines.SOLID_BSP) {
          ent.groundentity = hit;
          ent.groundentity_linkcount = hit.linkcount;
        }
      }
      if (trace.plane.normal[2] == 0.0f) {
        blocked |= 2; // step
      }

      //
      //	   run the impact function
      //
      SV_Impact(ent, trace);
      if (!ent.inuse) break; // removed by the impact function

      time_left -= time_left * trace.fraction;

      // cliped to another plane
      if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't
        // really happen
        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
        return 3;
      }

      Math3D.VectorCopy(trace.plane.normal, planes[numplanes]);
      numplanes++;

      //
      //	   modify original_velocity so it parallels all of the clip planes
      //
      for (i = 0; i < numplanes; i++) {
        GameBase.ClipVelocity(original_velocity, planes[i], new_velocity, 1);

        for (j = 0; j < numplanes; j++)
          if ((j != i) && !Math3D.VectorEquals(planes[i], planes[j])) {
            if (Math3D.DotProduct(new_velocity, planes[j]) < 0) break; // not ok
          }
        if (j == numplanes) break;
      }

      if (i != numplanes) { // go along this plane
        Math3D.VectorCopy(new_velocity, ent.velocity);
      } else { // go along the crease
        if (numplanes != 2) {
          //					gi.dprintf ("clip velocity, numplanes ==
          // %i\n",numplanes);
          Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
          return 7;
        }
        Math3D.CrossProduct(planes[0], planes[1], dir);
        d = Math3D.DotProduct(dir, ent.velocity);
        Math3D.VectorScale(dir, d, ent.velocity);
      }

      //
      //	   if original velocity is against the original velocity, stop dead
      //	   to avoid tiny occilations in sloping corners
      //
      if (Math3D.DotProduct(ent.velocity, primal_velocity) <= 0) {
        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);
        return blocked;
      }
    }

    return blocked;
  }