Пример #1
0
  public static void fire_grenade2(
      edict_t self,
      float[] start,
      float[] aimdir,
      int damage,
      int speed,
      float timer,
      float damage_radius,
      boolean held) {
    edict_t grenade;
    float[] dir = {0, 0, 0};
    float[] forward = {0, 0, 0}, right = {0, 0, 0}, up = {0, 0, 0};

    Math3D.vectoangles(aimdir, dir);
    Math3D.AngleVectors(dir, forward, right, up);

    grenade = GameUtil.G_Spawn();
    Math3D.VectorCopy(start, grenade.s.origin);
    Math3D.VectorScale(aimdir, speed, grenade.velocity);
    Math3D.VectorMA(grenade.velocity, 200f + Lib.crandom() * 10.0f, up, grenade.velocity);
    Math3D.VectorMA(grenade.velocity, Lib.crandom() * 10.0f, right, grenade.velocity);
    Math3D.VectorSet(grenade.avelocity, 300f, 300f, 300f);
    grenade.movetype = Defines.MOVETYPE_BOUNCE;
    grenade.clipmask = Defines.MASK_SHOT;
    grenade.solid = Defines.SOLID_BBOX;
    grenade.s.effects |= Defines.EF_GRENADE;
    Math3D.VectorClear(grenade.mins);
    Math3D.VectorClear(grenade.maxs);
    grenade.s.modelindex = GameBase.gi.modelindex("models/objects/grenade2/tris.md2");
    grenade.owner = self;
    grenade.touch = Grenade_Touch;
    grenade.nextthink = GameBase.level.time + timer;
    grenade.think = Grenade_Explode;
    grenade.dmg = damage;
    grenade.dmg_radius = damage_radius;
    grenade.classname = "hgrenade";
    if (held) grenade.spawnflags = 3;
    else grenade.spawnflags = 1;
    grenade.s.sound = GameBase.gi.soundindex("weapons/hgrenc1b.wav");

    if (timer <= 0.0) Grenade_Explode.think(grenade);
    else {
      GameBase.gi.sound(
          self,
          Defines.CHAN_WEAPON,
          GameBase.gi.soundindex("weapons/hgrent1a.wav"),
          1,
          Defines.ATTN_NORM,
          0);
      GameBase.gi.linkentity(grenade);
    }
  }
Пример #2
0
        public void touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf) {
          float[] origin = {0, 0, 0};
          int n;

          if (other == ent.owner) return;

          if (surf != null && (surf.flags & Defines.SURF_SKY) != 0) {
            GameUtil.G_FreeEdict(ent);
            return;
          }

          if (ent.owner.client != null)
            PlayerWeapon.PlayerNoise(ent.owner, ent.s.origin, Defines.PNOISE_IMPACT);

          // calculate position for the explosion entity
          Math3D.VectorMA(ent.s.origin, -0.02f, ent.velocity, origin);

          if (other.takedamage != 0) {
            GameCombat.T_Damage(
                other,
                ent,
                ent.owner,
                ent.velocity,
                ent.s.origin,
                plane.normal,
                ent.dmg,
                0,
                0,
                Defines.MOD_ROCKET);
          } else {
            // don't throw any debris in net games
            if (GameBase.deathmatch.value == 0 && 0 == GameBase.coop.value) {
              if ((surf != null)
                  && 0
                      == (surf.flags
                          & (Defines.SURF_WARP
                              | Defines.SURF_TRANS33
                              | Defines.SURF_TRANS66
                              | Defines.SURF_FLOWING))) {
                n = Lib.rand() % 5;
                while (n-- > 0)
                  GameMisc.ThrowDebris(ent, "models/objects/debris2/tris.md2", 2, ent.s.origin);
              }
            }
          }

          GameCombat.T_RadiusDamage(
              ent, ent.owner, ent.radius_dmg, other, ent.dmg_radius, Defines.MOD_R_SPLASH);

          GameBase.gi.WriteByte(Defines.svc_temp_entity);
          if (ent.waterlevel != 0) GameBase.gi.WriteByte(Defines.TE_ROCKET_EXPLOSION_WATER);
          else GameBase.gi.WriteByte(Defines.TE_ROCKET_EXPLOSION);
          GameBase.gi.WritePosition(origin);
          GameBase.gi.multicast(ent.s.origin, Defines.MULTICAST_PHS);

          GameUtil.G_FreeEdict(ent);
        }
