BosonX/src/generator/path.cpp

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);
}
}