Struct eos_rs::api::dungeon_mode::dungeon_generator::game_builtin::DungeonGridMutator
source · pub struct DungeonGridMutator { /* private fields */ }
Expand description
This helper struct can be used to create a grid of cells (DungeonGridCell
).
All coordinates that this struct uses are “ingame” coordinates (so (x, y)), unless otherwise noted.
It can also take ownership of existing Vec<DungeonGridCell>
and manipulate them.
Finally you can convert this struct into its inner Vec<DungeonGridCell>
using
Self::into_inner()
. See the notes on Self::new()
for more information.
The cell grid is used in one phase of the dungeon generation. Note that most of the generation functions here will generate tiles in the global dungeon struct.
Implementations§
source§impl DungeonGridMutator
impl DungeonGridMutator
sourcepub fn new_from_vec(
in_cells: Vec<DungeonGridCell>,
width: usize,
height: usize,
ov29: OverlayLoadLease<29>
) -> Self
pub fn new_from_vec( in_cells: Vec<DungeonGridCell>, width: usize, height: usize, ov29: OverlayLoadLease<29> ) -> Self
Takes ownership of the given in_cells
and returns a new DungeonGridMutator
.
The grid is a vector of grid cells stored in column-major order (!) (such that grid cells with the same x value are stored contiguously (y, x))
The dimensions passed in must match the dimensions of the Vec<DungeonGridCell>
,
otherwise this will panic.
Internally the grid has a fixed buffer size / capacity of 15 x 15. If the grid size in the
X or Y direction is less than this, so when working with the (raw) grid buffer,
you will need to take into account that each column will have 15 rows, where the last
(15-height
) in each column will be uninitialised and that after width
rows
the rest of the array will be uninitialised as well.
This helper will abstract for you over this, if you query a cell via eg. Self::get
,
however Self::into_inner()
will still return a vector with 15 x 15 cells, with all
missing values initialized with defaults.
Note that the game usually works with the assumption that there are exactly 15 rows. Using other row sizes may or may not lead to UB with some methods.
The maximum values for width
and height
are GRID_CAPACITY_DIM
,
otherwise this function will panic.
sourcepub fn new(&self, width: usize, ov29: OverlayLoadLease<29>) -> Self
pub fn new(&self, width: usize, ov29: OverlayLoadLease<29>) -> Self
Initialize a dungeon grid with defaults.
The grid is an array of grid cells stored in column-major order (!) (such that grid cells with the same x value are stored contiguously (y, x)).
Internally the grid has a fixed buffer size / capacity of 15 x 15. If the grid size in the
X or Y direction is less than this, so when working with the (raw) grid buffer,
you will need to take into account that each column will have 15 rows, where the last
(15-height
) in each column will be uninitialised and that after width
rows
the rest of the array will be uninitialised as well.
This helper will abstract for you over this, if you query a cell via eg. Self::get
,
however Self::into_inner()
ill still return a vector with 15 x 15 cells, with all
missing values initialized with defaults.
width
must be less than or equal to 15, otherwise this function will panic.
sourcepub fn into_inner(self) -> (Vec<DungeonGridCell>, usize, usize)
pub fn into_inner(self) -> (Vec<DungeonGridCell>, usize, usize)
Extract the grid from the mutator, along with its width and height.
The grid will always be a matrix with 15 rows per column and it might contain extra
dangling rows, you need to ignore cells outside of the grid’s actual width and height,
see the notes for Self::new()
for more information.
sourcepub fn get(&self, x: usize, y: usize) -> &DungeonGridCell
pub fn get(&self, x: usize, y: usize) -> &DungeonGridCell
Get the cell at the given coordinates. Panics if the coordinates are out of bounds.
sourcepub unsafe fn get_unchecked(&self, x: usize, y: usize) -> &DungeonGridCell
pub unsafe fn get_unchecked(&self, x: usize, y: usize) -> &DungeonGridCell
Get the cell at the given coordinates, no extra checking is done, just normal slice indexing is done. This is UB if overflow checks are disabled and the coordinates are oob.
Safety
The caller needs to make sure x
and y
are in bounds.
sourcepub fn get_mut(&mut self, x: usize, y: usize) -> &mut DungeonGridCell
pub fn get_mut(&mut self, x: usize, y: usize) -> &mut DungeonGridCell
Get the cell at the given coordinates, mutably. Panics if the coordinates are out of bounds.
sourcepub unsafe fn get_mut_unchecked(
&mut self,
x: usize,
y: usize
) -> &mut DungeonGridCell
pub unsafe fn get_mut_unchecked( &mut self, x: usize, y: usize ) -> &mut DungeonGridCell
Get the cell at the given coordinates, mutable, no extra checking is done, just normal slice indexing is done. This is UB if overflow checks are disabled and the coordinates are oob.
Safety
The caller needs to make sure x
and y
are in bounds.
sourcepub fn merge_rooms_vertically(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
x: i32,
y: i32,
dy: i32
)
pub fn merge_rooms_vertically( &mut self, _dungeon: &mut GlobalDungeonData<'_>, x: i32, y: i32, dy: i32 )
Merges two vertically stacked rooms into one larger room.
Arguments
_dungeon
- Reference to global dungeon struct.x
- x grid coordinate of the rooms to mergey
- y grid coordinate of the rooms to mergedy
- dy, where the lower room has a y grid coordinate of y+dy
sourcepub fn generate_extra_hallways(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
number_extra_hallways: i32
)
pub fn generate_extra_hallways( &mut self, _dungeon: &mut GlobalDungeonData<'_>, number_extra_hallways: i32 )
Generate extra hallways on the floor via a series of random walks.
Each random walk starts from a random tile in a random room, leaves the room in a random cardinal direction, and from there tunnels through obstacles through a series of random turns, leaving open terrain in its wake. The random walk stops when it reaches open terrain, goes out of bounds, or reaches an impassable obstruction.
sourcepub fn get_grid_positions(
width: i32,
height: i32,
_ov29: &OverlayLoadLease<29>
) -> (Vec<i32>, Vec<i32>)
pub fn get_grid_positions( width: i32, height: i32, _ov29: &OverlayLoadLease<29> ) -> (Vec<i32>, Vec<i32>)
Get the grid cell positions for a given set of floor grid dimensions. Width and height must be positive.
sourcepub fn assign_rooms(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
number_rooms: i32
)
pub fn assign_rooms( &mut self, _dungeon: &mut GlobalDungeonData<'_>, number_rooms: i32 )
Randomly selects a subset of grid cells to become rooms.
The given number of grid cells will become rooms. If any of the selected grid cells are invalid, fewer rooms will be generated. The number of rooms assigned will always be at least 2 and never exceed 36.
Cells not marked as rooms will become hallway anchors. A hallway anchor is a single tile in a non-room grid cell to which hallways will be connected later, thus “anchoring” hallway generation.
number_rooms
is the number of rooms; if positive, a random value between
[n_rooms, n_rooms+2] will be used. If negative, |n_rooms| will be used exactly.
sourcepub fn create_rooms_and_anchors(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
starts_x: &mut [i32],
starts_y: &mut [i32],
room_flags: u32
)
pub fn create_rooms_and_anchors( &mut self, _dungeon: &mut GlobalDungeonData<'_>, starts_x: &mut [i32], starts_y: &mut [i32], room_flags: u32 )
Creates rooms and hallway anchors in each grid cell as designated by Self::assign_rooms
.
This function creates a rectangle of open terrain for each room (with some margin relative to the grid cell border). A single open tile is created in hallway anchor cells, and a hallway anchor indicator is set for later reference.
Panics if any start position is invalid.
Arguments
starts_x
- Array of the starting x coordinates of each grid columnstarts_y
- Array of the starting y coordinates of each grid rowroom_flags
- Only uses bit 2 (mask: 0b100), which enables room imperfections
sourcepub fn generate_secondary_structures(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
_number_rooms: i32
)
pub fn generate_secondary_structures( &mut self, _dungeon: &mut GlobalDungeonData<'_>, _number_rooms: i32 )
Try to generate secondary structures in flagged rooms.
If a valid room with no special features is flagged to have a secondary structure, try to generate a random one in the room, based on the result of a dice roll:
0: no secondary structure
1: maze, or a central water/lava "plus sign" as fallback, or a single water/lava tile in
the center as a second fallback
2: checkerboard pattern of water/lava
3: central pool of water/lava
4: central "island" with items and a Warp Tile, surrounded by a "moat" of water/lava
5: horizontal or vertical divider of water/lava splitting the room in two
If the room isn’t the right shape, dimension, or otherwise doesn’t support the selected secondary structure, it is left untouched.
sourcepub fn assign_grid_cell_connections(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
cursor_x: i32,
cursor_y: i32,
floor_properties: &floor_properties
)
pub fn assign_grid_cell_connections( &mut self, _dungeon: &mut GlobalDungeonData<'_>, cursor_x: i32, cursor_y: i32, floor_properties: &floor_properties )
Randomly assigns connections between adjacent grid cells.
Connections are created via a random walk with momentum, starting from the grid cell at (cursor x, cursor y). A connection is drawn in a random direction from the current cursor, and this process is repeated a certain number of times (the “floor connectivity” specified in the floor properties). The direction of the random walk has “momentum”; there’s a 50% chance it will be the same as the previous step (or rotated counterclockwise if on the boundary).
This helps to reduce the number of dead ends and forks in the road caused by the random walk “doubling back” on itself.
If dead ends are disabled in the floor properties, there is an additional phase to remove dead end hallway anchors (only hallway anchors, not rooms) by drawing additional connections. Note that the actual implementation contains a bug: the grid cell validity checks use the wrong index, so connections may be drawn to invalid cells.
Panics if the cursor positions are out of bounds.
sourcepub fn create_grid_cell_connections(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
starts_x: &mut [i32],
starts_y: &mut [i32],
enable_room_merging: bool
)
pub fn create_grid_cell_connections( &mut self, _dungeon: &mut GlobalDungeonData<'_>, starts_x: &mut [i32], starts_y: &mut [i32], enable_room_merging: bool )
Create grid cell connections either by creating hallways or merging rooms.
When creating a hallway connecting a hallway anchor, the exact anchor coordinates are used
as the endpoint. When creating a hallway connecting a room, a random point on the room edge
facing the hallway is used as the endpoint. The grid cell boundaries are used as the middle
coordinates for kinks (see super::GlobalDungeonStructureGenerator::create_hallway
).
If room merging is enabled, there is a 9.75% chance that two connected rooms will be merged into a single larger room (9.75% comes from two 5% rolls, one for each of the two rooms being merged). A room can only participate in a merge once.
sourcepub fn generate_room_imperfections(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>
)
pub fn generate_room_imperfections( &mut self, _dungeon: &mut GlobalDungeonData<'_> )
Attempt to generate room imperfections for each room in the floor layout, if enabled.
Each room has a 40% chance of having imperfections if its grid cell is flagged to allow room imperfections. Imperfections are generated by randomly growing the walls of the room inwards for a certain number of iterations, starting from the corners.
sourcepub fn ensure_connected_grid(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
starts_x: &mut [i32],
starts_y: &mut [i32]
)
pub fn ensure_connected_grid( &mut self, _dungeon: &mut GlobalDungeonData<'_>, starts_x: &mut [i32], starts_y: &mut [i32] )
Ensure the grid forms a connected graph (all valid cells are reachable) by adding hallways to unreachable grid cells.
If a grid cell cannot be connected for some reason, remove it entirely.
sourcepub fn generate_kecleon_shop(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
spawn_chance: u8
)
pub fn generate_kecleon_shop( &mut self, _dungeon: &mut GlobalDungeonData<'_>, spawn_chance: u8 )
A Kecleon shop will be generated with a probability determined by the Kecleon shop spawn chance parameter (percentage from 0 to 100).
A Kecleon shop will be generated in a random room that is valid, connected, has no other special features, and has dimensions of at least 5x4. Kecleon shops will occupy the entire room interior, leaving a one tile margin from the room walls.
sourcepub fn generate_monster_house(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
spawn_chance: u8
)
pub fn generate_monster_house( &mut self, _dungeon: &mut GlobalDungeonData<'_>, spawn_chance: u8 )
A Monster House will be generated with a probability determined by the Monster House spawn chance parameter, and only if the current floor can support one (no non-Monster-House outlaw missions or special floor types). A Monster House will be generated in a random room that is valid, connected, and is not a merged or maze room.
spawn_chance
is the percentage chance that a Monster House will be generated (0-100).
sourcepub fn generate_maze_room(
&mut self,
_dungeon: &mut GlobalDungeonData<'_>,
spawn_chance: u8
)
pub fn generate_maze_room( &mut self, _dungeon: &mut GlobalDungeonData<'_>, spawn_chance: u8 )
Possibly generate a maze room on the floor.
A maze room will be generated with a probability determined by the maze room chance parameter. A maze will be generated in a random room that is valid, connected, has odd dimensions, and has no other features.
spawn_chance
is the percentage chance that a Monster House will be generated (0-100).
sourcepub fn generate_maze<'a>(
&'a self,
cell: &'a mut dungeon_grid_cell,
secondary_terrain_instead_of_walls: bool
)
pub fn generate_maze<'a>( &'a self, cell: &'a mut dungeon_grid_cell, secondary_terrain_instead_of_walls: bool )
Generate a maze room within a given grid cell.
A “maze” is generated within the room using a series of random walks to place obstacle
terrain (walls or secondary terrain) in a maze-like arrangement. “Maze lines”
(see super::GlobalDungeonStructureGenerator::generate_maze_line
) are
generated using every other tile around the room’s border, as well as every other interior
tile, as a starting point.
This ensures that there are stripes of walkable open terrain surrounded by stripes of
obstacles (the maze walls).
sourcepub fn set_spawn_flag_5<'a>(&'a self, cell: &'a mut dungeon_grid_cell)
pub fn set_spawn_flag_5<'a>(&'a self, cell: &'a mut dungeon_grid_cell)
Set spawn flag 5 (0b100000 or 0x20) on all tiles in a room.