1 #include "rogueviz.h"
2
3 namespace rogueviz {
4
5 #if CAP_CRYSTAL
6
7 namespace magic {
8
9 int back = 0x202020;
10
11 int magiccolors[14] = { 0xFFFFFF, 0xFFFF00, 0x0000FF, 0x00FF00, 0xFF0000, 0xFF8000, 0x800080, 0x808080, 0x00FFFF, 0x80FFFF, 0x4040C0, 0x40C040, 0xC04040, 0xC0A040 };
12
build(crystal::coord co,int at)13 void build(crystal::coord co, int at) {
14 if(at < crystal::get_dim()) {
15 for(int z: {0,2,-2,4,-4}) co[at] = z, build(co, at+1);
16 return;
17 }
18 for(int i=0; i<S7; i++) crystal::get_heptagon_at(co)->cmove(i);
19
20 int twos = 0, index = 0;
21 for(int a=0; a<crystal::get_dim(); a++)
22 if(co[a] == 4) twos++, index = 2*a;
23 else if(co[a] == -4) twos++, index = 2*a+1;
24
25 auto c = crystal::get_heptagon_at(co)->c7;
26 setdist(c, 7, NULL);
27 if(twos == 0)
28 c->landparam = back;
29 else if(twos == 1) {
30 c->landparam = magiccolors[index];
31 if(WDIM == 3) c->wall = waWaxWall;
32 }
33
34 println(hlog, co, " twos = ", twos, " index = ", index, " set = ", format("%06X", c->landparam));
35
36 }
37
curveline(hyperpoint a,hyperpoint b,int lev)38 void curveline(hyperpoint a, hyperpoint b, int lev) {
39 if(lev>0) {
40 hyperpoint c = mid(a, b);
41 curveline(a, c, lev-1);
42 curveline(c, b, lev-1);
43 }
44 curvepoint(b);
45 }
46
magic_markers(cell * c,const shiftmatrix & V)47 bool magic_markers(cell *c, const shiftmatrix& V) {
48 timerghost = false;
49 if(c->landparam == back) {
50 if(GDIM == 2) {
51 auto co = crystal::get_coord(c->master);
52 for(int a=0; a<S7/2; a++) if(co[a] >= 6 || co[a] <= -6) c->landparam = 0;
53 }
54 if(GDIM == 2)
55 for(int i=0; i<S7; i++) {
56 cell *c2 = c->move(i);
57 if(c2->landparam != back) {
58 hyperpoint h1 = get_corner_position(c, i, 3/.9);
59 hyperpoint h2 = get_corner_position(c, i+1, 3/.9);
60 curvepoint(h1);
61 curveline(h1, h2, 3);
62 hyperpoint h3 = get_corner_position(c, i, 3/.7);
63 hyperpoint h4 = get_corner_position(c, i+1, 3/.7);
64 curvepoint(h4);
65 curveline(h4, h3, 3);
66 queuecurve(V, 0xFF, (c2->landparam << 8) | 0xFF, PPR::LINE);
67 }
68 }
69 }
70 else {
71 c->wall = GDIM == 2 ? waInvisibleFloor : waWaxWall;
72 }
73 return false;
74 }
75
twos_to_fours(vector<int> & zeros,crystal::coord co,int d)76 void twos_to_fours(vector<int>& zeros, crystal::coord co, int d) {
77 if(d == crystal::get_dim()) {
78 int facetable[5][5];
79 for(int x=0; x<5; x++)
80 for(int y=0; y<5; y++) {
81 co[zeros[0]] = 2*x-4;
82 co[zeros[1]] = 2*y-4;
83 facetable[y][x] = crystal::get_heptagon_at(co)->c7->landparam;
84 }
85 for(int x=0; x<5; x++)
86 for(int y=0; y<5; y++) {
87 co[zeros[0]] = 2*y-4;
88 co[zeros[1]] = 4-2*x;
89 crystal::get_heptagon_at(co)->c7->landparam = facetable[y][x];
90 }
91 }
92 else {
93 twos_to_fours(zeros, co, d+1);
94 if(co[d] == 2 || co[d] == -2) {
95 co[d] *= 2;
96 twos_to_fours(zeros, co, d+1);
97 }
98 }
99 }
100
magic_rotate(cell * c)101 bool magic_rotate(cell *c) {
102 if(c->landparam != back) return false;
103 vector<int> zeros;
104 auto co = crystal::get_coord(c->master);
105 println(hlog, "co = ", co);
106 for(int i=0; i<crystal::get_dim(); i++) {
107 if(co[i] == 0) zeros.push_back(i);
108 else if(co[i] == 2 || co[i] == -2) ;
109 else if(co[i] == 4 || co[i] == -4) ;
110 else return false;
111 }
112 println(hlog, "zeros = ", zeros);
113 if(isize(zeros) != 2) return false;
114 twos_to_fours(zeros, co, 0);
115 return true;
116 }
117
magic_rugkey(int sym,int uni)118 bool magic_rugkey(int sym, int uni) {
119 if((cmode & sm::NORMAL) && uni == 'p') {
120 rug::texturesize = 4096;
121 if(rug::rugged) rug::close();
122 else rug::init();
123 return true;
124 }
125 if((cmode & sm::NORMAL) && uni == 'r') {
126 mine::performMarkCommand(mouseover);
127 return true;
128 }
129 if((cmode & sm::NORMAL) && uni == 'R') {
130 build(crystal::c0, 0);
131 }
132 if((cmode & sm::NORMAL) && uni == 'k') {
133 crystal::view_coordinates = !crystal::view_coordinates;
134 return true;
135 }
136 return false;
137 }
138
magic(int sides)139 void magic(int sides) {
140 stop_game();
141 if(sides < 0)
142 set_geometry(gCrystal344);
143 else
144 crystal::set_crystal(sides);
145 set_variation(eVariation::pure);
146 firstland = specialland = laCanvas;
147 patterns::whichCanvas = 'g';
148 patterns::canvasback = back;
149 check_cgi();
150 start_game();
151
152 build(crystal::c0, 0);
153
154 rv_hook(hooks_drawcell, 100, magic_markers);
155 rv_hook(mine::hooks_mark, 150, magic_rotate);
156 rv_hook(hooks_handleKey, 150, magic_rugkey);
157 }
158
__anon6e501c470102null159 auto magichook = arg::add2("-magic3", [] { magic(-1); }) + arg::add2("-magic", [] { magic(arg::shift_argi()); });
160
161 }
162 #endif
163 }