Пример #3
0
  public static void fire_grenade(
      edict_t self,
      float[] start,
      float[] aimdir,
      int damage,
      int speed,
      float timer,
      float damage_radius) {
    edict_t grenade;
    float[] dir = {0, 0, 0};
    float[] forward = {0, 0, 0}, right = {0, 0, 0}, up = {0, 0, 0};

    Math3D.vectoangles(aimdir, dir);
    Math3D.AngleVectors(dir, forward, right, up);

    grenade = GameUtil.G_Spawn();
    Math3D.VectorCopy(start, grenade.s.origin);
    Math3D.VectorScale(aimdir, speed, grenade.velocity);
    Math3D.VectorMA(grenade.velocity, 200f + Lib.crandom() * 10.0f, up, grenade.velocity);
    Math3D.VectorMA(grenade.velocity, Lib.crandom() * 10.0f, right, grenade.velocity);
    Math3D.VectorSet(grenade.avelocity, 300, 300, 300);
    grenade.movetype = Defines.MOVETYPE_BOUNCE;
    grenade.clipmask = Defines.MASK_SHOT;
    grenade.solid = Defines.SOLID_BBOX;
    grenade.s.effects |= Defines.EF_GRENADE;
    Math3D.VectorClear(grenade.mins);
    Math3D.VectorClear(grenade.maxs);
    grenade.s.modelindex = GameBase.gi.modelindex("models/objects/grenade/tris.md2");
    grenade.owner = self;
    grenade.touch = Grenade_Touch;
    grenade.nextthink = GameBase.level.time + timer;
    grenade.think = Grenade_Explode;
    grenade.dmg = damage;
    grenade.dmg_radius = damage_radius;
    grenade.classname = "grenade";

    GameBase.gi.linkentity(grenade);
  }
Пример #4
0
        public void touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf) {
          if (other == ent.owner) return;

          if (surf != null && 0 != (surf.flags & Defines.SURF_SKY)) {
            GameUtil.G_FreeEdict(ent);
            return;
          }

          if (other.takedamage == 0) {
            if ((ent.spawnflags & 1) != 0) {
              if (Lib.random() > 0.5f)
                GameBase.gi.sound(
                    ent,
                    Defines.CHAN_VOICE,
                    GameBase.gi.soundindex("weapons/hgrenb1a.wav"),
                    1,
                    Defines.ATTN_NORM,
                    0);
              else
                GameBase.gi.sound(
                    ent,
                    Defines.CHAN_VOICE,
                    GameBase.gi.soundindex("weapons/hgrenb2a.wav"),
                    1,
                    Defines.ATTN_NORM,
                    0);
            } else {
              GameBase.gi.sound(
                  ent,
                  Defines.CHAN_VOICE,
                  GameBase.gi.soundindex("weapons/grenlb1b.wav"),
                  1,
                  Defines.ATTN_NORM,
                  0);
            }
            return;
          }

          ent.enemy = other;
          Grenade_Explode.think(ent);
        }
Пример #5
0
  /*
   * =================
   * check_dodge
   *
   * This is a support routine used when a client is firing a non-instant
   * attack weapon. It checks to see if a monster's dodge function should be
   * called.
   * =================
   */
  static void check_dodge(edict_t self, float[] start, float[] dir, int speed) {
    float[] end = {0, 0, 0};
    float[] v = {0, 0, 0};
    trace_t tr;
    float eta;

    // easy mode only ducks one quarter the time
    if (GameBase.skill.value == 0) {
      if (Lib.random() > 0.25) return;
    }
    Math3D.VectorMA(start, 8192, dir, end);
    tr = GameBase.gi.trace(start, null, null, end, self, Defines.MASK_SHOT);
    if ((tr.ent != null)
        && (tr.ent.svflags & Defines.SVF_MONSTER) != 0
        && (tr.ent.health > 0)
        && (null != tr.ent.monsterinfo.dodge)
        && GameUtil.infront(tr.ent, self)) {
      Math3D.VectorSubtract(tr.endpos, start, v);
      eta = (Math3D.VectorLength(v) - tr.ent.maxs[0]) / speed;
      tr.ent.monsterinfo.dodge.dodge(tr.ent, self, eta);
    }
  }
Пример #6
0
/**
 * Mesh
 *
 * @author cwei
 */
public abstract class Mesh extends Light {

  // g_mesh.c: triangle model functions
  /*
   * =============================================================
   *
   * ALIAS MODELS
   *
   * =============================================================
   */

  static final int NUMVERTEXNORMALS = 162;

  float[][] r_avertexnormals = Anorms.VERTEXNORMALS;

  float[] shadevector = {0, 0, 0};

  float[] shadelight = {0, 0, 0};

  // precalculated dot products for quantized angles
  static final int SHADEDOT_QUANT = 16;

  float[][] r_avertexnormal_dots = Anorms.VERTEXNORMAL_DOTS;

  float[] shadedots = r_avertexnormal_dots[0];

