Пример #1
0
void		process_game(t_game *game)
{
	int	collisiontype;
	int i;

	if (game->playing)
	{
		handle_bar_position(game);
		if (!game->bar.sticky_ball)
		{
			i = -1;
			while (++i < 10)
			{
				if ((collisiontype = future_ball_collision(game)))
				{
					handle_collision(game, collisiontype);
					break ;
				}
				else
					do_ball_motion(game);
			}
		}
		if (game->ball.y > WIN_HEIGHT - BAR_MARGIN + 15)
			reset_game(game);
		if (count_brick(game->bricks->next) == 0)
			change_level(game);
	}
}
Пример #2
0
extern State *update_free( State * const state
                         , const double time
                         )
{
    Entity * const player_entity = & state->player.entity;

    const TileType non_walkable = TILE_WALL;
    TileType dst_tile = update_entity( player_entity, & state->map, 
                                       non_walkable, time );

    const int current = tile_at( & state->map, player_entity->position );
    if (current == TILE_TRAP) {
        die(state);
    } else if (current == TILE_TRADER) {
        change_state(state, STATE_TRADE);
    } else if (current == TILE_BOSS) {
        change_state(state, STATE_BOSS);
    }

    if (player_entity->position.x == state->map.width - 1) {
        state->current_level_no += 1;

        clean_map_data( & state-> map );
        change_level( & state->map, state->current_level_no );
        reset_entities( state );
        
        player_entity->position.x = 0;
        player_entity->destination 
            = player_entity->previous_position = player_entity->position;
    }

    for (int i = 0; i < state->enemies_count; i++) {
        Enemy *enemy = state->enemies + i;
        update_enemy( enemy, & state->map, time );
        if ( POINT_EQ( state->player.entity.position
                     , enemy->entity.position
                     ) ) {
            die(state);
        }

        Boulder * b = boulder_at( state, enemy->entity.destination );
        if ( b != NULL ) {
            cancel_move( & enemy->entity );
            swap_enemy_direction( enemy );
        }
    }

    for (int i = 0; i < state->boulders_count; i++) {
        Boulder *boulder = state->boulders + i;
        update_entity( & boulder->entity, & state->map, 0, time );
    }
        
    return state;
}
Пример #3
0
void warp(int blessing)
{
  int newlevel;
  if (Current_Environment != Current_Dungeon) 
    mprint("How strange! No effect....");
  else {
    newlevel = (int) parsenum("Warp to which level? ");
    if (newlevel >= MaxDungeonLevels || blessing < 0 || newlevel < 1) {
      mprint("You have been deflected!");
      newlevel=random_range(MaxDungeonLevels - 1) + 1;
    }
    mprint("You dematerialize...");
    change_level(Level->depth,newlevel,FALSE);
  }
  roomcheck();
}
Пример #4
0
extern State *create_initial_state()
{
    State *state = malloc(sizeof(State));
    if (state == NULL) return NULL;

    state->type = STATE_SPLASH;
    state->next_type = state->type;

    state->requested_quit = 0;

    state->marquee_amount = 0.0;
    state->is_marquee_closing = 0;

    init_player( & state->player, 0, 8 );
    state->trader_item = ITEM_SWORD;

    change_level( & state->map, 0 );

    return state;
}
Пример #5
0
/* Recreates the current level */
void flux(int blessing)
{
  mprint("The universe warps around you!");
  if (Current_Environment == E_CITY) {
    mprint("Sensing dangerous high order magic, the Collegium Magii");
    mprint("and the Circle of Sorcerors join forces to negate the spell.");
    mprint("You are zapped by an antimagic ray!!!");
    dispel(-1);
    mprint("The universe unwarps itself....");
  }
  else if (Current_Environment != Current_Dungeon)
    mprint("Odd.... No effect!");
  else {
    mprint("You stagger as the very nature of reality warps!");
    erase_level();
    Level->generated = FALSE;
    mprint("The fabric of spacetime reknits....");
    change_level(Level->depth-1,Level->depth,TRUE);
  }
}
Пример #6
0
int Map::l_split(int l, int vertex)
{
    int vertex2 = lines[l]->vertex2;

    int side1 = -1;
    int side2 = -1;
    int new_line = -1;

    // Add new side for side1
    if (lines[l]->side1 != -1)
    {
        side1 = add_side();
        memcpy(sides[side1], sides[lines[l]->side1], sizeof(sidedef_t));
    }

    // Add new side for side2
    if (lines[l]->side2 != -1)
    {
        side2 = add_side();
        memcpy(sides[side2], sides[lines[l]->side2], sizeof(sidedef_t));
    }

    // Create new line
    lines[l]->vertex2 = vertex;
    new_line = add_line(vertex, vertex2);

    // Setup new line
    memcpy(lines[new_line], lines[l], sizeof(linedef_t));
    lines[new_line]->vertex1 = vertex;
    lines[new_line]->vertex2 = vertex2;
    lines[new_line]->side1 = side1;
    lines[new_line]->side2 = side2;

    change_level(MC_LINES|MC_NODE_REBUILD);

    return new_line;
}
Пример #7
0
/*!

  Implements the estimation of a 2D parametric motion model.

  Depending on setRobustEstimator() two different schemes can be used: either
  involving a robust multiresolution estimation implementing the IRLS
  technique, or involving a multiresolution least-mean-square estimation.

  The estimation process is performed between images \f$I_t\f$ and
  \f$I_{t+1}\f$ for which the Gaussian and image gradient pyramids, denoted
  respectively \e pyramid1 and \e pyramid2, must be built using
  CMotion2DPyramid.

  The parameter \e support refers to the estimation support \f$R_t\f$. In other
  terms, \e support indicates which pixels of the image \f$I_t\f$ are taken
  into account in the estimation process. The size of \e support must be equal
  to the size of the finest level in the pyramids (\e pyramid1 or \e
  pyramid2). It usually consists of the whole image. In that case, all \e
  support must be set to \e label. But, if required, it can also be restricted
  to a specific area of the image. In that case, all the pixels belonging to
  this area must be set to \e label. The other pixels must be set to another
  value than \e label.

  An initialization of the motion \e model parameters does not affect the
  results.  That means that the parameters of the motion model given as input
  are not used to initialize the estimator.

  This function returns the estimated 2D parametric motion model in \e
  model. The returned parameters have to be considered for the highest
  resolution in the pyramids (level = 0) even if the last level considered in
  the estimation process is different when specified for example with
  setLastEstimationLevel(1). If the estimation process is stopped at a pyramid
  level different from 0, a projection of the motion model parameter to level 0
  is performed. For the projection from one given level to the next finer one,
  the constant parameters of the model are multiplied by 2, the affine
  parameters are unchanged and the quadratic parameters are divided by 2.

  The weight map can be obtained by getWeights().

  Returns true if the estimation process succeeds, false otherwise.

  \sa estimate(const CMotion2DPyramid &, const CMotion2DPyramid &, const unsigned char *, unsigned char, CMotion2DModel &), setRobustEstimator(), setFirstEstimationLevel(),
  setLastEstimationLevel(), getWeights(),


*/
bool CMotion2DEstimator::estimate(const CMotion2DPyramid & pyramid1,
				  const CMotion2DPyramid & pyramid2,
				  const short *support, short label,
				  CMotion2DModel & model,
				  bool useModelAsInitialization)
{
  if (DEBUG_LEVEL1)
    cout << "Begin CMotion2DEstimator::estimate()" << endl;

  Para paramet;
  float ligravbase = 0.;  /* Coordonnees du centre de gravite des regions.*/
  float cogravbase = 0.;  /* Coordonnees du centre de gravite des regions.*/
  int i;
  int Mode_Niv_Init;	  /* estime para cst, lin... avec niveaux par defaut */
  int para_init = 0;	  /* 108: au depart on n'a pas d'estimee des parametres */
			  /* //€ changer !! bug */

  bool state = false;

  // Check the pyramid size, if differ, return false
  int nrows_pyr1, ncols_pyr1;
  int nrows_pyr2, ncols_pyr2;
  if (pyramid1.getNumberOfRows(nrows_pyr1) != PYR_NO_ERROR)
    return false;
  if (pyramid1.getNumberOfCols(ncols_pyr1) != PYR_NO_ERROR)
    return false;
  if (pyramid2.getNumberOfRows(nrows_pyr2) != PYR_NO_ERROR)
    return false;
  if (pyramid2.getNumberOfCols(ncols_pyr2) != PYR_NO_ERROR)
    return false;
  if ((nrows_pyr1 != nrows_pyr2) || (ncols_pyr1 != ncols_pyr2)) {
    char message[FILENAME_MAX];
    sprintf(message, "CMotion2DEstimator::estimate() \n\tError: Pyramid size differ");
    __panic(message);
    return false;
  }

  if (DEBUG_LEVEL2) {
    cout << "Pyr 1: " << nrows_pyr1 << " x " << ncols_pyr1 << endl;
    cout << "Pyr 2: " << nrows_pyr2 << " x " << ncols_pyr2 << endl;
  }

  // Check if the memory initialization was done for the weights pyramid
  if (init_mem_weightsIsDone == true) {
    // Destruction of the weights pyramid if size differ
    if ((nrows != nrows_pyr1) || (ncols != ncols_pyr1)) {
      if (DEBUG_LEVEL3)
	cout << "free pyr_weights[] nlevels: " << pyr_level_max << endl;
      free_p_fl(&pyr_weights[0], pyr_level_max + 1);
      init_mem_weightsIsDone = false;
    }
  }

  // Check if the memory initialization was done for the internal pyramids
  if (init_mem_estIsDone == true) {
    // Destruction of the internal pyramids if size differ
    if ((nrows != nrows_pyr1) || (ncols != ncols_pyr1)) {
      if (DEBUG_LEVEL3)
	cout << "free mem_est nlevels: " << pyr_level_max << endl;
      efface_memoire_pyr_est(pyr_level_max + 1, &init_mem_estIsDone,
			     pyr_fl1, pyr_fl2, pyr_fl3, pyr_support);
      init_mem_estIsDone = false;
    }
  }

  // Initialisation:
  rapport_poids = 0.0;
  sigma2res     = 0.0;

  // Update the image size
  nrows         = nrows_pyr1;
  ncols         = ncols_pyr1;

  // Warning: To compute the covariance matrix we have to compute the residual
  // variance. Thus, if compute_covariance is true, we set compute_sigma2res to
  // true.
  if (compute_covariance)
    compute_sigma2res = true;

  // Initialize the covariance matrix to infinity
  init_covariance(&paramet);

  paramet.compute_covariance = compute_covariance;
  paramet.compute_sigma2res  = compute_sigma2res;
  paramet.sigma2res = 0.0;

  /* on prend les valeurs par d‰faut */
  if( level_ct==-1 && level_lin==-1 && level_quad==-1 )
    Mode_Niv_Init=0;
  else {
    Mode_Niv_Init=1;
    if (level_quad >= level_lin) {
      char message[FILENAME_MAX];
      sprintf(message, "CMotion2DEstimator::estimate() \n\tBad level number %d for starting the estimation of quadratic parameters while affine parameters are estimate at level %d...", level_quad, level_lin);
      __panic(message);
      return false;
    }
    if (level_lin >= level_ct ) {
      char message[FILENAME_MAX];
      sprintf(message, "CMotion2DEstimator::estimate() \n\tBad level number %d for starting the estimation of linear parameters while constant parameters are estimate at level %d...", level_lin, level_ct);
      __panic(message);
      return false;
    }
  }

  if (first_est_level < final_est_level) {
    char message[FILENAME_MAX];
    sprintf(message, "CMotion2DEstimator::estimate() \n\tBad initial and final estimation levels...");
    __panic(message);
    return false;
  }

  // Modifcation of the first level
  int pyr1_level_max = pyramid1.getNumberOfLevels() - 1;
  int pyr2_level_max = pyramid2.getNumberOfLevels() - 1;
  pyr_level_max      = Min(pyr1_level_max, pyr2_level_max);

  if (pyr_level_max < 0) {
    // The pyramid was not build
    return false;
  }

  // Modification of the first estimation level, if this level is not
  // built in the pyramids
  if (pyr_level_max > (int) first_est_level)
    pyr_level_max = first_est_level;

  // Allocate memory for the weights pyramid
  if (init_mem_weightsIsDone == false) {
    if (DEBUG_LEVEL3) {
      cout << "alloc pyr_weights[] nlevels: " << pyr_level_max << endl;
      cout << "nrows: " << nrows << " ncols: " << ncols << endl;
    }
    if (Mem_pyramide_float(&pyr_weights[0], nrows, ncols, pyr_level_max)
	== false)
      return false;
    init_mem_weightsIsDone = true;
  }

  // Initialize the memory used by the estimator for "pyr_fl1", "pyr_fl2" which
  // contains the displaced spatial gradients, for "pyr_fl3" which contains the
  // DFD ie I(pi+depl,t+1)-I(pi,t), and for "pyr_support" which contains the
  // estimator support.
  if (init_mem_est(nrows, ncols, pyr_level_max, &init_mem_estIsDone,
		   pyr_fl1, pyr_fl2, pyr_fl3, pyr_support) == false) {
    char message[FILENAME_MAX];
    sprintf(message, "CMotion2DEstimator::estimate() \n\tCan not allocate memory...");
    __panic(message);
    return false;
  }

  // Initialize the estimation support
  memcpy(pyr_support[0].ad, support, nrows * ncols*sizeof (short));

  paramet.n_points = 0;

  paramet.nb_para = Nb_Para_Modele(model.getIdModel());

  // Test if the motion model exists
  if (paramet.nb_para==0)
  {
    __panic("CMotion2DEstimator::estimate() \n\tMotion model not implemented.\n");
    return false;
  }

  paramet.var_light = model.getVarLight();
  paramet.id_model  = model.getIdModel();

  if (useModelAsInitialization == true) {
    para_init = 1;
    model.getParameters(paramet.thet); // set the MDL_NMAX_COEF parameters
    model.getVarLight(paramet.thet[12]);
  }
  else {
    para_init = 0;
    for(i=0;i<MAXCOEFSMODEL;i++) {
      paramet.thet[i] = 0.0;
    }
  }

  // Used to compute the window caracteristics
  center_of_gravity(&pyr_support[0], label,
		    &ligravbase, &cogravbase, &paramet.fen, 0);

  double row, col;
  model.getParameters(paramet.thet);
  model.getOrigin(row, col);

  if ((row == -1.f) && (col == -1.f)) { // Origin  not specified.
    // Origin set to the center of gravity
    paramet.li_c = ligravbase;
    paramet.co_c = cogravbase;
    model.setOrigin(paramet.li_c, paramet.co_c);
  }
  else {
    paramet.li_c = row;
    paramet.co_c = col;
  }

  if (DEBUG_LEVEL2) printf("avant appel RMRmod() label: %d\n", label);

  // Estimation robuste
  state = RMRmod(label, &paramet.fen, pyr_level_max,
		 pyramid1.pyr_ima, pyramid2.pyr_ima,
		 pyramid1.pyr_gx, pyramid1.pyr_gy,
		 pyramid2.pyr_gx, pyramid2.pyr_gy,
		 max_it_irls, ty_pond, least_mean_square,
		 type_variance, max_it_stab,
		 &paramet, para_init, &variance, Mode_Niv_Init,
		 level_ct, level_lin, level_quad,
		 final_est_level, &pyr_weights[0], tx_pts_min,
		 &pyr_fl1[0], &pyr_fl2[0],
		 &pyr_fl3[0], &pyr_support[0], verbose,
		 &ct_level_intro, &lin_level_intro, &quad_level_intro);

  // Test si l'estimation s'est bien deroulee
  if (state == false) return false;

  // Warning:
  // pyr_weights[final_est_level].ad contains the weights

  //
  // Compute the support size: conform pixels / pixels zone de recouvrement.
  //
  if (compute_support_size == 1) {
    double tx=0.0, ty=0.0;
    double a=0.0, b=0.0, c=0.0, d=0.0;
    double q1=0.0, q2=0.0, q3=0.0, q4=0.0, q5=0.0, q6=0.0; // Modele de mvt.

    int xsize = pyr_weights[final_est_level].nbco;
    int ysize = pyr_weights[final_est_level].nbli;
    int x, y;			// Coordonnees d'un pixel.
    int px, py;			// Coordonnees du pixel (x,y) deplace.
    float xg, yg;			// Origine du modele de mvt.
    int inter_size = 0;		// Taille de la zone commune entre t et t+1.
    float nb_pt_inter= 0.0;	// Nbre de points utiles dans la zone commune.
    float *pond = pyr_weights[final_est_level].ad;
    short *support = pyr_support[final_est_level].ad;
    int  support_size = 0;

    // On ramene si necessaire les parametres du modele de mvt du niveau 0
    // correspondant a la resolution la plus fine, au niveau final de
    // l'estimation (correspondant a l'imagette a un niveau plus grossier de la
    // pyramide).
    Para tmp_modele;

    change_level(&paramet, &tmp_modele, final_est_level);

    // The parameters
    tx = tmp_modele.thet[0];
    ty = tmp_modele.thet[1];
    a = tmp_modele.thet[2];
    b = tmp_modele.thet[3];
    c = tmp_modele.thet[4];
    d = tmp_modele.thet[5];
    q1 = tmp_modele.thet[6];
    q2 = tmp_modele.thet[7];
    q3 = tmp_modele.thet[8];
    q4 = tmp_modele.thet[9];
    q5 = tmp_modele.thet[10];
    q6 = tmp_modele.thet[11];

    // Balayage de l'imagette au niveau final de l'estimation
    xg = tmp_modele.co_c;
    yg = tmp_modele.li_c;
    // Pour optimiser legerement cette partie, 3 cas sont envisages en fonction
    // du degre du modele

    if ( model_degree(model.getIdModel()) == 2 ) {
      // Cas des modeles de mouvement quadratique
      for (y = 0; y < ysize; y++) {
	float y_yg    = y - yg;
        float y_yg2   = y_yg * y_yg;
	float y_yg_b  = y_yg * b;
	float y_yg_d  = y_yg * d;
	float ty_y    = ty + y;
	int    y_xsize = y * xsize;

	for (x = 0; x < xsize; x++) {
	  if (support[x + y_xsize] == label) {
	    float x_xg      = x - xg;
	    float x_xg2     = x_xg * x_xg;
	    float x_xg_y_yg = x_xg * y_yg;

	    support_size ++;

	    // Calcul du pixel deplace. Le calcul a effectuer est le suivant:
	    // px = (int) (tx + (x-xg)*a + (y-yg)*b
	    //  + (x-xg)*(x-xg)*q1 + (x-xg)*(y-yg)*q2 + (y-yg)*(y-yg)*q3 + x);
	    // py = (int) (ty + (x-xg)*c + (y-yg)*d
	    //  + (x-xg)*(x-xg)*q4 + (x-xg)*(y-yg)*q5 + (y-yg)*(y-yg)*q6 + y);
	    px = (int) (tx   + (x_xg)*a + y_yg_b
			+ (x_xg2)*q1 + (x_xg_y_yg)*q2 + (y_yg2)*q3 + x);
	    py = (int) (ty_y + (x_xg)*c + y_yg_d
			+ (x_xg2)*q4 + (x_xg_y_yg)*q5 + (y_yg2)*q6);

	    // Test si pixel deplace de t a t+1 reste a l'interieur de l'image
	    if ( (px >= 0) && (px < xsize) && (py >= 0) && (py < ysize) ) {
	      // Le pixel deplace restant dans l'imagette, incrementation de
	      // la taille de la zone commune entre t et t+1.
	      inter_size ++;
	      // Test si le pixel (x,y) participe au mvt dominant. En fait,
	      // on teste si la ponderation appliquee au pixel (x, y)
	      // est superieure a un seuil.
	      if (pond[x + y_xsize] > seuil_poids) {
		nb_pt_inter += 1.0;
	      }
	    }
	  }
	}
      }
    }
    else if ( model_degree(model.getIdModel()) == 1){
      // Cas des modeles de mouvement affine
      for (y = 0; y < ysize; y++) {
	float y_yg    = y - yg;
	float y_yg_b  = y_yg * b;
	float y_yg_d  = y_yg * d;
	float ty_y    = ty + y;
	int    y_xsize = y * xsize;

	for (x = 0; x < xsize; x++) {
	  if (support[x + y_xsize] == label) {
	    float x_xg = x - xg;

	    support_size ++;

	    // Calcul du pixel deplace. Le calcul a effectuer est le suivant:
	    //	px = (int) (tx + (x-xg)*a + (y-yg)*b + x);
	    //	py = (int) (ty + (x-xg)*c + (y-yg)*d + y);
	    px = (int) (tx   + (x_xg)*a + y_yg_b + x);
	    py = (int) (ty_y + (x_xg)*c + y_yg_d);

	    // Test si pixel deplace de t a t+1 reste a l'interieur de l'image
	    if ( (px >= 0) && (px < xsize) && (py >= 0) && (py < ysize) ) {
	      // Le pixel deplace restant dans l'imagette, incrementation de
	      // la taille de la zone commune entre t et t+1.
	      inter_size ++;
	      // Test si le pixel (x,y) participe au mvt dominant. En fait,
	      // on teste si la ponderation appliquee au pixel (x, y)
	      // est superieure a un seuil.
	      if (pond[x + y_xsize] > seuil_poids) {
		nb_pt_inter += 1.0;
	      }
	    }
	  }
	}
      }
    }
    else if ( model_degree(model.getIdModel()) == 0) {
      // Cas des modeles de mouvement constant
      for (y = 0; y < ysize; y++) {
	float ty_y    = ty + y;
	int   y_xsize = y * xsize;

	for (x = 0; x < xsize; x++) {
	  if (support[x + y_xsize] == label) {
	    support_size ++;

	    // Calcul du pixel deplace. Le calcul a effectuer est le suivant:
	    //	px = (int) (tx + x);
	    //	py = (int) (ty + y);
	    px = (int) (tx + x);
	    py = (int) (ty_y );

	    // Test si pixel deplace de t a t+1 reste a l'interieur de l'image
	    if ( (px >= 0) && (px < xsize) && (py >= 0) && (py < ysize) ) {
	      // Le pixel deplace restant dans l'imagette, incrementation de
	      // la taille de la zone commune entre t et t+1.
	      inter_size ++;
	      // Test si le pixel (x,y) participe au mvt dominant. En fait,
	      // on teste si la ponderation appliquee au pixel (x, y)
	      // est superieure a un seuil.
	      if (pond[x + y_xsize] > seuil_poids) {
		nb_pt_inter += 1.0;
	      }
	    }
	  }
	}
      }
    } // fin else degre modele

    // Calcul du taux de points conformes dans la zone de recouvrement.
    // Si le support est inferieur a 1/8 de la taille de l'image, on met
    // le rapport a 0.
    if (inter_size < ( (int) (support_size) / 8) )
      rapport_poids = 0.0;
    else
      rapport_poids = nb_pt_inter / inter_size;
  } // Fin du calcul du taux de points dans la zone de recouvrement.

  // Mise a jour de la variance du residuel.
  sigma2res = paramet.sigma2res;

  if (compute_covariance) {
    // Updates the covariance matrix
    memcpy(covariance, paramet.covariance,
	   MAXCOEFSMODEL * MAXCOEFSMODEL * sizeof(double));
  }

  double coefs[MAXCOEFSMODEL-1];
  for (i=0; i < MAXCOEFSMODEL-1; i++)
    coefs[i] = paramet.thet[i];

  model.setOrigin(paramet.li_c, paramet.co_c);
  model.setParameters(coefs);
  model.setVarLight(model.getVarLight(), paramet.thet[12]);

  if (DEBUG_LEVEL1)
    cout << "Fin CMotion2DEstimator::estimate()" << endl;

  return true;
}
Пример #8
0
void l_lift(void)
{
  char response;
  int levelnum;
  int distance;
  int too_far = 0;

  Level->site[Player.x][Player.y].locchar = FLOOR;
  Level->site[Player.x][Player.y].p_locf = L_NO_OP;
  lset(Player.x, Player.y, CHANGED);
  print1("You walk onto a shimmering disk....");
  print2("The disk vanishes, and a glow surrounds you.");
  print3("You feel weightless.... You feel ghostly....");
  morewait();
  clearmsg();
  print1("Go up, down, or neither [u,d,ESCAPE] ");
  do response = (char) mcigetc();
  while ((response != 'u') && 
	 (response != 'd') &&
	 (response != ESCAPE));
  if (response != ESCAPE) {
    print1("How many levels?");
    levelnum = (int) parsenum("");
    if (levelnum > 6) {
      too_far = 1;
      levelnum = 6;
    }
    if (response == 'u' && Level->depth - levelnum < 1) {
      distance = levelnum - Level->depth;
      change_environment(E_COUNTRYSIDE); /* "you return to the countryside." */
      if (distance > 0) {
	nprint1("..");
	print2("...and keep going up!  You hang in mid air...");
	morewait();
	print3("\"What goes up...\"");
	morewait();
	print3("Yaaaaaaaah........");
	p_damage(distance*10,NORMAL_DAMAGE,"a fall from a great height");
      }
      return;
    }
    else if (response == 'd' && Level->depth + levelnum > MaxDungeonLevels) {
      too_far = 1;
      levelnum = MaxDungeonLevels - Level->depth;
    }
    if (levelnum == 0) {
      print1("Nothing happens.");
      return;
    }
    if (too_far) {
      print1("The lift gives out partway...");
      print2("You rematerialize.....");
    }
    else
      print1("You rematerialize.....");
    change_level(Level->depth,
		(response=='d' ? 
		 Level->depth+levelnum : 
		 Level->depth-levelnum),
		FALSE);
    roomcheck();
  }
}
Пример #9
0
void l_abyss(void)
{
  int i;
  if (Current_Environment != Current_Dungeon) {
    print1("You fall through a dimensional portal!");
    morewait();
    strategic_teleport(-1);
  }
  else {
    print1("You enter the infinite abyss!");
    morewait();
    if (random_range(100)==13) {
      print1("As you fall you see before you what seems like");
      print2("an infinite congerie of iridescent bubbles.");
      print3("You have met Yog Sothoth!!!");
      morewait();
      clearmsg();
      if (Player.alignment > -10) 
	p_death("the Eater of Souls");
      else {
	print1("The All-In-One must have taken pity on you.");
	print2("A transdimensional portal appears...");
	morewait();
	change_level(Level->depth,Level->depth+1,FALSE);
	gain_experience(2000);
	Player.alignment -= 50;
      }
    }
    else {
      i = 0;
      print1("You fall...");
      while(random_range(3)!=2) {
	if (i%6 == 0)
	    print2("and fall... ");
	else
	    nprint2("and fall... ");
	i++;
	morewait();
      }
      i++;
      print1("Finally,you emerge through an interdimensional interstice...");
      morewait();
      if (Level->depth+i>MaxDungeonLevels) {
	print2("You emerge high above the ground!!!!");
	print3("Yaaaaaaaah........");
	morewait();
	change_environment(E_COUNTRYSIDE);
	do {
	  setPlayerXY( random_range(COUNTRY_WIDTH), random_range(COUNTRY_LENGTH));
	} while(Country[Player.x][Player.y].base_terrain_type == CHAOS_SEA);
	p_damage(i*50,NORMAL_DAMAGE,"a fall from a great height");
      }
      else {
	print2("You built up some velocity during your fall, though....");
	morewait();
	p_damage(i*5,NORMAL_DAMAGE,"a fall through the abyss");
	change_level(Level->depth,Level->depth+i,FALSE);
	gain_experience(i*i*50);
      }
    }
  }
}