1- use std:: { fmt, cmp} ;
2- use rand:: distributions:: WeightedIndex ;
1+ use crate :: error:: Result ;
32use rand:: prelude:: * ;
43use rand:: rngs:: StdRng ;
54use rand:: Rng ;
65use serde:: Serialize ;
7- use crate :: error :: Result ;
6+ use std :: { cmp , fmt } ;
87
98struct BspLevel {
109 level : Level ,
11- map_subsection_min_size : i32 ,
12- map_subsection_min_room_width : i32 ,
13- map_subsection_min_room_height : i32 ,
10+ map_subsection_min_size : usize ,
11+ map_subsection_min_room_width : usize ,
12+ map_subsection_min_room_height : usize ,
1413}
1514
16-
1715byond_fn ! ( fn bsp_generate( width, height, hash, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height) {
1816 bsp_gen( width, height, hash, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height) . ok( )
1917} ) ;
2018
21- fn bsp_gen ( width_as_str : & str ,
19+ fn bsp_gen (
20+ width_as_str : & str ,
2221 height_as_str : & str ,
2322 hash_as_str : & str ,
2423 map_subsection_min_size_as_str : & str ,
2524 map_subsection_min_room_width_as_str : & str ,
26- map_subsection_min_room_height_as_str : & str )
27- -> Result < String > {
25+ map_subsection_min_room_height_as_str : & str ,
26+ ) -> Result < String > {
2827 let default_hash: u64 = rand:: thread_rng ( ) . gen ( ) ;
29- let width = width_as_str. parse :: < i32 > ( ) ?;
30- let height = height_as_str. parse :: < i32 > ( ) ?;
31- let map_subsection_min_room_width = map_subsection_min_room_width_as_str. parse :: < i32 > ( ) ?;
32- let map_subsection_min_room_height = map_subsection_min_room_height_as_str. parse :: < i32 > ( ) ?;
28+ let width = width_as_str. parse :: < usize > ( ) ?;
29+ let height = height_as_str. parse :: < usize > ( ) ?;
30+ let map_subsection_min_room_width = map_subsection_min_room_width_as_str. parse :: < usize > ( ) ?;
31+ let map_subsection_min_room_height = map_subsection_min_room_height_as_str. parse :: < usize > ( ) ?;
3332
33+ //map subsections that the BSP algorithm creates should never be smaller than the minimum desired room size they will contain. This will crash the server
3434 let map_subsection_min_size = cmp:: max (
35- map_subsection_min_size_as_str. parse :: < i32 > ( ) ?,
36- cmp:: max ( map_subsection_min_room_width, map_subsection_min_room_height) + 1
35+ map_subsection_min_size_as_str. parse :: < usize > ( ) ?,
36+ cmp:: max (
37+ map_subsection_min_room_width,
38+ map_subsection_min_room_height,
39+ ) + 1 ,
3740 ) ;
3841
39- //let seed: &str = Alphanumeric.sample_string(&mut rand::thread_rng(), 32).as_str();
40-
41- let mut rng: StdRng = SeedableRng :: seed_from_u64 ( hash_as_str. parse :: < usize > ( ) ?. try_into ( ) . unwrap_or ( default_hash) ) ;
42-
42+ let mut rng: StdRng = SeedableRng :: seed_from_u64 (
43+ hash_as_str
44+ . parse :: < usize > ( ) ?
45+ . try_into ( )
46+ . unwrap_or ( default_hash) ,
47+ ) ;
4348
44- let level = BspLevel :: new ( width, height, & mut rng, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height) ;
49+ let level = BspLevel :: new (
50+ width,
51+ height,
52+ & mut rng,
53+ map_subsection_min_size,
54+ map_subsection_min_room_width,
55+ map_subsection_min_room_height,
56+ ) ;
4557
46- Ok ( serde_json:: to_string ( & level. all_rooms ) ?)
58+ Ok ( serde_json:: to_string ( & level. rooms ) ?)
4759}
4860
4961impl BspLevel {
5062 fn new (
51- width : i32 ,
52- height : i32 ,
63+ width : usize ,
64+ height : usize ,
5365 rng : & mut StdRng ,
54- map_subsection_min_size : i32 ,
55- map_subsection_min_room_width : i32 ,
56- map_subsection_min_room_height : i32 ,
66+ map_subsection_min_size : usize ,
67+ map_subsection_min_room_width : usize ,
68+ map_subsection_min_room_height : usize ,
5769 ) -> Level {
5870 let level = Level :: new ( width, height) ;
5971
60- let mut map = BspLevel { level, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height } ;
72+ let mut map = BspLevel {
73+ level,
74+ map_subsection_min_size,
75+ map_subsection_min_room_width,
76+ map_subsection_min_room_height,
77+ } ;
6178
6279 map. place_rooms ( rng) ;
6380
6481 map. level
6582 }
6683
6784 fn place_rooms ( & mut self , rng : & mut StdRng ) {
68- let mut root = Leaf :: new ( 0 , 0 , self . level . width , self . level . height , self . map_subsection_min_size , self . map_subsection_min_room_width , self . map_subsection_min_room_height ) ;
85+ let mut root = Leaf :: new (
86+ 0 ,
87+ 0 ,
88+ self . level . width ,
89+ self . level . height ,
90+ self . map_subsection_min_size ,
91+ self . map_subsection_min_room_width ,
92+ self . map_subsection_min_room_height ,
93+ ) ;
6994 root. generate ( rng) ;
7095
7196 root. create_rooms ( rng) ;
7297
7398 for leaf in root. iter ( ) {
7499 if leaf. is_leaf ( ) {
75100 if let Some ( room) = leaf. get_room ( ) {
76-
77101 self . level . add_room ( & room) ;
78102 }
79103 }
@@ -82,26 +106,33 @@ impl BspLevel {
82106 self . level . add_room ( & corridor) ;
83107 }
84108 }
85-
86109 }
87110}
88111
89112struct Leaf {
90- min_size : i32 ,
91- x : i32 ,
92- y : i32 ,
93- width : i32 ,
94- height : i32 ,
95- min_room_width : i32 ,
96- min_room_height : i32 ,
113+ min_size : usize ,
114+ x : usize ,
115+ y : usize ,
116+ width : usize ,
117+ height : usize ,
118+ min_room_width : usize ,
119+ min_room_height : usize ,
97120 left_child : Option < Box < Leaf > > ,
98121 right_child : Option < Box < Leaf > > ,
99122 room : Option < Room > ,
100123 corridors : Vec < Room > ,
101124}
102125
103126impl Leaf {
104- fn new ( x : i32 , y : i32 , width : i32 , height : i32 , min_size : i32 , min_room_width : i32 , min_room_height : i32 , ) -> Self {
127+ fn new (
128+ x : usize ,
129+ y : usize ,
130+ width : usize ,
131+ height : usize ,
132+ min_size : usize ,
133+ min_room_width : usize ,
134+ min_room_height : usize ,
135+ ) -> Self {
105136 Leaf {
106137 min_size,
107138 x,
@@ -223,22 +254,15 @@ impl Leaf {
223254 let height = rng. gen_range ( self . min_room_height ..=self . height ) ;
224255 let x = rng. gen_range ( 0 ..=self . width - width) ;
225256 let y = rng. gen_range ( 0 ..=self . height - height) ;
226- let choices = [ 0 , 4 ] ;
227- let weights = [ 1 , 4 ] ;
228- let dist = WeightedIndex :: new ( & weights) . unwrap ( ) ;
229- let mut rng = thread_rng ( ) ;
230- let room_layout = choices[ dist. sample ( & mut rng) ] ;
231257
232258 self . room = Some ( Room :: new (
233- format ! ( "extra room" ) ,
259+ format ! ( "bsp room" ) ,
234260 x + self . x ,
235261 y + self . y ,
236262 width,
237263 height,
238- room_layout,
239264 ) ) ;
240265 }
241-
242266 }
243267
244268 fn get_room ( & self ) -> Option < Room > {
@@ -315,70 +339,67 @@ impl<'a> Iterator for LeafIterator<'a> {
315339 }
316340}
317341
342+ #[ derive( Debug , Clone , Copy ) ]
343+ pub enum TileType {
344+ Space = 0 ,
345+ Floor = 1 ,
346+ Wall = 2 ,
347+ }
318348pub struct Level {
319- width : i32 ,
320- height : i32 ,
321- board : Vec < Vec < i32 > > ,
322- all_rooms : Vec < Room > ,
323- increment : i32 ,
324- //hash: String,
349+ width : usize ,
350+ height : usize ,
351+ board : Vec < Vec < usize > > ,
352+ rooms : Vec < Room > ,
353+ increment : usize ,
325354}
326355
327356impl Level {
328- fn new (
329- width : i32 ,
330- height : i32 ,
331- ) -> Self {
357+ fn new ( width : usize , height : usize ) -> Self {
332358 let mut new_level = Level {
333359 width,
334360 height,
335361 board : Vec :: new ( ) ,
336- all_rooms : Vec :: new ( ) ,
362+ rooms : Vec :: new ( ) ,
337363 increment : 0 ,
338364 } ;
339365 new_level. update_board ( ) ;
340366 new_level
341367 }
342368
343- fn update_board ( & mut self ) -> Vec < Vec < i32 > > {
369+ fn update_board ( & mut self ) -> Vec < Vec < usize > > {
344370 let mut new_board = Vec :: new ( ) ;
345- self . increment += 1 ;
371+ self . increment += 1 ;
346372 for _ in 0 ..self . height {
347- let space_tile = 0 ;
348- //let wall_tile = 1;
349- let floor_tile = 5 ;
350373 let gen_floor_first = true ;
351374
352- let mut row = vec ! [ floor_tile ; self . width as usize ] ;
375+ let mut row = vec ! [ TileType :: Floor as usize ; self . width as usize ] ;
353376 if !gen_floor_first {
354- row = vec ! [ space_tile ; self . width as usize ] ;
377+ row = vec ! [ TileType :: Space as usize ; self . width as usize ] ;
355378 }
356379
357380 new_board. push ( row) ;
358381 }
359- for room in & self . all_rooms {
382+ for room in & self . rooms {
360383 for row in 0 ..room. height {
361384 for col in 0 ..room. width {
362385 let y = ( room. y + row) as usize ;
363386 let x = ( room. x + col) as usize ;
364387 if row == 0 || col == 0 || row == room. height - 1 || col == room. width - 1 {
365388 // might just let byond handle the walls
366- new_board[ y] [ x] = 1 ;
389+ new_board[ y] [ x] = TileType :: Wall as usize ;
367390 } else {
368- new_board[ y] [ x] = room . room_type ;
391+ new_board[ y] [ x] = TileType :: Floor as usize ;
369392 }
370393 }
371394 }
372395 }
373396 self . board = new_board. clone ( ) ;
374- //draw(self, "increments", &self.increment.to_string()).unwrap();
375397 new_board
376398 }
377399
378400 fn add_room ( & mut self , room : & Room ) {
379- self . all_rooms . push ( room. clone ( ) ) ;
401+ self . rooms . push ( room. clone ( ) ) ;
380402 self . update_board ( ) ;
381-
382403 }
383404}
384405
@@ -388,7 +409,7 @@ impl fmt::Display for Level {
388409 for col in 0 ..self . width as usize {
389410 write ! ( f, "{}" , self . board[ row] [ col] ) ?
390411 }
391- // write!(f, "\n")?
412+ write ! ( f, "\n " ) ?
392413 }
393414
394415 Ok ( ( ) )
@@ -397,25 +418,24 @@ impl fmt::Display for Level {
397418
398419#[ derive( Debug , Clone , Copy , Eq , Ord , PartialEq , PartialOrd , Serialize ) ]
399420pub struct Point {
400- x : i32 ,
401- y : i32 ,
421+ x : usize ,
422+ y : usize ,
402423}
403424
404425#[ derive( Clone , Debug , Eq , Ord , PartialEq , PartialOrd , Serialize ) ]
405426pub struct Room {
406427 id : String ,
407- x : i32 ,
408- y : i32 ,
409- x2 : i32 ,
410- y2 : i32 ,
411- width : i32 ,
412- height : i32 ,
428+ x : usize ,
429+ y : usize ,
430+ x2 : usize ,
431+ y2 : usize ,
432+ width : usize ,
433+ height : usize ,
413434 center : Point ,
414- room_type : i32 ,
415435}
416436
417437impl Room {
418- pub fn new ( id : String , x : i32 , y : i32 , width : i32 , height : i32 , room_type : i32 ) -> Self {
438+ pub fn new ( id : String , x : usize , y : usize , width : usize , height : usize ) -> Self {
419439 Room {
420440 id,
421441 x,
@@ -428,14 +448,14 @@ impl Room {
428448 x : x + ( width / 2 ) ,
429449 y : y + ( height / 2 ) ,
430450 } ,
431- room_type,
432451 }
433452 }
434453
435454 pub fn intersects ( & self , other : & Self ) -> bool {
436455 self . x <= other. x2 && self . x2 >= other. x && self . y <= other. y2 && self . y2 >= other. y
437456 }
438- pub fn get_distance_to ( & self , other : & Point ) -> i32 {
439- ( ( ( other. x - self . center . x ) . pow ( 2 ) + ( other. y - self . center . y ) . pow ( 2 ) ) as f64 ) . sqrt ( ) as i32
457+ pub fn get_distance_to ( & self , other : & Point ) -> usize {
458+ ( ( ( other. x - self . center . x ) . pow ( 2 ) + ( other. y - self . center . y ) . pow ( 2 ) ) as f64 ) . sqrt ( )
459+ as usize
440460 }
441461}
0 commit comments