  /**
   * GL_LerpVerts
   *
   * @param nverts
   * @param ov
   * @param verts
   * @param move
   * @param frontv
   * @param backv
   */
  void GL_LerpVerts(int nverts, int[] ov, int[] v, float[] move, float[] frontv, float[] backv) {
    FloatBuffer lerp = vertexArrayBuf;
    lerp.limit((nverts << 2) - nverts); // nverts * 3

    int ovv, vv;
    // PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
    if ((currententity.flags
            & (Defines.RF_SHELL_RED
                | Defines.RF_SHELL_GREEN
                | Defines.RF_SHELL_BLUE
                | Defines.RF_SHELL_DOUBLE
                | Defines.RF_SHELL_HALF_DAM))
        != 0) {
      float[] normal;
      int j = 0;
      for (int i = 0; i < nverts; i++ /* , v++, ov++, lerp+=4 */) {
        vv = v[i];
        normal = r_avertexnormals[(vv >>> 24) & 0xFF];
        ovv = ov[i];
        lerp.put(
            j,
            move[0]
                + (ovv & 0xFF) * backv[0]
                + (vv & 0xFF) * frontv[0]
                + normal[0] * Defines.POWERSUIT_SCALE);
        lerp.put(
            j + 1,
            move[1]
                + ((ovv >>> 8) & 0xFF) * backv[1]
                + ((vv >>> 8) & 0xFF) * frontv[1]
                + normal[1] * Defines.POWERSUIT_SCALE);
        lerp.put(
            j + 2,
            move[2]
                + ((ovv >>> 16) & 0xFF) * backv[2]
                + ((vv >>> 16) & 0xFF) * frontv[2]
                + normal[2] * Defines.POWERSUIT_SCALE);
        j += 3;
      }
    } else {
      int j = 0;
      for (int i = 0; i < nverts; i++ /* , v++, ov++, lerp+=4 */) {
        ovv = ov[i];
        vv = v[i];

        lerp.put(j, move[0] + (ovv & 0xFF) * backv[0] + (vv & 0xFF) * frontv[0]);
        lerp.put(
            j + 1, move[1] + ((ovv >>> 8) & 0xFF) * backv[1] + ((vv >>> 8) & 0xFF) * frontv[1]);
        lerp.put(
            j + 2, move[2] + ((ovv >>> 16) & 0xFF) * backv[2] + ((vv >>> 16) & 0xFF) * frontv[2]);
        j += 3;
      }
    }
  }

  private final FloatBuffer colorArrayBuf = Lib.newFloatBuffer(qfiles.MAX_VERTS * 4);

  private final FloatBuffer vertexArrayBuf = Lib.newFloatBuffer(qfiles.MAX_VERTS * 3);

  private final FloatBuffer textureArrayBuf = Lib.newFloatBuffer(qfiles.MAX_VERTS * 2);

  boolean isFilled = false;

  float[] tmpVec = {0, 0, 0};

  float[][] vectors = {
    {0, 0, 0}, {0, 0, 0}, {0, 0, 0} // 3 mal vec3_t
  };

  // stack variable
  private final float[] move = {0, 0, 0}; // vec3_t

  private final float[] frontv = {0, 0, 0}; // vec3_t

  private final float[] backv = {0, 0, 0}; // vec3_t

  /**
   * GL_DrawAliasFrameLerp
   *
   * <p>interpolates between two frames and origins FIXME: batch lerp all vertexes
   */
  void GL_DrawAliasFrameLerp(qfiles.dmdl_t paliashdr, float backlerp) {
    qfiles.daliasframe_t frame = paliashdr.aliasFrames[currententity.frame];

    int[] verts = frame.verts;

    qfiles.daliasframe_t oldframe = paliashdr.aliasFrames[currententity.oldframe];

    int[] ov = oldframe.verts;

    float alpha;
    if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) alpha = currententity.alpha;
    else alpha = 1.0f;

    // PMM - added double shell
    if ((currententity.flags
            & (Defines.RF_SHELL_RED
                | Defines.RF_SHELL_GREEN
                | Defines.RF_SHELL_BLUE
                | Defines.RF_SHELL_DOUBLE
                | Defines.RF_SHELL_HALF_DAM))
        != 0) gl.glDisable(GL_TEXTURE_2D);

    float frontlerp = 1.0f - backlerp;

    // move should be the delta back to the previous frame * backlerp
    Math3D.VectorSubtract(currententity.oldorigin, currententity.origin, frontv);
    Math3D.AngleVectors(currententity.angles, vectors[0], vectors[1], vectors[2]);

    move[0] = Math3D.DotProduct(frontv, vectors[0]); // forward
    move[1] = -Math3D.DotProduct(frontv, vectors[1]); // left
    move[2] = Math3D.DotProduct(frontv, vectors[2]); // up

    Math3D.VectorAdd(move, oldframe.translate, move);

    for (int i = 0; i < 3; i++) {
      move[i] = backlerp * move[i] + frontlerp * frame.translate[i];
      frontv[i] = frontlerp * frame.scale[i];
      backv[i] = backlerp * oldframe.scale[i];
    }

    // ab hier wird optimiert

    GL_LerpVerts(paliashdr.num_xyz, ov, verts, move, frontv, backv);

    gl.glEnableClientState(GL_VERTEX_ARRAY);
    gl.glVertexPointer(3, 0, vertexArrayBuf);

