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