/*
* This file is part of Deliantra, the Roguelike Realtime MMORPG.
*
* Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
* Copyright (©) 2001 Mark Wedel & Crossfire Development Team
* Copyright (©) 1992 Frank Tore Johansen
*
* Deliantra is free software: you can redistribute it and/or modify it under
* the terms of the Affero GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the Affero GNU General Public License
* and the GNU General Public License along with this program. If not, see
* .
*
* The authors can be reached via e-mail to
*/
#ifndef RANDOM_MAP_H
#define RANDOM_MAP_H
#include "util.h"
struct random_map_params : zero_initialised
{
char wall_name[512];
int xsize, ysize;
int expand2x;
int layoutoptions1;
int layoutoptions2;
int layoutoptions3;
int symmetry;
int difficulty;
int difficulty_given;
float difficulty_increase;
int dungeon_level;
int dungeon_depth;
int orientation;
uint32_t random_seed;
uint64_t total_map_hp;
int map_layout_style;
int symmetry_used;
HV *hv;
shstr_tmp as_shstr () const;
// fetch something from the options hash
SV *get_sv (const char *option) const;
const_utf8_string get_str (const char *option, const_utf8_string fallback = "") const;
IV get_iv (const char *option, IV fallback = 0) const;
UV get_uv (const char *option, UV fallback = 0) const;
NV get_nv (const char *option, NV fallback = 0) const;
void set (const char *option, SV *value) const;
void set (const char *option, const_utf8_string value) const;
void set (const char *option, IV value) const;
void set (const char *option, UV value) const;
void set (const char *option, NV value) const;
void set (const char *option, int value) const { set (option, (IV)value); }
// "private", adjusted sizes
int Xsize;
int Ysize;
random_map_params ();
random_map_params (random_map_params *RP);
random_map_params (HV *hv);
~random_map_params ();
};
enum {
LAYOUT_NONE,
LAYOUT_ONION,
LAYOUT_MAZE,
LAYOUT_SPIRAL,
LAYOUT_ROGUELIKE,
LAYOUT_SNAKE,
LAYOUT_SQUARE_SPIRAL,
LAYOUT_CAVE,
LAYOUT_MULTIPLE,
NROFLAYOUTS,
};
/*
* Move these defines out of room_gen_onion.c to here, as
* other files (like square_spiral) also uses them.
options:
0 Pick random options below
1 "centered"
2 linear doors (default is nonlinear)
4 bottom "centered"
8 bottom-right centered
16 irregularly/randomly spaced layers (default: regular)
32 outer wall off: i.e., no outer wall.
*/
enum {
RMOPT_RANDOM = 0,
RMOPT_CENTERED = 1,
RMOPT_LINEAR = 2,
RMOPT_BOTTOM_C = 4,
RMOPT_BOTTOM_R = 8,
RMOPT_IRR_SPACE = 16,
RMOPT_WALL_OFF = 32,
RMOPT_WALLS_ONLY = 64,
RMOPT_NO_DOORS = 256, /* Place walls insead of doors. Produces broken map. */
};
/* symmetry definitions--used in this file AND in treasure.c:
the numerical values matter so don't change them. */
enum {
SYMMETRY_RANDOM,
SYMMETRY_NONE,
SYMMETRY_X,
SYMMETRY_Y,
SYMMETRY_XY,
};
// 12 has been experimentally :( determined ot be a lot more stable
// than 11 or 10, leading to the assumption that something inherently
// needs a minimum size of at least 12
#define MIN_RANDOM_MAP_SIZE 12
// we often use signed chars for coordinates (and U8 for distances)
#define MAX_RANDOM_MAP_SIZE 120
// reference
//
// \0 floor only
// # wall
// D door
// < up
// > down
// C "center" (of onion maze)
// . ?? (rogue)
//
// use this in new code
INTERFACE_CLASS(layout)
struct layout
{
typedef char cell;
cell **data;
int w, h;
layout (int w, int h);
layout (layout ©);
// reference rect in other layout - will not keep the data alive,
// so never swap with it's orig, or free the orig when in use.
layout (layout &orig, int x1, int y1, int x2, int y2);
~layout ();
operator cell **() const
{
return data;
}
void swap (layout &maze)
{
::swap (maze.data, data);
::swap (maze.w , w );
::swap (maze.h , h );
::swap (maze.size, size);
}
MTH void swap (layout *maze) { swap (*maze); }
// for debugging, print maze to stdout
MTH void print () const;
// simple inpainting
MTH void fill (char fill);
MTH void clear () { fill (0); }
MTH void border (char fill = '#');
MTH void rect (int x1, int y1, int x2, int y2, char fill); // x2, y2 exclusive
MTH void fill_rect (int x1, int y1, int x2, int y2, char fill); // x2, y2 exclusive
MTH void fill_rand (int perc);
// makes sure all areas are connected
MTH void isolation_remover ();
// generates a cave, subtype 0 is a rough cave, randomly open or closed
MTH void gen_cave (int subtype);
// helper functions to modify the maze
MTH void erode_1_2 (int c1, int c2 = -1, int repeat = 1);
MTH void doorify ();
MTH void roomify (); // make some rooms in it, works best on onions
MTH void expand2x ();
MTH void symmetrize (int symmetry);
MTH void rotate (int rotation); // rotate by 1=90, 2=180, 3=270 degrees
void generate (random_map_params *RP);
private:
int size;
void alloc (int w, int h);
};
// utility functions, to use rmg_rndm instead of rndm.
static inline int
rmg_find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
{
swap (rmg_rndm, rndm);
int i = find_free_spot (ob, m, x, y, start, stop);
swap (rmg_rndm, rndm);
return i;
}
// a simple point helper struct
struct point
{
short x;
short y;
point ()
{
}
point (int x, int y)
: x(x), y(y)
{
}
};
// something like a vector or stack, but without
// out of bounds checking
template
struct fixed_stack
{
T *data;
int size;
int max;
fixed_stack ()
: size (0), data (0)
{
}
fixed_stack (int max)
: size (0), max (max)
{
data = salloc (max);
}
void reset (int new_max)
{
sfree (data, max);
size = 0;
max = new_max;
data = salloc (max);
}
void free ()
{
sfree (data, max);
data = 0;
}
~fixed_stack ()
{
sfree (data, max);
}
T &operator[](int idx)
{
return data [idx];
}
void push (T v)
{
data [size++] = v;
}
T &pop ()
{
return data [--size];
}
T remove (int idx)
{
T v = data [idx];
data [idx] = data [--size];
return v;
}
};
#endif