Ejemplo n.º 1
0
  /** R_SetupFrame */
  void R_SetupFrame() {
    r_framecount++;

    //	build the transformation matrix for the given view angles
    Math3D.VectorCopy(r_newrefdef.vieworg, r_origin);

    Math3D.AngleVectors(r_newrefdef.viewangles, vpn, vright, vup);

    //	current viewcluster
    mleaf_t leaf;
    if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) == 0) {
      r_oldviewcluster = r_viewcluster;
      r_oldviewcluster2 = r_viewcluster2;
      leaf = Mod_PointInLeaf(r_origin, r_worldmodel);
      r_viewcluster = r_viewcluster2 = leaf.cluster;

      // check above and below so crossing solid water doesn't draw wrong
      if (leaf.contents == 0) { // look down a bit
        Math3D.VectorCopy(r_origin, temp);
        temp[2] -= 16;
        leaf = Mod_PointInLeaf(temp, r_worldmodel);
        if ((leaf.contents & Defines.CONTENTS_SOLID) == 0 && (leaf.cluster != r_viewcluster2))
          r_viewcluster2 = leaf.cluster;
      } else { // look up a bit
        Math3D.VectorCopy(r_origin, temp);
        temp[2] += 16;
        leaf = Mod_PointInLeaf(temp, r_worldmodel);
        if ((leaf.contents & Defines.CONTENTS_SOLID) == 0 && (leaf.cluster != r_viewcluster2))
          r_viewcluster2 = leaf.cluster;
      }
    }

    for (int i = 0; i < 4; i++) v_blend[i] = r_newrefdef.blend[i];

    c_brush_polys = 0;
    c_alias_polys = 0;

    // clear out the portion of the screen that the NOWORLDMODEL defines
    if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0) {
      GL11.glEnable(GL11.GL_SCISSOR_TEST);
      GL11.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
      GL11.glScissor(
          r_newrefdef.x,
          vid.height - r_newrefdef.height - r_newrefdef.y,
          r_newrefdef.width,
          r_newrefdef.height);
      GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
      GL11.glClearColor(1.0f, 0.0f, 0.5f, 0.5f);
      GL11.glDisable(GL11.GL_SCISSOR_TEST);
    }
  }
