mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-01 03:46:16 +00:00
Bringris 1.3
This commit is contained in:
parent
9f5da212a7
commit
50474abae1
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#ifdef BRINGRIS
|
#ifdef BRINGRIS
|
||||||
|
|
||||||
#define CUSTOM_CAPTION "Bringris 1.2"
|
#define CUSTOM_CAPTION "Bringris 1.3"
|
||||||
|
|
||||||
#define MAXMDIM 4
|
#define MAXMDIM 4
|
||||||
|
|
||||||
@ -41,6 +41,9 @@
|
|||||||
#else
|
#else
|
||||||
#include "../hyper.cpp"
|
#include "../hyper.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "subquotient.cpp"
|
||||||
|
#define SUBQ
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../hyper.h"
|
#include "../hyper.h"
|
||||||
@ -49,11 +52,19 @@
|
|||||||
|
|
||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
|
namespace subquotient {
|
||||||
|
#ifndef SUBQ
|
||||||
|
void create_subquotient(int qty = -1, int id = 0);
|
||||||
|
#endif
|
||||||
|
extern eGeometry gSubquotient;
|
||||||
|
}
|
||||||
|
|
||||||
namespace bringris {
|
namespace bringris {
|
||||||
|
|
||||||
struct bgeometry {
|
struct bgeometry {
|
||||||
string name;
|
string name;
|
||||||
string cap;
|
string cap;
|
||||||
|
flagtype flags;
|
||||||
reaction_t create;
|
reaction_t create;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,6 +95,8 @@ vector<cell*> level;
|
|||||||
|
|
||||||
vector<cell*> out_level;
|
vector<cell*> out_level;
|
||||||
|
|
||||||
|
map<cell*, int> center_distance;
|
||||||
|
|
||||||
bool pro_game;
|
bool pro_game;
|
||||||
|
|
||||||
int well_size = 10;
|
int well_size = 10;
|
||||||
@ -114,8 +127,25 @@ enum eState {
|
|||||||
|
|
||||||
eState state = tsPreGame;
|
eState state = tsPreGame;
|
||||||
|
|
||||||
|
constexpr flagtype HYPERBOLIC = 1;
|
||||||
|
constexpr flagtype ORBIFOLD = 2;
|
||||||
|
constexpr flagtype SECRET = 4;
|
||||||
|
constexpr flagtype NONORIENTABLE = 8;
|
||||||
|
constexpr flagtype SPHERICAL = 16;
|
||||||
|
constexpr flagtype EUCLIDEAN = 32;
|
||||||
|
constexpr flagtype SUBQUOTIENT = 64;
|
||||||
|
constexpr flagtype HDUAL = 128;
|
||||||
|
constexpr flagtype BOUNDED_WELL = 256;
|
||||||
|
constexpr flagtype ASYMMETRIC_ONLY = 512;
|
||||||
|
constexpr flagtype FLAT_ONLY = 1024;
|
||||||
|
|
||||||
|
cell *get_center();
|
||||||
|
cell *shift_block_target(int dir);
|
||||||
|
void shift_block(int dir, bool camera_only = false);
|
||||||
|
void rotate_block(int dir, bool camera_only = false);
|
||||||
|
|
||||||
vector<bgeometry> bgeoms = {
|
vector<bgeometry> bgeoms = {
|
||||||
{"Bring surface", "the original Bringris geometry", [] {
|
{"Bring surface", "the original Bringris geometry", HYPERBOLIC, [] {
|
||||||
using namespace fieldpattern;
|
using namespace fieldpattern;
|
||||||
current_extra = 2;
|
current_extra = 2;
|
||||||
auto& gxcur = fgeomextras[current_extra];
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
@ -132,7 +162,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"torus", "Euclidean level geometry", [] {
|
{"torus", "Euclidean level geometry", EUCLIDEAN, [] {
|
||||||
auto& T0 = euc::eu_input.user_axes;
|
auto& T0 = euc::eu_input.user_axes;
|
||||||
T0[0][0] = 5;
|
T0[0][0] = 5;
|
||||||
T0[0][1] = 0;
|
T0[0][1] = 0;
|
||||||
@ -146,7 +176,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = true;
|
rotate_allowed = true;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"Cube", "spherical level geometry", [] {
|
{"Cube", "spherical level geometry", SPHERICAL, [] {
|
||||||
set_geometry(gSmallSphere);
|
set_geometry(gSmallSphere);
|
||||||
set_variation(eVariation::pure);
|
set_variation(eVariation::pure);
|
||||||
set_geometry(gProduct);
|
set_geometry(gProduct);
|
||||||
@ -154,7 +184,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"Klein bottle", "non-orientable manifold", [] {
|
{"Klein bottle", "non-orientable manifold", EUCLIDEAN | NONORIENTABLE, [] {
|
||||||
auto& T0 = euc::eu_input.user_axes;
|
auto& T0 = euc::eu_input.user_axes;
|
||||||
T0[0][0] = 5;
|
T0[0][0] = 5;
|
||||||
T0[0][1] = 0;
|
T0[0][1] = 0;
|
||||||
@ -168,7 +198,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = true;
|
rotate_allowed = true;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"pentagons", "different tiles on the Bring surface", [] {
|
{"pentagons", "different tiles on the Bring surface", HYPERBOLIC | HDUAL, [] {
|
||||||
using namespace fieldpattern;
|
using namespace fieldpattern;
|
||||||
current_extra = 2;
|
current_extra = 2;
|
||||||
auto& gxcur = fgeomextras[current_extra];
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
@ -182,7 +212,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"double cube", "six squares around a vertex", [] {
|
{"double cube", "six squares around a vertex", HYPERBOLIC, [] {
|
||||||
using namespace fieldpattern;
|
using namespace fieldpattern;
|
||||||
current_extra = 3;
|
current_extra = 3;
|
||||||
auto& gxcur = fgeomextras[current_extra];
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
@ -199,7 +229,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = true;
|
rotate_allowed = true;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"30/6", "six squares around a vertex", [] {
|
{"30/6", "six squares around a vertex", HYPERBOLIC, [] {
|
||||||
using namespace fieldpattern;
|
using namespace fieldpattern;
|
||||||
current_extra = 3;
|
current_extra = 3;
|
||||||
auto& gxcur = fgeomextras[current_extra];
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
@ -216,7 +246,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = true;
|
rotate_allowed = true;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"42", "seven squares around a vertex", [] {
|
{"42", "seven squares around a vertex", HYPERBOLIC, [] {
|
||||||
using namespace fieldpattern;
|
using namespace fieldpattern;
|
||||||
current_extra = 4;
|
current_extra = 4;
|
||||||
auto& gxcur = fgeomextras[current_extra];
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
@ -233,7 +263,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"bounded well", "five squares around a vertex", [] {
|
{"bounded well", "five squares around a vertex", BOUNDED_WELL, [] {
|
||||||
set_geometry(g45);
|
set_geometry(g45);
|
||||||
gp::param = gp::loc(1, 1);
|
gp::param = gp::loc(1, 1);
|
||||||
set_variation(eVariation::unrectified);
|
set_variation(eVariation::unrectified);
|
||||||
@ -243,7 +273,18 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"giant", "like Bring's but much larger", [] {
|
{"mirrored Bring", "hyperbolic and non-orientable", HYPERBOLIC | NONORIENTABLE | ASYMMETRIC_ONLY, [] {
|
||||||
|
set_geometry(gBring);
|
||||||
|
gp::param = gp::loc(1, 1);
|
||||||
|
set_variation(eVariation::unrectified);
|
||||||
|
start_game();
|
||||||
|
subquotient::create_subquotient(2);
|
||||||
|
set_geometry(gProduct);
|
||||||
|
max_piece = 4;
|
||||||
|
rotate_allowed = false;
|
||||||
|
}},
|
||||||
|
|
||||||
|
{"giant", "like mirrored Bring but much larger", HYPERBOLIC | NONORIENTABLE, [] {
|
||||||
using namespace fieldpattern;
|
using namespace fieldpattern;
|
||||||
current_extra = 2;
|
current_extra = 2;
|
||||||
auto& gxcur = fgeomextras[current_extra];
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
@ -254,14 +295,33 @@ vector<bgeometry> bgeoms = {
|
|||||||
|
|
||||||
gp::param = gp::loc(1, 1);
|
gp::param = gp::loc(1, 1);
|
||||||
set_variation(eVariation::unrectified);
|
set_variation(eVariation::unrectified);
|
||||||
|
subquotient::create_subquotient(2);
|
||||||
|
|
||||||
set_geometry(gProduct);
|
set_geometry(gProduct);
|
||||||
max_piece = 5;
|
max_piece = 5;
|
||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
well_size = 5;
|
well_size = 6;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"torus: shear", "Nil geometry: are you sure you want this?", [] {
|
{"orbifold", "one fifth of the giant", HYPERBOLIC | NONORIENTABLE | ORBIFOLD, [] {
|
||||||
|
using namespace fieldpattern;
|
||||||
|
current_extra = 2;
|
||||||
|
auto& gxcur = fgeomextras[current_extra];
|
||||||
|
while(isize(gxcur.primes) < 1) nextPrime(gxcur);
|
||||||
|
fgeomextras[current_extra].current_prime_id = 1;
|
||||||
|
enableFieldChange();
|
||||||
|
set_geometry(gFieldQuotient);
|
||||||
|
|
||||||
|
gp::param = gp::loc(1, 1);
|
||||||
|
set_variation(eVariation::unrectified);
|
||||||
|
subquotient::create_subquotient(10);
|
||||||
|
|
||||||
|
set_geometry(gProduct);
|
||||||
|
max_piece = 4;
|
||||||
|
rotate_allowed = false;
|
||||||
|
}},
|
||||||
|
|
||||||
|
{"torus: shear", "Nil geometry: are you sure you want this?", SECRET, [] {
|
||||||
nilv::nilperiod = make_array(5, 0, 5);
|
nilv::nilperiod = make_array(5, 0, 5);
|
||||||
// nilv::set_flags();
|
// nilv::set_flags();
|
||||||
set_geometry(gNil);
|
set_geometry(gNil);
|
||||||
@ -269,7 +329,8 @@ vector<bgeometry> bgeoms = {
|
|||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"torus: Arnold's Cat", "Solv geometry: flat shapes are crazy enough", [] {
|
#if CAP_SOLV
|
||||||
|
{"torus: Arnold's Cat", "Solv geometry: flat shapes are crazy enough", SECRET | FLAT_ONLY, [] {
|
||||||
asonov::period_xy = 5;
|
asonov::period_xy = 5;
|
||||||
asonov::period_z = 0;
|
asonov::period_z = 0;
|
||||||
asonov::set_flags();
|
asonov::set_flags();
|
||||||
@ -277,6 +338,7 @@ vector<bgeometry> bgeoms = {
|
|||||||
max_piece = 2;
|
max_piece = 2;
|
||||||
rotate_allowed = false;
|
rotate_allowed = false;
|
||||||
}},
|
}},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void create_game();
|
void create_game();
|
||||||
@ -295,6 +357,8 @@ void enable_bgeom(int b) {
|
|||||||
enable_bgeom();
|
enable_bgeom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flagtype bflags() { return bgeoms[bgeom].flags; }
|
||||||
|
|
||||||
using code_t = vector<pair<int, int>>;
|
using code_t = vector<pair<int, int>>;
|
||||||
|
|
||||||
struct piecedata {
|
struct piecedata {
|
||||||
@ -380,6 +444,20 @@ cellwalker flatspin(cellwalker cw, int i) {
|
|||||||
return cw;
|
return cw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int add_dir(cellwalker orig, int i, int sym = 0) {
|
||||||
|
if(prod) {
|
||||||
|
if(i >= orig.at->type-2) {
|
||||||
|
if(sym&2) i ^= (orig.at->type-1) ^ (orig.at->type-2);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(sym&1) i = -i;
|
||||||
|
return flatspin(orig, i).spin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
cellwalker add(cellwalker orig, int i, int sym = 0) {
|
cellwalker add(cellwalker orig, int i, int sym = 0) {
|
||||||
if(prod) {
|
if(prod) {
|
||||||
if(i >= orig.at->type-2) {
|
if(i >= orig.at->type-2) {
|
||||||
@ -402,21 +480,14 @@ vector<cellwalker> build_from(const code_t& code, cellwalker start, int sym = 0)
|
|||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<transmatrix> build_shape_matrices(const vector<cellwalker>& cells) {
|
vector<transmatrix> build_shape_matrices(const code_t& code, cellwalker start, int sym = 0) {
|
||||||
vector<transmatrix> all = {Id};
|
vector<cellwalker> all = {start};
|
||||||
all.reserve(isize(cells));
|
vector<transmatrix> allm = {Id};
|
||||||
for(int i=1; i<isize(cells); i++) {
|
for(auto c: code) {
|
||||||
for(int j=0; j<i; j++) {
|
all.push_back(add(all[c.first], c.second, sym));
|
||||||
int nei = neighborId(cells[j].at, cells[i].at);
|
allm.push_back(allm[c.first] * currentmap->adj(all[c.first].at, add_dir(all[c.first], c.second, sym)));
|
||||||
if(nei != -1) {
|
|
||||||
transmatrix T = all[j];
|
|
||||||
T = T * currentmap->adj(cells[j].at, nei);
|
|
||||||
all.push_back(T);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return all;
|
return allm;
|
||||||
}
|
}
|
||||||
|
|
||||||
int penalty(const vector<cellwalker>& shape, const code_t& code) {
|
int penalty(const vector<cellwalker>& shape, const code_t& code) {
|
||||||
@ -477,7 +548,13 @@ void generate_shapes_rec(vector<cellwalker>& sofar, code_t& code, int cnt) {
|
|||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
int syms = 0;
|
int syms = 0;
|
||||||
for(int i: {0,1,2,3}) if(builds(sofar, code, i)) syms++;
|
bool invalid = false;
|
||||||
|
for(int i: {0,1,2,3}) if(builds(sofar, code, i)) {
|
||||||
|
syms++;
|
||||||
|
if((bflags() & ASYMMETRIC_ONLY) && i == 1 && cnt >= 4)
|
||||||
|
invalid = true;
|
||||||
|
}
|
||||||
|
if(invalid) return;
|
||||||
bool vertical = true;
|
bool vertical = true;
|
||||||
for(auto c: code) if(c.second < 4) vertical = false;
|
for(auto c: code) if(c.second < 4) vertical = false;
|
||||||
if(vertical) syms *= 2;
|
if(vertical) syms *= 2;
|
||||||
@ -499,7 +576,7 @@ void generate_shapes_rec(vector<cellwalker>& sofar, code_t& code, int cnt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generate_shapes(int cnt) {
|
void generate_shapes(int cnt) {
|
||||||
vector<cellwalker> cws = { cwt };
|
vector<cellwalker> cws = { get_at(get_center(), -well_size - 1) };
|
||||||
code_t co = {};
|
code_t co = {};
|
||||||
generate_shapes_rec(cws, co, cnt);
|
generate_shapes_rec(cws, co, cnt);
|
||||||
}
|
}
|
||||||
@ -556,6 +633,11 @@ void remove_shape() {
|
|||||||
bool shape_conflict(cellwalker cw) {
|
bool shape_conflict(cellwalker cw) {
|
||||||
auto shape = build_from(piecelist[shape_id].code, cw);
|
auto shape = build_from(piecelist[shape_id].code, cw);
|
||||||
|
|
||||||
|
/* self-conflict possible in the orbifold */
|
||||||
|
for(int i=0; i<isize(shape); i++) for(int j=0; j<i; j++)
|
||||||
|
if(shape[i].at == shape[j].at)
|
||||||
|
return true;
|
||||||
|
|
||||||
for(auto c: shape)
|
for(auto c: shape)
|
||||||
if(c.at->wall)
|
if(c.at->wall)
|
||||||
return true;
|
return true;
|
||||||
@ -593,13 +675,26 @@ int choose_piece() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void reset_view();
|
void reset_view();
|
||||||
|
void set_tview(transmatrix T);
|
||||||
|
|
||||||
void new_piece() {
|
void new_piece() {
|
||||||
at.at = get_at(well_center ? well_center : get_where(at.at).first, -well_size - 1);
|
if(well_center && true) {
|
||||||
if(well_center) {
|
again:
|
||||||
at.spin = 0;
|
if(get_where(at.at).first != well_center) {
|
||||||
reset_view();
|
at.at = get_at(get_where(at.at).first, -well_size - 1);
|
||||||
|
int d = center_distance[get_where(at.at).first];
|
||||||
|
for(int i=0; i<4; i++) {
|
||||||
|
auto mov = get_where(shift_block_target(i)).first;
|
||||||
|
if(center_distance.count(mov) && center_distance[mov] < d) {
|
||||||
|
shift_block(i, true);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println(hlog, "failed to recenter");
|
||||||
|
}
|
||||||
|
while(at.spin) rotate_block(1, true);
|
||||||
}
|
}
|
||||||
|
at.at = get_at(get_where(at.at).first, -well_size - 1);
|
||||||
shape_id = next_shape_id;
|
shape_id = next_shape_id;
|
||||||
next_shape_id = choose_piece();
|
next_shape_id = choose_piece();
|
||||||
if(shape_conflict(at)) {
|
if(shape_conflict(at)) {
|
||||||
@ -765,7 +860,7 @@ ld move_dist;
|
|||||||
void set_view() {
|
void set_view() {
|
||||||
move_dist = hdist0(currentmap->adj(cwt.at, 0) * C0);
|
move_dist = hdist0(currentmap->adj(cwt.at, 0) * C0);
|
||||||
|
|
||||||
if(in_h2xe() && PURE) {
|
if(in_h2xe() && PURE && S3 == 4) {
|
||||||
ld dist = PIU(hdist0(get_corner_position(currentmap->gamestart(), 0)));
|
ld dist = PIU(hdist0(get_corner_position(currentmap->gamestart(), 0)));
|
||||||
dist -= 1e-4;
|
dist -= 1e-4;
|
||||||
move_dist = PIU(hdist(get_corner_position(currentmap->gamestart(), 0), get_corner_position(currentmap->gamestart(), 1)));
|
move_dist = PIU(hdist(get_corner_position(currentmap->gamestart(), 0), get_corner_position(currentmap->gamestart(), 1)));
|
||||||
@ -774,6 +869,8 @@ void set_view() {
|
|||||||
}
|
}
|
||||||
if(in_h2xe() && UNRECTIFIED)
|
if(in_h2xe() && UNRECTIFIED)
|
||||||
tView = spin(135*degree) * tView;
|
tView = spin(135*degree) * tView;
|
||||||
|
if(in_h2xe() && S7 == 4)
|
||||||
|
tView = spin(90*degree) * tView;
|
||||||
if(in_s2xe())
|
if(in_s2xe())
|
||||||
tView = spin(90*degree) * tView;
|
tView = spin(90*degree) * tView;
|
||||||
if(in_e2xe())
|
if(in_e2xe())
|
||||||
@ -804,19 +901,19 @@ void set_tview(transmatrix T) {
|
|||||||
when_t = ticks + turn_animation;
|
when_t = ticks + turn_animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rotate_block(int d) {
|
void rotate_block(int d, bool camera_only) {
|
||||||
if(!rotate_allowed) {
|
if(!rotate_allowed && !camera_only) {
|
||||||
playSound(cwt.at, "hit-crush3");
|
playSound(cwt.at, "hit-crush3");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
remove_shape();
|
if(!camera_only) remove_shape();
|
||||||
cellwalker at1 = flatspin(at, d);
|
cellwalker at1 = flatspin(at, d);
|
||||||
if(!shape_conflict(at1)) {
|
if(camera_only || !shape_conflict(at1)) {
|
||||||
at = at1;
|
at = at1;
|
||||||
set_tview(spin(d*90*degree));
|
set_tview(spin(d*90*degree));
|
||||||
}
|
}
|
||||||
else playSound(cwt.at, "hit-crush3");
|
else playSound(cwt.at, "hit-crush3");
|
||||||
draw_shape();
|
if(!camera_only) draw_shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
int nilmap(int dir) {
|
int nilmap(int dir) {
|
||||||
@ -831,11 +928,15 @@ int nilmap(int dir) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shift_block(int dir) {
|
cell *shift_block_target(int dir) {
|
||||||
|
return flatspin(at, dir).cpeek();
|
||||||
|
}
|
||||||
|
|
||||||
|
void shift_block(int dir, bool camera_only) {
|
||||||
int t = currentmap->gamestart()->type;
|
int t = currentmap->gamestart()->type;
|
||||||
if(prod) t -= 2;
|
if(prod) t -= 2;
|
||||||
|
|
||||||
remove_shape();
|
if(!camera_only) remove_shape();
|
||||||
|
|
||||||
cellwalker at1;
|
cellwalker at1;
|
||||||
|
|
||||||
@ -860,7 +961,7 @@ void shift_block(int dir) {
|
|||||||
|
|
||||||
ld angle = dir * 90 * degree;
|
ld angle = dir * 90 * degree;
|
||||||
|
|
||||||
if(!shape_conflict(at1)) {
|
if(camera_only || !shape_conflict(at1)) {
|
||||||
// playSound(cwt.at, "hit-crush1");
|
// playSound(cwt.at, "hit-crush1");
|
||||||
at = at1;
|
at = at1;
|
||||||
if(solnil) {
|
if(solnil) {
|
||||||
@ -869,6 +970,7 @@ void shift_block(int dir) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
set_tview(spin(-angle) * ypush(-move_dist) * spin(angle));
|
set_tview(spin(-angle) * ypush(-move_dist) * spin(angle));
|
||||||
|
if(!camera_only) draw_shape();
|
||||||
}
|
}
|
||||||
else playSound(cwt.at, "hit-crush3");
|
else playSound(cwt.at, "hit-crush3");
|
||||||
}
|
}
|
||||||
@ -943,7 +1045,7 @@ void draw_piece(int zlev, int id) {
|
|||||||
sightranges[geometry] *= 100;
|
sightranges[geometry] *= 100;
|
||||||
initquickqueue();
|
initquickqueue();
|
||||||
auto shape = build_from(piecelist[id].code, at);
|
auto shape = build_from(piecelist[id].code, at);
|
||||||
auto matrices = build_shape_matrices(shape);
|
auto matrices = build_shape_matrices(piecelist[id].code, at);
|
||||||
|
|
||||||
auto where_at = get_where(at.at);
|
auto where_at = get_where(at.at);
|
||||||
|
|
||||||
@ -1126,7 +1228,8 @@ void geometry_menu() {
|
|||||||
dialog::addInfo(bgeoms[i].cap);
|
dialog::addInfo(bgeoms[i].cap);
|
||||||
dialog::items.back().key = 'a' + i;
|
dialog::items.back().key = 'a' + i;
|
||||||
dialog::addBreak(50);
|
dialog::addBreak(50);
|
||||||
if(i >= isize(bgeoms) && bgeom != i) {
|
if(i == bgeom) bgeoms[i].flags &= ~SECRET;
|
||||||
|
if(bgeoms[i].flags & SECRET) {
|
||||||
dialog::items.pop_back();
|
dialog::items.pop_back();
|
||||||
dialog::items.pop_back();
|
dialog::items.pop_back();
|
||||||
dialog::items.pop_back();
|
dialog::items.pop_back();
|
||||||
@ -1140,6 +1243,13 @@ void geometry_menu() {
|
|||||||
create_game();
|
create_game();
|
||||||
state = tsPreGame;
|
state = tsPreGame;
|
||||||
});
|
});
|
||||||
|
if(bflags() & ASYMMETRIC_ONLY)
|
||||||
|
dialog::addInfo("(only asymmetric large pieces)");
|
||||||
|
else if(bflags() & FLAT_ONLY)
|
||||||
|
dialog::addInfo("(only flat pieces)");
|
||||||
|
else
|
||||||
|
dialog::addBreak(100);
|
||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
dialog::addBack();
|
dialog::addBack();
|
||||||
dialog::display();
|
dialog::display();
|
||||||
@ -1249,6 +1359,7 @@ void run() {
|
|||||||
ld alpha = atan2(Tspin*xpush0(1));
|
ld alpha = atan2(Tspin*xpush0(1));
|
||||||
pView = spin(alpha * part) * gpushxto0(direct_exp(vec*part)) * pView;
|
pView = spin(alpha * part) * gpushxto0(direct_exp(vec*part)) * pView;
|
||||||
fixmatrix(pView);
|
fixmatrix(pView);
|
||||||
|
View = tView;
|
||||||
smooth = inverse(pView) * cview().T;
|
smooth = inverse(pView) * cview().T;
|
||||||
// println(hlog, "smooth = ", smooth);
|
// println(hlog, "smooth = ", smooth);
|
||||||
}
|
}
|
||||||
@ -1480,8 +1591,7 @@ void start_new_game() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void get_level() {
|
void get_level() {
|
||||||
well_center = nullptr;
|
if(bflags() & BOUNDED_WELL) {
|
||||||
if(geometry == g45) {
|
|
||||||
set<cell*> all;
|
set<cell*> all;
|
||||||
well_center = currentmap->gamestart();
|
well_center = currentmap->gamestart();
|
||||||
all.insert(well_center);
|
all.insert(well_center);
|
||||||
@ -1516,17 +1626,49 @@ void get_level() {
|
|||||||
for(auto c: all_ext)
|
for(auto c: all_ext)
|
||||||
out_level.push_back(c);
|
out_level.push_back(c);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
level = currentmap->allcells();
|
level = currentmap->allcells();
|
||||||
|
if(bflags() & ORBIFOLD) {
|
||||||
|
vector<cell*> clist;
|
||||||
|
set<cell*> visited;
|
||||||
|
auto visit = [&] (cell *c) {
|
||||||
|
if(!visited.count(c))
|
||||||
|
visited.insert(c),
|
||||||
|
clist.push_back(c);
|
||||||
|
};
|
||||||
|
for(auto c: level) if(isNeighbor(c, c)) visit(c);
|
||||||
|
for(int i=0; i<isize(clist); i++)
|
||||||
|
for(int j=0; j<clist[i]->type; j++)
|
||||||
|
visit(clist[i]->cmove(j));
|
||||||
|
well_center = clist.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(well_center) {
|
||||||
|
vector<cell*> visited;
|
||||||
|
set<cell*> all;
|
||||||
|
for(auto l: level) all.insert(l);
|
||||||
|
auto visit = [&] (cell *c, int d) {
|
||||||
|
if(all.count(c) && !center_distance.count(c))
|
||||||
|
center_distance[c] = d,
|
||||||
|
visited.push_back(c);
|
||||||
|
};
|
||||||
|
visit(well_center, 0);
|
||||||
|
for(int i=0; i<isize(visited); i++)
|
||||||
|
for(int j=0; j<visited[i]->type; j++)
|
||||||
|
visit(visited[i]->move(j), center_distance[visited[i]] + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_game() {
|
void create_game() {
|
||||||
|
level.clear();
|
||||||
|
out_level.clear();
|
||||||
|
well_center = nullptr;
|
||||||
|
|
||||||
if(!prod && !solnil) {
|
if(!prod && !solnil) {
|
||||||
println(hlog, "need product or Solnil geometry");
|
println(hlog, "need product or Solnil geometry");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(nil) {
|
if(nil) {
|
||||||
level.clear();
|
|
||||||
for(int x=0; x<5; x++)
|
for(int x=0; x<5; x++)
|
||||||
for(int y=0; y<5; y++)
|
for(int y=0; y<5; y++)
|
||||||
level.push_back(nilv::get_heptagon_at(nilv::mvec(x, 0, y))->c7);
|
level.push_back(nilv::get_heptagon_at(nilv::mvec(x, 0, y))->c7);
|
||||||
@ -1565,6 +1707,8 @@ void create_game() {
|
|||||||
|
|
||||||
start_new_game();
|
start_new_game();
|
||||||
state = tsPreGame;
|
state = tsPreGame;
|
||||||
|
|
||||||
|
vid.axes3 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_all() {
|
void init_all() {
|
||||||
|
Loading…
Reference in New Issue
Block a user