mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +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);
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| } | 
