126 lines
2.7 KiB
C++
126 lines
2.7 KiB
C++
#include "../generator.h"
|
|
#include "../level.h"
|
|
|
|
path_carver::path_carver(int initial_face)
|
|
{
|
|
m_face = initial_face;
|
|
m_last_skipped = true;
|
|
m_z = num(0);
|
|
}
|
|
|
|
bool path_carver::next(num length, struct platform *p, bool force)
|
|
{
|
|
int skip = !force && !m_last_skipped && (rand() % 4 == 0);
|
|
|
|
if(skip) {
|
|
m_last_skipped = true;
|
|
m_z += length;
|
|
return false;
|
|
}
|
|
else {
|
|
p->face = m_face;
|
|
p->z = m_z;
|
|
p->length = length;
|
|
p->type = PLATFORM_WHITE;
|
|
p->height = 0;
|
|
|
|
int diff = rand() % 3 - 1;
|
|
m_face = (m_face + PLATFORM_COUNT + diff) % PLATFORM_COUNT;
|
|
m_z += length;
|
|
m_last_skipped = false;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void path_carver::teleport(num z)
|
|
{
|
|
m_z = z;
|
|
}
|
|
|
|
//~
|
|
|
|
MultiPathCarver::MultiPathCarver(int N)
|
|
{
|
|
m_N = N;
|
|
m_paths = new Path[m_N];
|
|
m_noskip = false;
|
|
m_checkerboard = false;
|
|
|
|
for(int i = 0; i < m_N; i++)
|
|
m_paths[i].last_skipped = false;
|
|
}
|
|
|
|
MultiPathCarver::~MultiPathCarver()
|
|
{
|
|
delete[] m_paths;
|
|
}
|
|
|
|
void MultiPathCarver::set_faces(int const *faces)
|
|
{
|
|
for(int i = 0; i < m_N; i++)
|
|
m_paths[i].face = faces[i];
|
|
}
|
|
|
|
void MultiPathCarver::get_faces(int *faces)
|
|
{
|
|
for(int i = 0; i < m_N; i++) {
|
|
faces[i] = m_paths[i].face;
|
|
}
|
|
}
|
|
|
|
void MultiPathCarver::set_noskip(bool noskip)
|
|
{
|
|
m_noskip = noskip;
|
|
}
|
|
|
|
void MultiPathCarver::set_checkerboard(bool checkerboard)
|
|
{
|
|
m_checkerboard = checkerboard;
|
|
}
|
|
|
|
void MultiPathCarver::force_to_match(int face)
|
|
{
|
|
if(m_N <= 0)
|
|
return;
|
|
|
|
int diff = face - m_paths[0].face;
|
|
for(int i = 0; i < m_N; i++) {
|
|
m_paths[i].face = add_to_face(m_paths[i].face, diff);
|
|
}
|
|
}
|
|
|
|
void MultiPathCarver::next(struct level *level, num z, num length)
|
|
{
|
|
/* Decide whether to skip */
|
|
for(int i = 0; i < m_N; i++) {
|
|
bool skip = !m_noskip && !m_paths[i].last_skipped && (rand() % 4 == 0);
|
|
m_paths[i].last_skipped = skip;
|
|
}
|
|
|
|
/* Generate platforms for the current positions */
|
|
for(int face = 0; face < PLATFORM_COUNT; face++) {
|
|
bool is_hit = false;
|
|
for(int i = 0; i < m_N; i++)
|
|
is_hit |= (!m_paths[i].last_skipped && m_paths[i].face == face);
|
|
|
|
if(is_hit) {
|
|
struct platform p;
|
|
p.face = face;
|
|
p.z = z;
|
|
p.length = length;
|
|
p.height = 0;
|
|
p.type = PLATFORM_WHITE;
|
|
level->platform_buffer.push_back(p);
|
|
}
|
|
}
|
|
|
|
/* Advance positions */
|
|
for(int i = 0; i < m_N; i++) {
|
|
/* In checkerboard mode, only allow diff -1/+1 instead of -1/0/+1 */
|
|
int diff = m_checkerboard
|
|
? 2 * (rand() % 2) - 1
|
|
: rand() % 3 - 1;
|
|
m_paths[i].face = add_to_face(m_paths[i].face, diff);
|
|
}
|
|
}
|