diff --git a/src/generator.h b/src/generator.h index 31c6b17..6c3b8ff 100644 --- a/src/generator.h +++ b/src/generator.h @@ -57,7 +57,7 @@ struct MultiPathCarver void force_to_match(int face); /* Add the next set of platforms (all at z) to the level. */ - void next(struct level *level, num z, num length); + void next(struct level *level, num z, num length, num height=0.0); private: struct Path { @@ -134,6 +134,7 @@ struct AcceleronGenerator: public Generator num generate_ascending_funnel(struct level *level, num z); num generate_tunnel_block(struct level *level, num z, int sections); + num generate_fractured_tunnel(struct level *level, num z, int sections); void change_phase(void); diff --git a/src/generator/gen2.cpp b/src/generator/gen2.cpp index abdbf69..51ded41 100644 --- a/src/generator/gen2.cpp +++ b/src/generator/gen2.cpp @@ -11,6 +11,7 @@ #define P_ASCF_RED num(0.2) #define P_TUNNEL_RED num(0.2) #define P_TUNNEL_RED_RING num(0.15) +#define P_TUNNEL_BLUE num(0.05) AcceleronGenerator::AcceleronGenerator(): m_checkerboard_carver{3} @@ -123,6 +124,16 @@ num AcceleronGenerator::generate_ascending_funnel(struct level *level, num z) return z; } +static platform_type_t tunnel_type(void) +{ + if(num_rand() <= P_TUNNEL_BLUE) + return PLATFORM_BLUE; + else if(num_rand() <= P_TUNNEL_RED) + return PLATFORM_RED; + else + return PLATFORM_WHITE; +} + /* Generates a tunnel block, which is full ring alternating with half rings. The total length (which should be odd) is specified as a parameter. @@ -133,8 +144,8 @@ num AcceleronGenerator::generate_ascending_funnel(struct level *level, num z) ########## [h=0] (...repeats) - There is a random probability for any of the platforms to be red, and also a - random probability for entire rings to be red. */ + There is a random probability for any of the platforms to be red or blue, + and also a random probability for entire rings to be red. */ num AcceleronGenerator::generate_tunnel_block(struct level *level, num z, int sec) @@ -151,7 +162,7 @@ num AcceleronGenerator::generate_tunnel_block(struct level *level, num z, continue; struct platform p; - p.type = (num_rand() <= P_TUNNEL_RED) ? PLATFORM_RED : type; + p.type = (type == PLATFORM_WHITE) ? tunnel_type() : type; p.face = j; p.z = z; p.length = len; @@ -164,6 +175,55 @@ num AcceleronGenerator::generate_tunnel_block(struct level *level, num z, return z; } +/* Generates a fractured tunnel, which is a full ring followed by random-length + platforms varying between 0 and 3 units. This is repeated for as many + sections as requested. + + 0123456789 + ########## [h=0] + ##..###.## [h=0] + ||#.||.#|. + .|..|..|.. + (...repeats) + + There is a random probability for any of the platforms to be red or blue. */ +num AcceleronGenerator::generate_fractured_tunnel(struct level *level, num z, + int sec) +{ + for(int i = 0; i < sec; i++) { + /* Initial ring */ + for(int j = 0; j < PLATFORM_COUNT; j++) { + struct platform p; + p.type = tunnel_type(); + p.face = j; + p.z = z; + p.length = G_PLATFORM_LEN; + p.height = 0; + add(level, p); + } + + /* Fractured ring */ + for(int j = 0; j < PLATFORM_COUNT; j++) { + int start = (num_rand() <= num(0.3)) ? 1 : 0; + int length = rand() % (4 - start); + if(!length) + continue; + + struct platform p; + p.type = tunnel_type(); + p.face = j; + p.z = z + (start + 1) * G_PLATFORM_LEN; + p.length = length * G_PLATFORM_LEN; + p.height = 0; + add(level, p); + } + + z += 4 * G_PLATFORM_LEN; + } + + return z; +} + void AcceleronGenerator::change_phase(void) { static int const freq_table[] = { @@ -253,7 +313,7 @@ void AcceleronGenerator::generate(struct level *level) where you can't side-jump from the middle platform to the left one because the wall prevents it. */ - bool walls = (i == 2 || i == 5 || i == 8 || i == 1); + bool walls = (i == 2 || i == 5 || i == 8 || i == 11); /* Start by excluding platforms from iteration #i */ if(walls) { @@ -265,7 +325,9 @@ void AcceleronGenerator::generate(struct level *level) } /* Advance */ - m_checkerboard_carver.next(level, m_z, G_PLATFORM_LEN); + int height = (i == 13) ? 2 : (i == 12) ? 1 : (i / 3); + m_checkerboard_carver.next(level, m_z, G_PLATFORM_LEN, + height * PLATFORM_HEIGHT_STEP); /* Generate blocks and walls */ if(walls) { @@ -309,21 +371,13 @@ void AcceleronGenerator::generate(struct level *level) /* Phase #4: Incomplete tunnel block */ else if(m_phase == 4) { - // TODO + m_z = this->generate_fractured_tunnel(level, m_z, 3); this->change_phase(); } - /* Phase #1: Almost-full tunnel with random holes? */ - - /* Phase #2: Path with spacing + random onlookers */ - - /* Phase #3: Full + odd + even tunnel combination leading into #0 */ - - - /* Phase #5: Obstacles + /* Phase #5: Fixed obstacles - ##.##.#.#. - .##.##.#.# - ..#..#..#. - .#..#..#.. */ - } diff --git a/src/generator/path.cpp b/src/generator/path.cpp index acd75df..10ff368 100644 --- a/src/generator/path.cpp +++ b/src/generator/path.cpp @@ -89,7 +89,7 @@ void MultiPathCarver::force_to_match(int face) } } -void MultiPathCarver::next(struct level *level, num z, num length) +void MultiPathCarver::next(struct level *level, num z, num length, num height) { /* Decide whether to skip */ for(int i = 0; i < m_N; i++) { @@ -108,7 +108,7 @@ void MultiPathCarver::next(struct level *level, num z, num length) p.face = face; p.z = z; p.length = length; - p.height = 0; + p.height = height; p.type = PLATFORM_WHITE; level->platform_buffer.push_back(p); } diff --git a/src/render.cpp b/src/render.cpp index 0db36fc..66f1e14 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -153,8 +153,10 @@ uint16_t render_platform_color(struct platform const *p, return camera_platform_color(camera, p->face); if(p->type == PLATFORM_BLUE) return render_color_blue_platform(t); - if(p->type == PLATFORM_SEPARATING_WALL || p->type == PLATFORM_BLOCK_TOP) + if(p->type == PLATFORM_SEPARATING_WALL) return RGB24(0x909090); + if(p->type == PLATFORM_BLOCK_TOP) + return RGB24(0xa0a0a0); if(p->type == PLATFORM_BLOCK) return RGB24(0x808080); if(p->type == PLATFORM_RED) {