    // PMM - added double damage shell
    if ((currententity.flags
            & (Defines.RF_SHELL_RED
                | Defines.RF_SHELL_GREEN
                | Defines.RF_SHELL_BLUE
                | Defines.RF_SHELL_DOUBLE
                | Defines.RF_SHELL_HALF_DAM))
        != 0) {
      gl.glColor4f(shadelight[0], shadelight[1], shadelight[2], alpha);
    } else {
      gl.glEnableClientState(GL_COLOR_ARRAY);
      gl.glColorPointer(4, 0, colorArrayBuf);

      //
      // pre light everything
      //
      FloatBuffer color = colorArrayBuf;
      float l;
      int size = paliashdr.num_xyz;
      int j = 0;
      for (int i = 0; i < size; i++) {
        l = shadedots[(verts[i] >>> 24) & 0xFF];
        color.put(j, l * shadelight[0]);
        color.put(j + 1, l * shadelight[1]);
        color.put(j + 2, l * shadelight[2]);
        color.put(j + 3, alpha);
        j += 4;
      }
    }

    gl.glClientActiveTextureARB(TEXTURE0);
    gl.glTexCoordPointer(2, 0, textureArrayBuf);
    gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    int pos = 0;
    int[] counts = paliashdr.counts;

    ShortBuffer srcIndexBuf = null;

    FloatBuffer dstTextureCoords = textureArrayBuf;
    FloatBuffer srcTextureCoords = paliashdr.textureCoordBuf;

    int dstIndex = 0;
    int srcIndex = 0;
    int count;
    int mode;
    int size = counts.length;
    for (int j = 0; j < size; j++) {

      // get the vertex count and primitive type
      count = counts[j];
      if (count == 0) break; // done

      srcIndexBuf = paliashdr.indexElements[j];

      mode = GL_TRIANGLE_STRIP;
      if (count < 0) {
        mode = GL_TRIANGLE_FAN;
        count = -count;
      }
      srcIndex = pos << 1;
      srcIndex--;
      for (int k = 0; k < count; k++) {
        dstIndex = srcIndexBuf.get(k) << 1;
        dstTextureCoords.put(dstIndex, srcTextureCoords.get(++srcIndex));
        dstTextureCoords.put(++dstIndex, srcTextureCoords.get(++srcIndex));
      }

      gl.glDrawElements(mode, srcIndexBuf);
      pos += count;
    }

    // PMM - added double damage shell
    if ((currententity.flags
            & (Defines.RF_SHELL_RED
                | Defines.RF_SHELL_GREEN
                | Defines.RF_SHELL_BLUE
                | Defines.RF_SHELL_DOUBLE
                | Defines.RF_SHELL_HALF_DAM))
        != 0) gl.glEnable(GL_TEXTURE_2D);