Ejemplo n.º 2
0
  /** Objects need to be moved back on a failed push, otherwise riders would continue to slide. */
  public static boolean SV_Push(edict_t pusher, float[] move, float[] amove) {
    int i, e;
    edict_t check, block[];
    float[] mins = {0, 0, 0};
    float[] maxs = {0, 0, 0};
    pushed_t p;
    float[] org = {0, 0, 0};
    float[] org2 = {0, 0, 0};
    float[] move2 = {0, 0, 0};
    float[] forward = {0, 0, 0};
    float[] right = {0, 0, 0};
    float[] up = {0, 0, 0};

    // clamp the move to 1/8 units, so the position will
    // be accurate for client side prediction
    for (i = 0; i < 3; i++) {
      float temp;
      temp = move[i] * 8.0f;
      if (temp > 0.0) temp += 0.5;
      else temp -= 0.5;
      move[i] = 0.125f * (int) temp;
    }

    // find the bounding box
    for (i = 0; i < 3; i++) {
      mins[i] = pusher.absmin[i] + move[i];
      maxs[i] = pusher.absmax[i] + move[i];
    }

    //	   we need this for pushing things later
    Math3D.VectorSubtract(Globals.vec3_origin, amove, org);
    Math3D.AngleVectors(org, forward, right, up);

    //	   save the pusher's original position
    GameBase.pushed[GameBase.pushed_p].ent = pusher;
    Math3D.VectorCopy(pusher.s.origin, GameBase.pushed[GameBase.pushed_p].origin);
    Math3D.VectorCopy(pusher.s.angles, GameBase.pushed[GameBase.pushed_p].angles);

    if (pusher.client != null)
      GameBase.pushed[GameBase.pushed_p].deltayaw =
          pusher.client.ps.pmove.delta_angles[Defines.YAW];

    GameBase.pushed_p++;

    //	   move the pusher to it's final position
    Math3D.VectorAdd(pusher.s.origin, move, pusher.s.origin);
    Math3D.VectorAdd(pusher.s.angles, amove, pusher.s.angles);
    GameBase.gi.linkentity(pusher);

    //	   see if any solid entities are inside the final position

    // check= g_edicts + 1;
    for (e = 1; e < GameBase.num_edicts; e++) {
      check = GameBase.g_edicts[e];
      if (!check.inuse) continue;
      if (check.movetype == Defines.MOVETYPE_PUSH
          || check.movetype == Defines.MOVETYPE_STOP
          || check.movetype == Defines.MOVETYPE_NONE
          || check.movetype == Defines.MOVETYPE_NOCLIP) continue;

      if (check.area.prev == null) continue; // not linked in anywhere

      // if the entity is standing on the pusher, it will definitely be
      // moved
      if (check.groundentity != pusher) {
        // see if the ent needs to be tested
        if (check.absmin[0] >= maxs[0]
            || check.absmin[1] >= maxs[1]
            || check.absmin[2] >= maxs[2]
            || check.absmax[0] <= mins[0]
            || check.absmax[1] <= mins[1]
            || check.absmax[2] <= mins[2]) continue;

        // see if the ent's bbox is inside the pusher's final position
        if (SV_TestEntityPosition(check) == null) continue;
      }

      if ((pusher.movetype == Defines.MOVETYPE_PUSH) || (check.groundentity == pusher)) {
        // move this entity
        GameBase.pushed[GameBase.pushed_p].ent = check;
        Math3D.VectorCopy(check.s.origin, GameBase.pushed[GameBase.pushed_p].origin);
        Math3D.VectorCopy(check.s.angles, GameBase.pushed[GameBase.pushed_p].angles);
        GameBase.pushed_p++;

        // try moving the contacted entity
        Math3D.VectorAdd(check.s.origin, move, check.s.origin);
        if (check.client != null) { // FIXME: doesn't rotate monsters?
          check.client.ps.pmove.delta_angles[Defines.YAW] += amove[Defines.YAW];
        }

        // figure movement due to the pusher's amove
        Math3D.VectorSubtract(check.s.origin, pusher.s.origin, org);
        org2[0] = Math3D.DotProduct(org, forward);
        org2[1] = -Math3D.DotProduct(org, right);
        org2[2] = Math3D.DotProduct(org, up);
        Math3D.VectorSubtract(org2, org, move2);
        Math3D.VectorAdd(check.s.origin, move2, check.s.origin);

        // may have pushed them off an edge
        if (check.groundentity != pusher) check.groundentity = null;

        block = SV_TestEntityPosition(check);
        if (block == null) { // pushed ok
          GameBase.gi.linkentity(check);
          // impact?
          continue;
        }

        // if it is ok to leave in the old position, do it
        // this is only relevent for riding entities, not pushed
        // FIXME: this doesn't acount for rotation
        Math3D.VectorSubtract(check.s.origin, move, check.s.origin);
        block = SV_TestEntityPosition(check);

        if (block == null) {
          GameBase.pushed_p--;
          continue;
        }
      }

      // save off the obstacle so we can call the block function
      GameBase.obstacle = check;

      // move back any entities we already moved
      // go backwards, so if the same entity was pushed
      // twice, it goes back to the original position
      for (int ip = GameBase.pushed_p - 1; ip >= 0; ip--) {
        p = GameBase.pushed[ip];
        Math3D.VectorCopy(p.origin, p.ent.s.origin);
        Math3D.VectorCopy(p.angles, p.ent.s.angles);
        if (p.ent.client != null) {
          p.ent.client.ps.pmove.delta_angles[Defines.YAW] = (short) p.deltayaw;
        }
        GameBase.gi.linkentity(p.ent);
      }
      return false;
    }

    //	  FIXME: is there a better way to handle this?
    // see if anything we moved has touched a trigger
    for (int ip = GameBase.pushed_p - 1; ip >= 0; ip--)
      GameBase.G_TouchTriggers(GameBase.pushed[ip].ent);

    return true;
  }