1 #include "rogueviz.h"
2
3 /* a sample higher dimensional Sokoban puzzle */
4
5 namespace rogueviz {
6
7 namespace crystal_sokoban {
8
9 vector<string> sokomap = {
10 "########|########|########|########|########|########|########|########",
11 "########|########|## #####|## #####|########|########|########|########",
12 "########|##. ####|# $ ###|##.$####|##. ####|########|########|########",
13 "########|##.#####|# $$@###|## ####|## #####|########|########|########",
14 "########|########|## #####|## #####|########|########|########|########",
15 "########|########|########|########|########|########|########|########",
16 "########|########|########|########|########|########|########|########",
17 "########|########|########|########|########|########|########|########"
18 };
19
20 bool on;
21
22 bool created;
23
24 vector<cell*> celllist;
25
26 struct undo_state {
27 vector<eWall> board;
28 cell* where;
29 };
30
31 vector<undo_state> undos;
32
current_state()33 undo_state current_state() {
34 undo_state u;
35 u.where = cwt.at;
36 for(cell *c: celllist) u.board.push_back(c->wall);
37 return u;
38 }
39
40 void sb_hooks();
41
run_sb()42 void run_sb() {
43 showstartmenu = false;
44 crystal::compass_probability = 0;
45 stop_game();
46 crystal::set_crystal(6);
47 set_variation(eVariation::pure);
48 firstland = specialland = laCanvas;
49 patterns::whichCanvas = 'g';
50 patterns::canvasback = 0x101010;
51 check_cgi();
52 start_game();
53
54 for(int z=-8; z<8; z++)
55 for(int y=-8; y<8; y++)
56 for(int x=-8; x<8; x++) {
57 crystal::coord co = crystal::c0; co[0] = 2*x; co[1] = 2*y; co[2] = 2*z;
58 cell *c = crystal::get_heptagon_at(co)->c7;
59 setdist(c, 7, c);
60 }
61
62 for(int z=-8; z<8; z++)
63 for(int y=-8; y<8; y++)
64 for(int x=-8; x<8; x++) {
65 char what;
66 if(x<0 || y<0 || z<0)
67 what = '#';
68 else
69 what = sokomap[y][x*9+z];
70
71 crystal::coord co = crystal::c0; co[0] = 2*x; co[1] = 2*y; co[2] = 2*z;
72 cell *c = crystal::get_heptagon_at(co)->c7;
73
74 color_t col;
75 for(int i=0; i<3; i++)
76 part(col, i) = 0x80 + 0x20 * (co[i] - 5);
77
78 c->landparam = col;
79
80 if(what == '#')
81 c->wall = waStone;
82 else if(what == '$')
83 c->wall = waCrateCrate;
84 else if(what == '*')
85 c->wall = waCrateOnTarget;
86 else if(what == '.')
87 c->wall = waCrateTarget;
88 else {
89 c->wall = waNone;
90 if(what == '@') {
91 cwt.at = c;
92 centerover = c;
93 }
94 }
95 celllist.push_back(c);
96 }
97 vid.smart_range_detail = ISWEB ? 20 : 1;
98 vid.use_smart_range = 2;
99 undos.push_back(current_state());
100 peace::on = true;
101 }
102
save_undo()103 void save_undo() {
104 undos.push_back(current_state());
105 }
106
restore_undo()107 void restore_undo() {
108 undos.pop_back();
109 auto& u = undos.back();
110 cwt.at = u.where;
111 current_display->which_copy = Id;
112 int i = 0;
113 for(cell *c: celllist) c->wall = u.board[i++];
114
115 undos.pop_back();
116 }
117
sokomap2()118 bool sokomap2() {
119
120 if(undos.back().where != cwt.at) save_undo();
121
122 if(1) {
123 glflush();
124 dynamicval<eGeometry> g(geometry, gEuclidSquare);
125 check_cgi();
126 cgi.require_shapes();
127 initquickqueue();
128
129 if(1) {
130 auto gm = gmatrix;
131 dynamicval<bool> ww(wmspatial, false);
132 dynamicval<bool> wm(mmspatial, false);
133 dynamicval<shiftmatrix> s1(playerV);
134 dynamicval<transmatrix> s2(current_display->which_copy);
135 dynamicval<shiftmatrix> s3(cwtV, cwtV);
136 dynamicval<array<map<cell*, animation>, ANIMLAYERS>> an(animations);
137 animations[LAYER_SMALL] = {};
138
139 for(int x=0; x<4; x++)
140 for(int y=0; y<4; y++)
141 for(int z=0; z<4; z++) {
142 crystal::coord co = crystal::c0; co[0] = 2*x+2; co[1] = 2*y+2; co[2] = 2*z+2;
143 cell *c = crystal::get_heptagon_at(co)->c7;
144 drawcell(c, shiftless(euscale(.12,.12) * eupush(3+(vid.xres*1./vid.yres-1)*12, -16) * eupush(z*4.2+x, y) * Id));
145 }
146
147 gmatrix = gm;
148 }
149
150 quickqueue();
151 glflush();
152 }
153
154 check_cgi();
155
156 return true;
157 }
158
soko_key(int sym,int uni)159 bool soko_key(int sym, int uni) {
160 if((cmode & sm::NORMAL) && (uni == SDLK_BACKSPACE || uni == 'r') && isize(undos) != 1) {
161 restore_undo();
162 return true;
163 }
164 return false;
165 }
166
sb_hooks()167 void sb_hooks() {
168 rv_hook(hooks_prestats, 90, sokomap2);
169 rv_hook(hooks_welcome_message, 50, [] () {
170 addMessage(XLAT("Welcome to Crystal Sokoban!"));
171 return true;
172 });
173 rv_hook(hooks_handleKey, 50, soko_key);
174 }
175
176 auto sbhook = arg::add2("-crystal-sokoban", run_sb);
177
178
179 }
180
181 }