Add bsp interior
This commit is contained in:
parent
c1893aec74
commit
5a00ebf1f1
8
.idea/.gitignore
vendored
8
.idea/.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
99
.idea/workspace.xml
Normal file
99
.idea/workspace.xml
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="CMakeSettings">
|
||||
<configurations>
|
||||
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" />
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="CargoProjects">
|
||||
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="a9f5cad0-d253-42e8-a38a-89dfec417dbc" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/src/map_builders/bsp/mod.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/map_builders/bsp_interior.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/components.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/map_builders/bsp_dungeon.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/map_builders/bsp_dungeon.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/map_builders/common.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/map_builders/common.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/map_builders/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/map_builders/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/map_builders/simple_map.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/map_builders/simple_map.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/spawner.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/spawner.rs" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ClangdSettings">
|
||||
<option name="formatViaClangd" value="false" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="GitSEFilterConfiguration">
|
||||
<file-type-list>
|
||||
<filtered-out-file-type name="LOCAL_BRANCH" />
|
||||
<filtered-out-file-type name="REMOTE_BRANCH" />
|
||||
<filtered-out-file-type name="TAG" />
|
||||
<filtered-out-file-type name="COMMIT_BY_MESSAGE" />
|
||||
</file-type-list>
|
||||
</component>
|
||||
<component name="MacroExpansionManager">
|
||||
<option name="directoryName" value="7zted9t8" />
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectId" id="24PyiDwZbQQQ0gzNvMewyQ4Zryi" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="RunOnceActivity.cidr.known.project.marker" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="cf.first.check.clang-format" value="false" />
|
||||
<property name="cidr.known.project.marker" value="true" />
|
||||
<property name="node.js.detected.package.eslint" value="true" />
|
||||
<property name="node.js.detected.package.tslint" value="true" />
|
||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
||||
<property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
|
||||
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.project.grazie" />
|
||||
</component>
|
||||
<component name="RustProjectSettings">
|
||||
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="a9f5cad0-d253-42e8-a38a-89dfec417dbc" name="Changes" comment="" />
|
||||
<created>1643546643557</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1643546643557</updated>
|
||||
<workItem from="1643546645546" duration="2136000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
<option name="TAB_STATES">
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
File diff suppressed because one or more lines are too long
@ -11,6 +11,23 @@ pub struct Position {
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
impl Position {
|
||||
pub fn new(x: i32, y: i32) -> Self {
|
||||
Self {
|
||||
x, y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Position {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, ConvertSaveload, Clone)]
|
||||
pub struct Renderable {
|
||||
pub glyph: rltk::FontCharType,
|
||||
|
22
src/map_builders/bsp/mod.rs
Normal file
22
src/map_builders/bsp/mod.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{Map, TileType};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn draw_corridor(map: &mut Map, x1: i32, y1: i32, x2: i32, y2: i32) {
|
||||
let mut x = x1;
|
||||
let mut y = y1;
|
||||
|
||||
while x != x2 || y != y2 {
|
||||
if x < x2 {
|
||||
x += 1;
|
||||
} else if x > x2 {
|
||||
x -= 1;
|
||||
} else if y < y2 {
|
||||
y += 1;
|
||||
} else if y > y2 {
|
||||
y -= 1;
|
||||
}
|
||||
|
||||
let idx = map.xy_idx(x, y);
|
||||
map.tiles[idx] = TileType::Floor;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use rltk::{Point, RandomNumberGenerator};
|
||||
|
||||
use crate::map_builders::common::apply_room_to_map;
|
||||
use crate::map_builders::MapBuilder;
|
||||
use crate::map_builders::{bsp, MapBuilder};
|
||||
use crate::rect::Rect;
|
||||
use crate::{spawner, Map, Position, TileType, World, SHOW_MAPGEN_VISUALIZER};
|
||||
|
||||
@ -175,23 +175,7 @@ impl BspDungeonBuilder {
|
||||
can_build
|
||||
}
|
||||
fn draw_corridor(&mut self, x1: i32, y1: i32, x2: i32, y2: i32) {
|
||||
let mut x = x1;
|
||||
let mut y = y1;
|
||||
|
||||
while x != x2 || y != y2 {
|
||||
if x < x2 {
|
||||
x += 1;
|
||||
} else if x > x2 {
|
||||
x -= 1;
|
||||
} else if y < y2 {
|
||||
y += 1;
|
||||
} else if y > y2 {
|
||||
y -= 1;
|
||||
}
|
||||
|
||||
let idx = self.map.xy_idx(x, y);
|
||||
self.map.tiles[idx] = TileType::Floor;
|
||||
}
|
||||
bsp::draw_corridor(&mut self.map, x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +186,7 @@ impl MapBuilder for BspDungeonBuilder {
|
||||
|
||||
fn spawn_entities(&mut self, ecs: &mut World) {
|
||||
for room in self.rooms.iter().skip(1) {
|
||||
spawner::spawn_room(ecs, room, self.depth);
|
||||
spawner::spawn_room(ecs, room, self.depth, &self.map);
|
||||
}
|
||||
}
|
||||
|
||||
|
157
src/map_builders/bsp_interior.rs
Normal file
157
src/map_builders/bsp_interior.rs
Normal file
@ -0,0 +1,157 @@
|
||||
use rltk::RandomNumberGenerator;
|
||||
use crate::{Map, Position, SHOW_MAPGEN_VISUALIZER, spawner, TileType, World};
|
||||
use crate::map_builders::common::reveal_all;
|
||||
use crate::map_builders::{bsp, MapBuilder};
|
||||
use crate::rect::Rect;
|
||||
|
||||
const MIN_ROOM_SIZE : i32 = 8;
|
||||
|
||||
pub struct BspInteriorBuilder {
|
||||
map: Map,
|
||||
starting_position: Position,
|
||||
depth: i32,
|
||||
rooms: Vec<Rect>,
|
||||
history: Vec<Map>,
|
||||
rects: Vec<Rect>,
|
||||
}
|
||||
|
||||
impl BspInteriorBuilder {
|
||||
pub fn new(new_depth: i32) -> Self{
|
||||
Self {
|
||||
map: Map::new(new_depth),
|
||||
rects: Vec::new(),
|
||||
history:Vec::new(),
|
||||
depth: new_depth,
|
||||
rooms: Vec::new(),
|
||||
starting_position: Position::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn build(&mut self) {
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
|
||||
self.place_rooms(&mut rng);
|
||||
self.place_corridors(&mut rng);
|
||||
self.place_stairs();
|
||||
self.place_start()
|
||||
}
|
||||
|
||||
fn place_start(&mut self) {
|
||||
let start = self.rooms[0].center();
|
||||
self.starting_position = Position::new(start.0, start.1)
|
||||
}
|
||||
|
||||
fn place_stairs(&mut self) {
|
||||
let stairs = self.rooms[self.rooms.len() - 1].center();
|
||||
let stairs_idx = self.map.xy_idx(stairs.0, stairs.1);
|
||||
self.map.tiles[stairs_idx] = TileType::DownStairs;
|
||||
}
|
||||
|
||||
fn place_corridors(&mut self, rng: &mut RandomNumberGenerator) {
|
||||
for i in 0..self.rooms.len() - 1 {
|
||||
let room = self.rooms[i];
|
||||
let next_room = self.rooms[i + 1];
|
||||
let start_x = room.x1 + (rng.roll_dice(1, i32::abs(room.x1 - room.x2)) - 1);
|
||||
let start_y = room.y1 + (rng.roll_dice(1, i32::abs(room.y1 - room.y2)) - 1);
|
||||
let end_x = next_room.x1 + (rng.roll_dice(1, i32::abs(next_room.x1 - next_room.x2)) - 1);
|
||||
let end_y = next_room.y1 + (rng.roll_dice(1, i32::abs(next_room.y1 - next_room.y2)) - 1);
|
||||
self.draw_corridor(start_x, start_y, end_x, end_y);
|
||||
self.take_snapshot();
|
||||
}
|
||||
}
|
||||
|
||||
fn place_rooms(&mut self, mut rng: &mut RandomNumberGenerator) {
|
||||
self.rects.clear();
|
||||
self.rects.push(Rect::new(1, 1, self.map.width - 2, self.map.height - 2));
|
||||
let first_room = self.rects[0];
|
||||
self.add_subrects(first_room, &mut rng);
|
||||
|
||||
let rooms = self.rects.clone();
|
||||
for r in rooms.iter() {
|
||||
let room = *r;
|
||||
self.rooms.push(room);
|
||||
for y in room.y1..room.y2 {
|
||||
for x in room.x1..room.x2 {
|
||||
let idx = self.map.xy_idx(x, y);
|
||||
if idx > 0 && idx < ((self.map.width * self.map.height) - 1) as usize {
|
||||
self.map.tiles[idx] = TileType::Floor;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.take_snapshot();
|
||||
}
|
||||
}
|
||||
|
||||
fn add_subrects(&mut self, rect: Rect, rng: &mut RandomNumberGenerator) {
|
||||
if !self.rects.is_empty() {
|
||||
self.rects.remove(self.rects.len() - 1);
|
||||
}
|
||||
|
||||
let width = rect.x2 - rect.x1;
|
||||
let height = rect.y2 - rect.y1;
|
||||
let half_width = width / 2;
|
||||
let half_height = height / 2;
|
||||
|
||||
let split = rng.roll_dice(1, 4);
|
||||
|
||||
if split <= 2 {
|
||||
let h1 = Rect::new(rect.x1, rect.y1, half_width -1, height);
|
||||
self.rects.push(h1);
|
||||
if half_width > MIN_ROOM_SIZE {
|
||||
self.add_subrects(h1, rng);
|
||||
}
|
||||
let h2 = Rect::new(rect.x1 + half_width, rect.y1, half_width, height);
|
||||
self.rects.push(h2);
|
||||
if half_width > MIN_ROOM_SIZE {
|
||||
self.add_subrects(h2, rng);
|
||||
}
|
||||
}else {
|
||||
let v1 = Rect::new(rect.x1, rect.y1, width , half_height - 1);
|
||||
self.rects.push(v1);
|
||||
if half_height > MIN_ROOM_SIZE {
|
||||
self.add_subrects(v1, rng);
|
||||
}
|
||||
let v2 = Rect::new(rect.x1 , rect.y1 + half_height, width, half_height);
|
||||
self.rects.push(v2);
|
||||
if half_height > MIN_ROOM_SIZE {
|
||||
self.add_subrects(v2, rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_corridor(&mut self, x1: i32, y1: i32, x2: i32, y2: i32) {
|
||||
bsp::draw_corridor(&mut self.map, x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
impl MapBuilder for BspInteriorBuilder {
|
||||
fn build_map(&mut self) {
|
||||
self.build();
|
||||
}
|
||||
|
||||
fn spawn_entities(&mut self, ecs: &mut World) {
|
||||
for room in self.rooms.iter().skip(1) {
|
||||
spawner::spawn_room(ecs, room, self.depth, &self.map);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_map(&self) -> Map {
|
||||
self.map.clone()
|
||||
}
|
||||
|
||||
fn get_starting_position(&self) -> Position {
|
||||
self.starting_position.clone()
|
||||
}
|
||||
|
||||
fn get_snapshot_history(&self) -> Vec<Map> {
|
||||
self.history.clone()
|
||||
}
|
||||
|
||||
fn take_snapshot(&mut self) {
|
||||
if SHOW_MAPGEN_VISUALIZER {
|
||||
self.history.push(reveal_all(&self.map));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,3 +29,11 @@ pub fn apply_vertical_tunnel(map: &mut Map, y1: i32, y2: i32, x: i32) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reveal_all(map: &Map) -> Map {
|
||||
let mut snapshot = map.clone();
|
||||
for v in snapshot.revealed_tiles.iter_mut() {
|
||||
*v = true;
|
||||
}
|
||||
snapshot
|
||||
}
|
||||
|
@ -3,8 +3,11 @@ use specs::World;
|
||||
use crate::map_builders::bsp_dungeon::BspDungeonBuilder;
|
||||
use crate::map_builders::simple_map::SimpleMapBuilder;
|
||||
use crate::{Map, Position};
|
||||
use crate::map_builders::bsp_interior::BspInteriorBuilder;
|
||||
|
||||
mod bsp;
|
||||
mod bsp_dungeon;
|
||||
mod bsp_interior;
|
||||
mod common;
|
||||
mod simple_map;
|
||||
|
||||
@ -19,8 +22,10 @@ pub trait MapBuilder {
|
||||
|
||||
pub fn new_random_builder(new_depth: i32) -> Box<dyn MapBuilder> {
|
||||
let mut rng = rltk::RandomNumberGenerator::new();
|
||||
let builder_choice = rng.roll_dice(1, 2);
|
||||
//let builder_choice = rng.roll_dice(1, 3);
|
||||
let builder_choice = 2;
|
||||
match builder_choice {
|
||||
2 => Box::new(BspInteriorBuilder::new(new_depth)),
|
||||
1 => Box::new(SimpleMapBuilder::new(new_depth)),
|
||||
_ => Box::new(BspDungeonBuilder::new(new_depth)),
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ impl MapBuilder for SimpleMapBuilder {
|
||||
|
||||
fn spawn_entities(&mut self, ecs: &mut World) {
|
||||
for room in self.rooms.iter().skip(1) {
|
||||
spawner::spawn_room(ecs, room, self.depth);
|
||||
spawner::spawn_room(ecs, room, self.depth, &self.map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,12 +6,7 @@ use specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
|
||||
use crate::random_table::RandomTable;
|
||||
use crate::rect::Rect;
|
||||
use crate::{
|
||||
AreaOfEffect, BlocksTile, CombatStats, Confusion, Consumable, DefenseBonus, EntryTrigger,
|
||||
EquipmentSlot, Equippable, Hidden, HungerClock, HungerState, InflictsDamage, Item, MagicMapper,
|
||||
MeleePowerBonus, Monster, Name, Player, Position, ProvidesFood, ProvidesHealing, Ranged,
|
||||
Renderable, SerializeMe, SingleActivation, Viewshed, MAP_WIDTH, MAX_MONSTER,
|
||||
};
|
||||
use crate::{AreaOfEffect, BlocksTile, CombatStats, Confusion, Consumable, DefenseBonus, EntryTrigger, EquipmentSlot, Equippable, Hidden, HungerClock, HungerState, InflictsDamage, Item, MagicMapper, MeleePowerBonus, Monster, Name, Player, Position, ProvidesFood, ProvidesHealing, Ranged, Renderable, SerializeMe, SingleActivation, Viewshed, MAP_WIDTH, MAX_MONSTER, Map, TileType};
|
||||
|
||||
pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
||||
ecs.create_entity()
|
||||
@ -86,7 +81,7 @@ fn monster<S: ToString>(ecs: &mut World, x: i32, y: i32, glyph: FontCharType, na
|
||||
}
|
||||
|
||||
#[allow(clippy::map_entry)]
|
||||
pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32) {
|
||||
pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32, map: &Map) {
|
||||
let spawn_table = room_table(map_depth);
|
||||
let mut spawn_points: HashMap<usize, String> = HashMap::new();
|
||||
|
||||
@ -101,7 +96,7 @@ pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32) {
|
||||
let x = (room.x1 + rng.roll_dice(1, i32::abs(room.x2 - room.x1))) as usize;
|
||||
let y = (room.y1 + rng.roll_dice(1, i32::abs(room.y2 - room.y1))) as usize;
|
||||
let idx = (y * MAP_WIDTH) + x;
|
||||
if !spawn_points.contains_key(&idx) {
|
||||
if !spawn_points.contains_key(&idx) && map.tiles[idx] != TileType::Wall {
|
||||
spawn_points.insert(idx, spawn_table.roll(&mut rng));
|
||||
added = true;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user