    gl.glDisableClientState(GL_COLOR_ARRAY);
  }

  private final float[] point = {0, 0, 0};

  /** GL_DrawAliasShadow */
  void GL_DrawAliasShadow(qfiles.dmdl_t paliashdr, int posenum) {
    float lheight = currententity.origin[2] - lightspot[2];
    int[] order = paliashdr.glCmds;
    float height = -lheight + 1.0f;

    int orderIndex = 0;
    int index = 0;

    // TODO shadow drawing with vertex arrays

    int count;
    while (true) {
      // get the vertex count and primitive type
      count = order[orderIndex++];
      if (count == 0) break; // done
      if (count < 0) {
        count = -count;
        gl.glBegin(GL_TRIANGLE_FAN);
      } else gl.glBegin(GL_TRIANGLE_STRIP);

      do {
        index = order[orderIndex + 2] * 3;
        point[0] = vertexArrayBuf.get(index);
        point[1] = vertexArrayBuf.get(index + 1);
        point[2] = vertexArrayBuf.get(index + 2);

        point[0] -= shadevector[0] * (point[2] + lheight);
        point[1] -= shadevector[1] * (point[2] + lheight);
        point[2] = height;
        gl.glVertex3f(point[0], point[1], point[2]);

        orderIndex += 3;

      } while (--count != 0);

      gl.glEnd();
    }
  }

  // TODO sync with jogl renderer. hoz
  // stack variable
  private final float[] mins = {0, 0, 0};

  private final float[] maxs = {0, 0, 0};

  /** R_CullAliasModel */
  boolean R_CullAliasModel(entity_t e) {
    qfiles.dmdl_t paliashdr = (qfiles.dmdl_t) currentmodel.extradata;

    if ((e.frame >= paliashdr.num_frames) || (e.frame < 0)) {
      VID.Printf(
          Defines.PRINT_ALL,
          "R_CullAliasModel " + currentmodel.name + ": no such frame " + e.frame + '\n');
      e.frame = 0;
    }
    if ((e.oldframe >= paliashdr.num_frames) || (e.oldframe < 0)) {
      VID.Printf(
          Defines.PRINT_ALL,
          "R_CullAliasModel " + currentmodel.name + ": no such oldframe " + e.oldframe + '\n');
      e.oldframe = 0;
    }

    qfiles.daliasframe_t pframe = paliashdr.aliasFrames[e.frame];
    qfiles.daliasframe_t poldframe = paliashdr.aliasFrames[e.oldframe];

    /*
     * * compute axially aligned mins and maxs
     */
    if (pframe == poldframe) {
      for (int i = 0; i < 3; i++) {
        mins[i] = pframe.translate[i];
        maxs[i] = mins[i] + pframe.scale[i] * 255;
      }
    } else {
      float thismaxs, oldmaxs;
      for (int i = 0; i < 3; i++) {
        thismaxs = pframe.translate[i] + pframe.scale[i] * 255;

        oldmaxs = poldframe.translate[i] + poldframe.scale[i] * 255;

        if (pframe.translate[i] < poldframe.translate[i]) mins[i] = pframe.translate[i];
        else mins[i] = poldframe.translate[i];

        if (thismaxs > oldmaxs) maxs[i] = thismaxs;
        else maxs[i] = oldmaxs;
      }
    }

    /*
     * * compute a full bounding box
     */
    float[] tmp;
    for (int i = 0; i < 8; i++) {
      tmp = bbox[i];
      if ((i & 1) != 0) tmp[0] = mins[0];
      else tmp[0] = maxs[0];

      if ((i & 2) != 0) tmp[1] = mins[1];
      else tmp[1] = maxs[1];

      if ((i & 4) != 0) tmp[2] = mins[2];
      else tmp[2] = maxs[2];
    }

    /*
     * * rotate the bounding box
     */
    tmp = mins;
    Math3D.VectorCopy(e.angles, tmp);
    tmp[YAW] = -tmp[YAW];
    Math3D.AngleVectors(tmp, vectors[0], vectors[1], vectors[2]);

    for (int i = 0; i < 8; i++) {
      Math3D.VectorCopy(bbox[i], tmp);

      bbox[i][0] = Math3D.DotProduct(vectors[0], tmp);
      bbox[i][1] = -Math3D.DotProduct(vectors[1], tmp);
      bbox[i][2] = Math3D.DotProduct(vectors[2], tmp);

      Math3D.VectorAdd(e.origin, bbox[i], bbox[i]);
    }

    int f, mask;
    int aggregatemask = ~0; // 0xFFFFFFFF

    for (int p = 0; p < 8; p++) {
      mask = 0;

      for (f = 0; f < 4; f++) {
        float dp = Math3D.DotProduct(frustum[f].normal, bbox[p]);

        if ((dp - frustum[f].dist) < 0) {
          mask |= (1 << f);
        }
      }

      aggregatemask &= mask;
    }

    if (aggregatemask != 0) {
      return true;
    }

    return false;
  }

  // bounding box
  float[][] bbox = {
    {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}
  };

  // TODO sync with jogl renderer. hoz
  /** R_DrawAliasModel */
  void R_DrawAliasModel(entity_t e) {
    if ((e.flags & Defines.RF_WEAPONMODEL) == 0) {
      if (R_CullAliasModel(e)) return;
    }

    if ((e.flags & Defines.RF_WEAPONMODEL) != 0) {
      if (r_lefthand.value == 2.0f) return;
    }

    qfiles.dmdl_t paliashdr = (qfiles.dmdl_t) currentmodel.extradata;

    //
    // get lighting information
    //
    // PMM - rewrote, reordered to handle new shells & mixing
    // PMM - 3.20 code .. replaced with original way of doing it to keep mod
    // authors happy
    //
    int i;
    if ((currententity.flags
            & (Defines.RF_SHELL_HALF_DAM
                | Defines.RF_SHELL_GREEN
                | Defines.RF_SHELL_RED
                | Defines.RF_SHELL_BLUE
                | Defines.RF_SHELL_DOUBLE))
        != 0) {
      Math3D.VectorClear(shadelight);
      if ((currententity.flags & Defines.RF_SHELL_HALF_DAM) != 0) {
        shadelight[0] = 0.56f;
        shadelight[1] = 0.59f;
        shadelight[2] = 0.45f;
      }
      if ((currententity.flags & Defines.RF_SHELL_DOUBLE) != 0) {
        shadelight[0] = 0.9f;
        shadelight[1] = 0.7f;
      }
      if ((currententity.flags & Defines.RF_SHELL_RED) != 0) shadelight[0] = 1.0f;
      if ((currententity.flags & Defines.RF_SHELL_GREEN) != 0) shadelight[1] = 1.0f;
      if ((currententity.flags & Defines.RF_SHELL_BLUE) != 0) shadelight[2] = 1.0f;
    } else if ((currententity.flags & Defines.RF_FULLBRIGHT) != 0) {
      for (i = 0; i < 3; i++) shadelight[i] = 1.0f;
    } else {
      R_LightPoint(currententity.origin, shadelight);

      // player lighting hack for communication back to server
      // big hack!
      if ((currententity.flags & Defines.RF_WEAPONMODEL) != 0) {
        // pick the greatest component, which should be the same
        // as the mono value returned by software
        if (shadelight[0] > shadelight[1]) {
          if (shadelight[0] > shadelight[2]) r_lightlevel.value = 150 * shadelight[0];
          else r_lightlevel.value = 150 * shadelight[2];
        } else {
          if (shadelight[1] > shadelight[2]) r_lightlevel.value = 150 * shadelight[1];
          else r_lightlevel.value = 150 * shadelight[2];
        }
      }

      if (gl_monolightmap.string.charAt(0) != '0') {
        float s = shadelight[0];

        if (s < shadelight[1]) s = shadelight[1];
        if (s < shadelight[2]) s = shadelight[2];

        shadelight[0] = s;
        shadelight[1] = s;
        shadelight[2] = s;
      }
    }

    if ((currententity.flags & Defines.RF_MINLIGHT) != 0) {
      for (i = 0; i < 3; i++) if (shadelight[i] > 0.1f) break;
      if (i == 3) {
        shadelight[0] = 0.1f;
        shadelight[1] = 0.1f;
        shadelight[2] = 0.1f;
      }
    }

    if ((currententity.flags & Defines.RF_GLOW) != 0) { // bonus items
      // will pulse
      // with time
      float scale;
      float min;

      scale = (float) (0.1f * Math.sin(r_newrefdef.time * 7));
      for (i = 0; i < 3; i++) {
        min = shadelight[i] * 0.8f;
        shadelight[i] += scale;
        if (shadelight[i] < min) shadelight[i] = min;
      }
    }

    // =================
    // PGM ir goggles color override
    if ((r_newrefdef.rdflags & Defines.RDF_IRGOGGLES) != 0
        && (currententity.flags & Defines.RF_IR_VISIBLE) != 0) {
      shadelight[0] = 1.0f;
      shadelight[1] = 0.0f;
      shadelight[2] = 0.0f;
    }
    // PGM
    // =================

    shadedots =
        r_avertexnormal_dots[
            ((int) (currententity.angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];

    float an = (float) (currententity.angles[1] / 180 * Math.PI);
    shadevector[0] = (float) Math.cos(-an);
    shadevector[1] = (float) Math.sin(-an);
    shadevector[2] = 1;
    Math3D.VectorNormalize(shadevector);

    //
    // locate the proper data
    //

    c_alias_polys += paliashdr.num_tris;

    //
    // draw all the triangles
    //
    if ((currententity.flags & Defines.RF_DEPTHHACK) != 0) // hack the
      // depth range
      // to prevent
      // view model
      // from poking
      // into walls
      gl.glDepthRange(gldepthmin, gldepthmin + 0.3 * (gldepthmax - gldepthmin));

    if ((currententity.flags & Defines.RF_WEAPONMODEL) != 0 && (r_lefthand.value == 1.0f)) {
      gl.glMatrixMode(GL_PROJECTION);
      gl.glPushMatrix();
      gl.glLoadIdentity();
      gl.glScalef(-1, 1, 1);
      MYgluPerspective(r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height, 4, 4096);
      gl.glMatrixMode(GL_MODELVIEW);

      gl.glCullFace(GL_BACK);
    }

    gl.glPushMatrix();
    e.angles[PITCH] = -e.angles[PITCH]; // sigh.
    R_RotateForEntity(e);
    e.angles[PITCH] = -e.angles[PITCH]; // sigh.

    image_t skin;
    // select skin
    if (currententity.skin != null) skin = currententity.skin; // custom player skin
    else {
      if (currententity.skinnum >= qfiles.MAX_MD2SKINS) skin = currentmodel.skins[0];
      else {
        skin = currentmodel.skins[currententity.skinnum];
        if (skin == null) skin = currentmodel.skins[0];
      }
    }
    if (skin == null) skin = r_notexture; // fallback...
    GL_Bind(skin.texnum);

    // draw it

    gl.glShadeModel(GL_SMOOTH);

    GL_TexEnv(GL_MODULATE);
    if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) {
      gl.glEnable(GL_BLEND);
    }

    if ((currententity.frame >= paliashdr.num_frames) || (currententity.frame < 0)) {
      VID.Printf(
          Defines.PRINT_ALL,
          "R_DrawAliasModel "
              + currentmodel.name
              + ": no such frame "
              + currententity.frame
              + '\n');
      currententity.frame = 0;
      currententity.oldframe = 0;
    }

    if ((currententity.oldframe >= paliashdr.num_frames) || (currententity.oldframe < 0)) {
      VID.Printf(
          Defines.PRINT_ALL,
          "R_DrawAliasModel "
              + currentmodel.name
              + ": no such oldframe "
              + currententity.oldframe
              + '\n');
      currententity.frame = 0;
      currententity.oldframe = 0;
    }

    if (r_lerpmodels.value == 0.0f) currententity.backlerp = 0;

    GL_DrawAliasFrameLerp(paliashdr, currententity.backlerp);

    GL_TexEnv(GL_REPLACE);
    gl.glShadeModel(GL_FLAT);

    gl.glPopMatrix();

    if ((currententity.flags & Defines.RF_WEAPONMODEL) != 0 && (r_lefthand.value == 1.0F)) {
      gl.glMatrixMode(GL_PROJECTION);
      gl.glPopMatrix();
      gl.glMatrixMode(GL_MODELVIEW);
      gl.glCullFace(GL_FRONT);
    }

    if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) {
      gl.glDisable(GL_BLEND);
    }

    if ((currententity.flags & Defines.RF_DEPTHHACK) != 0) gl.glDepthRange(gldepthmin, gldepthmax);

    if (gl_shadows.value != 0.0f
        && (currententity.flags & (Defines.RF_TRANSLUCENT | Defines.RF_WEAPONMODEL)) == 0) {
      gl.glPushMatrix();
      R_RotateForEntity(e);
      gl.glDisable(GL_TEXTURE_2D);
      gl.glEnable(GL_BLEND);
      gl.glColor4f(0, 0, 0, 0.5f);
      GL_DrawAliasShadow(paliashdr, currententity.frame);
      gl.glEnable(GL_TEXTURE_2D);
      gl.glDisable(GL_BLEND);
      gl.glPopMatrix();
    }
    gl.glColor4f(1, 1, 1, 1);
  }
}
Пример #7
0
  /*
   * =================
   * fire_lead
   *
   * This is an internal support routine used for bullet/pellet based weapons.
   * =================
   */
  public static void fire_lead(
      edict_t self,
      float[] start,
      float[] aimdir,
      int damage,
      int kick,
      int te_impact,
      int hspread,
      int vspread,
      int mod) {
    trace_t tr;
    float[] dir = {0, 0, 0};
    float[] forward = {0, 0, 0}, right = {0, 0, 0}, up = {0, 0, 0};
    float[] end = {0, 0, 0};
    float r;
    float u;
    float[] water_start = {0, 0, 0};
    boolean water = false;
    int content_mask = Defines.MASK_SHOT | Defines.MASK_WATER;

    tr = GameBase.gi.trace(self.s.origin, null, null, start, self, Defines.MASK_SHOT);
    if (!(tr.fraction < 1.0)) {
      Math3D.vectoangles(aimdir, dir);
      Math3D.AngleVectors(dir, forward, right, up);

      r = Lib.crandom() * hspread;
      u = Lib.crandom() * vspread;
      Math3D.VectorMA(start, 8192, forward, end);
      Math3D.VectorMA(end, r, right, end);
      Math3D.VectorMA(end, u, up, end);

      if ((GameBase.gi.pointcontents.pointcontents(start) & Defines.MASK_WATER) != 0) {
        water = true;
        Math3D.VectorCopy(start, water_start);
        content_mask &= ~Defines.MASK_WATER;
      }

      tr = GameBase.gi.trace(start, null, null, end, self, content_mask);

      // see if we hit water
      if ((tr.contents & Defines.MASK_WATER) != 0) {
        int color;

        water = true;
        Math3D.VectorCopy(tr.endpos, water_start);

        if (!Math3D.VectorEquals(start, tr.endpos)) {
          if ((tr.contents & Defines.CONTENTS_WATER) != 0) {
            if (Lib.strcmp(tr.surface.name, "*brwater") == 0) color = Defines.SPLASH_BROWN_WATER;
            else color = Defines.SPLASH_BLUE_WATER;
          } else if ((tr.contents & Defines.CONTENTS_SLIME) != 0) color = Defines.SPLASH_SLIME;
          else if ((tr.contents & Defines.CONTENTS_LAVA) != 0) color = Defines.SPLASH_LAVA;
          else color = Defines.SPLASH_UNKNOWN;

          if (color != Defines.SPLASH_UNKNOWN) {
            GameBase.gi.WriteByte(Defines.svc_temp_entity);
            GameBase.gi.WriteByte(Defines.TE_SPLASH);
            GameBase.gi.WriteByte(8);
            GameBase.gi.WritePosition(tr.endpos);
            GameBase.gi.WriteDir(tr.plane.normal);
            GameBase.gi.WriteByte(color);
            GameBase.gi.multicast(tr.endpos, Defines.MULTICAST_PVS);
          }

          // change bullet's course when it enters water
          Math3D.VectorSubtract(end, start, dir);
          Math3D.vectoangles(dir, dir);
          Math3D.AngleVectors(dir, forward, right, up);
          r = Lib.crandom() * hspread * 2;
          u = Lib.crandom() * vspread * 2;
          Math3D.VectorMA(water_start, 8192, forward, end);
          Math3D.VectorMA(end, r, right, end);
          Math3D.VectorMA(end, u, up, end);
        }

        // re-trace ignoring water this time
        tr = GameBase.gi.trace(water_start, null, null, end, self, Defines.MASK_SHOT);
      }
    }

    // send gun puff / flash
    if (!((tr.surface != null) && 0 != (tr.surface.flags & Defines.SURF_SKY))) {
      if (tr.fraction < 1.0) {
        if (tr.ent.takedamage != 0) {
          GameCombat.T_Damage(
              tr.ent,
              self,
              self,
              aimdir,
              tr.endpos,
              tr.plane.normal,
              damage,
              kick,
              Defines.DAMAGE_BULLET,
              mod);
        } else {
          if (!"sky".equals(tr.surface.name)) {
            GameBase.gi.WriteByte(Defines.svc_temp_entity);
            GameBase.gi.WriteByte(te_impact);
            GameBase.gi.WritePosition(tr.endpos);
            GameBase.gi.WriteDir(tr.plane.normal);
            GameBase.gi.multicast(tr.endpos, Defines.MULTICAST_PVS);

            if (self.client != null)
              PlayerWeapon.PlayerNoise(self, tr.endpos, Defines.PNOISE_IMPACT);
          }
        }
      }
    }

    // if went through water, determine where the end and make a bubble
    // trail
    if (water) {
      float[] pos = {0, 0, 0};

      Math3D.VectorSubtract(tr.endpos, water_start, dir);
      Math3D.VectorNormalize(dir);
      Math3D.VectorMA(tr.endpos, -2, dir, pos);
      if ((GameBase.gi.pointcontents.pointcontents(pos) & Defines.MASK_WATER) != 0)
        Math3D.VectorCopy(pos, tr.endpos);
      else tr = GameBase.gi.trace(pos, null, null, water_start, tr.ent, Defines.MASK_WATER);

      Math3D.VectorAdd(water_start, tr.endpos, pos);
      Math3D.VectorScale(pos, 0.5f, pos);

      GameBase.gi.WriteByte(Defines.svc_temp_entity);
      GameBase.gi.WriteByte(Defines.TE_BUBBLETRAIL);
      GameBase.gi.WritePosition(water_start);
      GameBase.gi.WritePosition(tr.endpos);
      GameBase.gi.multicast(pos, Defines.MULTICAST_PVS);
    }
  }
