BosonX/src/generator/gen2.cpp

170 lines
4.1 KiB
C++

#include "../generator.h"
#include "../level.h"
#include "../util.h"
#include <stdlib.h>
/* Geometric parameters */
#define G_PLATFORM_LEN num(2.5)
#define G_PLATFORM_SPC num(0.5)
#define G_PLATFORM_LEN_INITIAL num(6.0)
/* Probabilities */
#define P_ASCF_RED num(0.2)
AcceleronGenerator::AcceleronGenerator():
m_checkerboard_carver{3}
{
srand(123456);
m_initial = true;
m_z = 0.0;
m_phase = 0;
int faces[3] = { 0, 4, 8 };
m_checkerboard_carver.set_faces(faces);
m_checkerboard_carver.set_noskip(true);
m_checkerboard_carver.set_checkerboard(true);
}
/* Generates an ascending funnel up to a long red platform on face #4, in the
following shape.
0123456789
#.#.#.#.#. [h=0]
.#.#.#.#.. [h=1]
..#.#.#... [h=2]
...#.#.... [h=3]
....#..... [h=4]
....##.... [h=5]
...##..... [h=6]
....##.... [h=7]
....R..... [h=8]
....|.....
....|.....
....|.....
...B...... [h=5]
...|.#.... [h=4]
...|.|....
....#..... [h=1]
Returns updated z. */
static num generate_ascending_funnel(struct level *level, num z)
{
/* Ascending funnel */
for(int i = 0; i < 5; i++) {
/* Generate 5-i platforms starting at i, spaced by 2 */
for(int j = 0; j < 5-i; j++) {
struct platform p;
p.type = PLATFORM_WHITE;
p.face = i + 2*j;
p.z = z;
p.length = G_PLATFORM_LEN;
p.height = i;
if(num_rand() <= P_ASCF_RED)
p.type = PLATFORM_RED;
level->platform_buffer.push_back(p);
}
z += G_PLATFORM_LEN + G_PLATFORM_SPC;
}
/* Steps */
for(int i = 0; i < 3; i++) {
struct platform p;
p.type = PLATFORM_WHITE;
p.face = 4;
p.z = z;
p.length = G_PLATFORM_LEN;
p.height = i + 5;
level->platform_buffer.push_back(p);
p.face = (i & 1) ? 3 : 5;
level->platform_buffer.push_back(p);
z += G_PLATFORM_LEN + G_PLATFORM_SPC;
}
/* Overlapping red platform and blue/white neighbors */
struct platform p;
p.type = PLATFORM_RED;
p.face = 4;
p.z = z;
p.length = G_PLATFORM_LEN * 3;
p.height = 8;
level->platform_buffer.push_back(p);
z += G_PLATFORM_LEN * 3 + G_PLATFORM_SPC;
p.type = PLATFORM_BLUE;
p.face = 3;
p.z = z;
p.length = G_PLATFORM_LEN * 3;
p.height = 5;
level->platform_buffer.push_back(p);
p.type = PLATFORM_WHITE;
p.face = 5;
p.z = z + G_PLATFORM_LEN;
p.length = G_PLATFORM_LEN * 2;
p.height = 4;
level->platform_buffer.push_back(p);
z += G_PLATFORM_LEN * 3 + G_PLATFORM_SPC;
/* Exit platform */
p.type = PLATFORM_WHITE;
p.face = 4;
p.z = z;
p.length = G_PLATFORM_LEN;
p.height = 0;
level->platform_buffer.push_back(p);
z += G_PLATFORM_LEN + G_PLATFORM_SPC;
return z;
}
void AcceleronGenerator::generate(struct level *level)
{
/* Friendly platform at start of level */
if(m_initial) {
struct platform p;
p.type = PLATFORM_WHITE;
p.face = 0;
p.z = m_z;
p.length = G_PLATFORM_LEN_INITIAL;
p.height = 0;
level->platform_buffer.push_back(p);
m_z += p.length;
m_initial = false;
}
/* Phase #0: Ascending funnel and long/tight red platform */
if(m_phase == 0) {
m_z = generate_ascending_funnel(level, m_z);
m_checkerboard_carver.force_to_match(4);
m_phase = 1;
}
/* Phase #1: Checkerboard random paths */
else if(m_phase == 1) {
int length = 4 + 2 * (rand() % 2);
for(int i = 0; i < length; i++) {
m_checkerboard_carver.next(level, m_z, G_PLATFORM_LEN);
m_z += G_PLATFORM_LEN + G_PLATFORM_SPC;
}
m_phase = 0;
}
/* 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
- ##.##.#.#.
- .##.##.#.#
- ..#..#..#.
- .#..#..#.. */
}