/**
   * G_RunFrame
   *
   * <p>Advances the world by Defines.FRAMETIME (0.1) seconds.
   */
  public static void G_RunFrame() {
    int i;
    Entity ent;

    level.framenum++;
    level.time = level.framenum * Constants.FRAMETIME;

    // choose a client for monsters to target this frame
    GameAI.AI_SetSightClient();

    // exit intermissions

    if (level.exitintermission) {
      ExitLevel();
      return;
    }

    //
    // treat each object in turn
    // even the world gets a chance to think
    //

    for (i = 0; i < num_edicts; i++) {
      ent = g_edicts[i];
      if (!ent.inuse) continue;

      level.current_entity = ent;

      Math3D.VectorCopy(ent.s.origin, ent.s.old_origin);

      // if the ground entity moved, make sure we are still on it
      if ((ent.groundentity != null)
          && (ent.groundentity.linkcount != ent.groundentity_linkcount)) {
        ent.groundentity = null;
        if (0 == (ent.flags & (Constants.FL_SWIM | Constants.FL_FLY))
            && (ent.svflags & Constants.SVF_MONSTER) != 0) {
          ClientMonsterMethods.M_CheckGround(ent);
        }
      }

      if (i > 0 && i <= maxclients.value) {
        PlayerClient.ClientBeginServerFrame(ent);
        continue;
      }

      G_RunEntity(ent);
    }

    // see if it is time to end a deathmatch
    CheckDMRules();

    // see if needpass needs updated
    CheckNeedPass();

    // build the playerstate_t structures for all players
    ClientEndServerFrames();
  }
  /** Returns the created target changelevel. */
  public static Entity CreateTargetChangeLevel(String map) {
    Entity ent;

    ent = GameUtil.G_Spawn();
    ent.classname = "target_changelevel";
    level.nextmap = map;
    ent.map = level.nextmap;
    return ent;
  }
  /** Exits a level. */
  public static void ExitLevel() {
    int i;
    Entity ent;

    String command = "gamemap \"" + level.changemap + "\"\n";
    CommandBuffer.AddText(command);
    level.changemap = null;
    level.exitintermission = false;
    level.intermissiontime = 0;
    ClientEndServerFrames();

    // clear some things before going to next level
    for (i = 0; i < maxclients.value; i++) {
      ent = g_edicts[1 + i];
      if (!ent.inuse) continue;
      if (ent.health > ent.client.pers.max_health) ent.health = ent.client.pers.max_health;
    }
  }