mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
186 lines
4.5 KiB
C++
186 lines
4.5 KiB
C++
#include "rogueviz.h"
|
|
|
|
/* a sample higher dimensional Sokoban puzzle */
|
|
|
|
namespace rogueviz {
|
|
|
|
namespace crystal_sokoban {
|
|
|
|
vector<string> sokomap = {
|
|
"########|########|########|########|########|########|########|########",
|
|
"########|########|## #####|## #####|########|########|########|########",
|
|
"########|##. ####|# $ ###|##.$####|##. ####|########|########|########",
|
|
"########|##.#####|# $$@###|## ####|## #####|########|########|########",
|
|
"########|########|## #####|## #####|########|########|########|########",
|
|
"########|########|########|########|########|########|########|########",
|
|
"########|########|########|########|########|########|########|########",
|
|
"########|########|########|########|########|########|########|########"
|
|
};
|
|
|
|
bool on;
|
|
|
|
bool created;
|
|
|
|
vector<cell*> celllist;
|
|
|
|
struct undo_state {
|
|
vector<eWall> board;
|
|
cell* where;
|
|
};
|
|
|
|
vector<undo_state> undos;
|
|
|
|
undo_state current_state() {
|
|
undo_state u;
|
|
u.where = cwt.at;
|
|
for(cell *c: celllist) u.board.push_back(c->wall);
|
|
return u;
|
|
}
|
|
|
|
void sb_hooks();
|
|
|
|
void run_sb() {
|
|
showstartmenu = false;
|
|
crystal::compass_probability = 0;
|
|
stop_game();
|
|
crystal::set_crystal(6);
|
|
set_variation(eVariation::pure);
|
|
enable_canvas();
|
|
ccolor::set_plain(0x101010);
|
|
check_cgi();
|
|
start_game();
|
|
|
|
for(int z=-8; z<8; z++)
|
|
for(int y=-8; y<8; y++)
|
|
for(int x=-8; x<8; x++) {
|
|
crystal::coord co = crystal::c0; co[0] = 2*x; co[1] = 2*y; co[2] = 2*z;
|
|
cell *c = crystal::get_heptagon_at(co)->c7;
|
|
setdist(c, 7, c);
|
|
}
|
|
|
|
for(int z=-8; z<8; z++)
|
|
for(int y=-8; y<8; y++)
|
|
for(int x=-8; x<8; x++) {
|
|
char what;
|
|
if(x<0 || y<0 || z<0)
|
|
what = '#';
|
|
else
|
|
what = sokomap[y][x*9+z];
|
|
|
|
crystal::coord co = crystal::c0; co[0] = 2*x; co[1] = 2*y; co[2] = 2*z;
|
|
cell *c = crystal::get_heptagon_at(co)->c7;
|
|
|
|
color_t col;
|
|
for(int i=0; i<3; i++)
|
|
part(col, i) = 0x80 + 0x20 * (co[i] - 5);
|
|
|
|
c->landparam = col;
|
|
|
|
if(what == '#')
|
|
c->wall = waStone;
|
|
else if(what == '$')
|
|
c->wall = waCrateCrate;
|
|
else if(what == '*')
|
|
c->wall = waCrateOnTarget;
|
|
else if(what == '.')
|
|
c->wall = waCrateTarget;
|
|
else {
|
|
c->wall = waNone;
|
|
if(what == '@') {
|
|
cwt.at = c;
|
|
centerover = c;
|
|
}
|
|
}
|
|
celllist.push_back(c);
|
|
}
|
|
vid.smart_range_detail = ISWEB ? 20 : 1;
|
|
vid.use_smart_range = 2;
|
|
undos.push_back(current_state());
|
|
peace::on = true;
|
|
|
|
sb_hooks();
|
|
}
|
|
|
|
void save_undo() {
|
|
undos.push_back(current_state());
|
|
}
|
|
|
|
void restore_undo() {
|
|
undos.pop_back();
|
|
auto& u = undos.back();
|
|
cwt.at = u.where;
|
|
current_display->which_copy = Id;
|
|
int i = 0;
|
|
for(cell *c: celllist) c->wall = u.board[i++];
|
|
|
|
undos.pop_back();
|
|
}
|
|
|
|
bool sokomap2() {
|
|
|
|
if(undos.back().where != cwt.at) save_undo();
|
|
|
|
if(1) {
|
|
glflush();
|
|
dynamicval<eGeometry> g(geometry, gEuclidSquare);
|
|
check_cgi();
|
|
cgi.require_shapes();
|
|
initquickqueue();
|
|
|
|
if(1) {
|
|
auto gm = gmatrix;
|
|
dynamicval<bool> ww(wmspatial, false);
|
|
dynamicval<bool> wm(mmspatial, false);
|
|
dynamicval<shiftmatrix> s1(playerV);
|
|
dynamicval<transmatrix> s2(current_display->which_copy);
|
|
dynamicval<shiftmatrix> s3(cwtV, cwtV);
|
|
dynamicval<array<map<cell*, animation>, ANIMLAYERS>> an(animations);
|
|
animations[LAYER_SMALL] = {};
|
|
|
|
for(int x=0; x<4; x++)
|
|
for(int y=0; y<4; y++)
|
|
for(int z=0; z<4; z++) {
|
|
crystal::coord co = crystal::c0; co[0] = 2*x+2; co[1] = 2*y+2; co[2] = 2*z+2;
|
|
cell *c = crystal::get_heptagon_at(co)->c7;
|
|
drawcell(c, shiftless(euscale(.12,.12) * eupush(3+(vid.xres*1./vid.yres-1)*12, -16) * eupush(z*4.2+x, y) * Id));
|
|
}
|
|
|
|
gmatrix = gm;
|
|
}
|
|
|
|
quickqueue();
|
|
glflush();
|
|
}
|
|
|
|
check_cgi();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool soko_key(int sym, int uni) {
|
|
if((cmode & sm::NORMAL) && (uni == SDLK_BACKSPACE || uni == 'r') && isize(undos) != 1) {
|
|
restore_undo();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void sb_hooks() {
|
|
rv_hook(hooks_prestats, 90, sokomap2);
|
|
rv_hook(hooks_welcome_message, 50, [] () {
|
|
addMessage(XLAT("Welcome to Crystal Sokoban!"));
|
|
return true;
|
|
});
|
|
rv_hook(hooks_handleKey, 50, soko_key);
|
|
on_cleanup_or_next([] {
|
|
undos.clear();
|
|
celllist.clear();
|
|
});
|
|
}
|
|
|
|
auto sbhook = arg::add2("-crystal-sokoban", run_sb);
|
|
|
|
|
|
}
|
|
|
|
} |