Пример #8
0
        public boolean think(edict_t self) {
          edict_t ent;
          edict_t ignore;
          float[] point = {0, 0, 0};
          float[] dir = {0, 0, 0};
          float[] start = {0, 0, 0};
          float[] end = {0, 0, 0};
          int dmg;
          trace_t tr;

          if (GameBase.deathmatch.value != 0) dmg = 5;
          else dmg = 10;

          EdictIterator edit = null;
          while ((edit = GameBase.findradius(edit, self.s.origin, 256)) != null) {
            ent = edit.o;

            if (ent == self) continue;

            if (ent == self.owner) continue;

            if (ent.takedamage == 0) continue;

            if (0 == (ent.svflags & Defines.SVF_MONSTER)
                && (null == ent.client)
                && (Lib.strcmp(ent.classname, "misc_explobox") != 0)) continue;

            Math3D.VectorMA(ent.absmin, 0.5f, ent.size, point);

            Math3D.VectorSubtract(point, self.s.origin, dir);
            Math3D.VectorNormalize(dir);

            ignore = self;
            Math3D.VectorCopy(self.s.origin, start);
            Math3D.VectorMA(start, 2048, dir, end);
            while (true) {
              tr =
                  GameBase.gi.trace(
                      start,
                      null,
                      null,
                      end,
                      ignore,
                      Defines.CONTENTS_SOLID
                          | Defines.CONTENTS_MONSTER
                          | Defines.CONTENTS_DEADMONSTER);

              if (null == tr.ent) break;

              // hurt it if we can
              if ((tr.ent.takedamage != 0)
                  && 0 == (tr.ent.flags & Defines.FL_IMMUNE_LASER)
                  && (tr.ent != self.owner))
                GameCombat.T_Damage(
                    tr.ent,
                    self,
                    self.owner,
                    dir,
                    tr.endpos,
                    Globals.vec3_origin,
                    dmg,
                    1,
                    Defines.DAMAGE_ENERGY,
                    Defines.MOD_BFG_LASER);

              // if we hit something that's not a monster or player we're
              // done
              if (0 == (tr.ent.svflags & Defines.SVF_MONSTER) && (null == tr.ent.client)) {
                GameBase.gi.WriteByte(Defines.svc_temp_entity);
                GameBase.gi.WriteByte(Defines.TE_LASER_SPARKS);
                GameBase.gi.WriteByte(4);
                GameBase.gi.WritePosition(tr.endpos);
                GameBase.gi.WriteDir(tr.plane.normal);
                GameBase.gi.WriteByte(self.s.skinnum);
                GameBase.gi.multicast(tr.endpos, Defines.MULTICAST_PVS);
                break;
              }

              ignore = tr.ent;
              Math3D.VectorCopy(tr.endpos, start);
            }

            GameBase.gi.WriteByte(Defines.svc_temp_entity);
            GameBase.gi.WriteByte(Defines.TE_BFG_LASER);
            GameBase.gi.WritePosition(self.s.origin);
            GameBase.gi.WritePosition(tr.endpos);
            GameBase.gi.multicast(self.s.origin, Defines.MULTICAST_PHS);
          }

          self.nextthink = GameBase.level.time + Defines.FRAMETIME;
          return true;
        }