mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-29 21:13:00 +00:00 
			
		
		
		
	Merge branch 'master' into offsetof1
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -84,7 +84,7 @@ ifeq (${TOOLCHAIN},clang) | ||||
|   CXXFLAGS_EARLY += -march=native -fPIC | ||||
|   CXXFLAGS_EARLY += -W -Wall -Wextra -Werror -pedantic | ||||
|   CXXFLAGS_EARLY += -Wno-unused-parameter -Wno-implicit-fallthrough -Wno-maybe-uninitialized -Wno-unknown-warning-option | ||||
|   CXXFLAGS_EARLY += -Wno-invalid-offsetof | ||||
|   CXXFLAGS_EARLY += -Wno-invalid-offsetof -Wno-overloaded-virtua | ||||
| endif | ||||
|  | ||||
| ifeq (${TOOLCHAIN},gcc) | ||||
|   | ||||
							
								
								
									
										26
									
								
								barriers.cpp
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								barriers.cpp
									
									
									
									
									
								
							| @@ -745,13 +745,15 @@ EX void buildCrossroads2(cell *c) { | ||||
|   } | ||||
|  | ||||
| #if MAXMDIM >= 4 | ||||
| EX bool bufferzone() { return false; } | ||||
|  | ||||
| EX void extend3D(cell *c) { | ||||
|   eLand l1 = c->land; | ||||
|   c->barleft = NOWALLSEP_USED; | ||||
|    | ||||
|   cellwalker cw(c, c->bardir); | ||||
|    | ||||
|   if(S3 == 5) { | ||||
|   if(bufferzone()) { | ||||
|     cw += wstep; cw += rev; | ||||
|     cw.at->bardir = NOBARRIERS; | ||||
|     setland(cw.at, laBarrier); | ||||
| @@ -765,9 +767,10 @@ EX void extend3D(cell *c) { | ||||
|     cw1.at->bardir = cw1.spin; | ||||
|     } | ||||
|  | ||||
|   for(int j=0; j<S7; j++) if(cgi.dirs_adjacent[cw.spin][j]) { | ||||
|     cellwalker bb2 = reg3::strafe(cw, j); | ||||
|     if(S3 == 5) { bb2 += rev; bb2 += wstep; } | ||||
|   auto& ad = currentmap->adjacent_dirs(cw); | ||||
|   for(int j=0; j<S7; j++) if(ad[j]) { | ||||
|     cellwalker bb2 = currentmap->strafe(cw, j); | ||||
|     if(bufferzone()) { bb2 += rev; bb2 += wstep; } | ||||
|  | ||||
|     if(bb2.at->bardir == NODIR) { | ||||
|       bb2.at->bardir = bb2.spin; | ||||
| @@ -788,7 +791,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) { | ||||
|     return false; | ||||
|     } | ||||
|   cellwalker cw(c, forced_dir); | ||||
|   if(S3 == 5) { cw += wstep; cw += rev; } | ||||
|   if(bufferzone()) { cw += wstep; cw += rev; } | ||||
|   set<cell*> listed_cells = { cw.at }; | ||||
|   vector<cellwalker> to_test { cw };   | ||||
|   for(int i=0; i<isize(to_test); i++) { | ||||
| @@ -796,13 +799,14 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) { | ||||
|     if(bb.at->mpdist < BARLEV) return false; | ||||
|     if(bb.cpeek()->mpdist < BARLEV) return false; | ||||
|     if(bb.cpeek()->bardir != NODIR) return false; | ||||
|     if(S3 == 5 && (bb+rev).cpeek()->mpdist < BARLEV) return false; | ||||
|     if(S3 == 5 && (bb+rev).cpeek()->bardir != NODIR) return false; | ||||
|     if(bufferzone() && (bb+rev).cpeek()->mpdist < BARLEV) return false; | ||||
|     if(bufferzone() && (bb+rev).cpeek()->bardir != NODIR) return false; | ||||
|     if(bb.at->bardir != NODIR) return false; | ||||
|     auto& ad = currentmap->adjacent_dirs(bb); | ||||
|     for(int j=0; j<S7; j++) { | ||||
|       if(S3 == 5 && i <= 5) bb.at->cmove(j); | ||||
|       if(cgi.dirs_adjacent[bb.spin][j] && bb.at->move(j)) { | ||||
|         cellwalker bb2 = reg3::strafe(bb, j); | ||||
|       if(bufferzone() && i <= 5) bb.at->cmove(j); | ||||
|       if(ad[j] && bb.at->move(j)) { | ||||
|         cellwalker bb2 = currentmap->strafe(bb, j); | ||||
|         if(listed_cells.count(bb2.at)) continue; | ||||
|         listed_cells.insert(bb2.at); | ||||
|         to_test.push_back(bb2); | ||||
| @@ -812,7 +816,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) { | ||||
|  | ||||
|   for(int i=0; i<isize(to_test); i++) { | ||||
|     auto bb = to_test[i]; | ||||
|     if(S3 == 5) { bb.at->bardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; } | ||||
|     if(bufferzone()) { bb.at->bardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; } | ||||
|     bb.at->land = c->land; | ||||
|     bb.at->bardir = bb.spin; | ||||
|     bb.at->barleft = NOWALLSEP; | ||||
|   | ||||
							
								
								
									
										31
									
								
								bigstuff.cpp
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								bigstuff.cpp
									
									
									
									
									
								
							| @@ -206,10 +206,11 @@ void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) { | ||||
|   } | ||||
|  | ||||
| #if MAXMDIM >= 4 | ||||
| EX int hrandom_adjacent(int d) { | ||||
|   vector<int> choices = {d}; | ||||
|   for(int a=0; a<S7; a++) if(cgi.dirs_adjacent[d][a]) choices.push_back(a); | ||||
|   return hrand_elt(choices, d); | ||||
| EX int hrandom_adjacent(cellwalker cw) { | ||||
|   auto& da = currentmap->adjacent_dirs(cw);   | ||||
|   vector<int> choices = {cw.spin}; | ||||
|   for(int a=0; a<S7; a++) if(da[a]) choices.push_back(a); | ||||
|   return hrand_elt(choices, cw.spin); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| @@ -271,7 +272,7 @@ EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special | ||||
|     #if MAXMDIM >= 4 | ||||
|     // in 3D honeycombs we vary the direction, but never for three successive i's | ||||
|     if(WDIM == 3 && firststate == hsOrigin && (i%3)) | ||||
|       bf.spin = hrandom_adjacent(bf.spin); | ||||
|       bf.spin = hrandom_adjacent(bf); | ||||
|     #endif | ||||
|     } | ||||
|   cx[rad] = bf.at; | ||||
| @@ -694,9 +695,12 @@ EX void buildEquidistant(cell *c) { | ||||
|           if(cw.at->landparam != c->landparam-1) continue; | ||||
|           if(!cw.at->landflags) continue; | ||||
|           if(S7 == 6) c->landflags = 1; | ||||
|           else for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !cgi.dirs_adjacent[j][cw.spin]) | ||||
|             if(c->landparam == 2 ? cw.at->move(j)->land != laEndorian : cw.at->move(j)->landparam) | ||||
|               c->landflags = 1; | ||||
|           else { | ||||
|             auto& da = currentmap->adjacent_dirs(cw); | ||||
|             for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !da[j]) | ||||
|               if(c->landparam == 2 ? cw.at->move(j)->land != laEndorian : cw.at->move(j)->landparam) | ||||
|                 c->landflags = 1; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       else if(c->landparam == 2) { | ||||
| @@ -718,8 +722,11 @@ EX void buildEquidistant(cell *c) { | ||||
|           if(cw.at->landparam != c->landparam-1) continue; | ||||
|           if(!cw.at->landflags) continue; | ||||
|           if(S7 == 6) c->landflags = 1; | ||||
|           else for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !cgi.dirs_adjacent[j][cw.spin] && cw.at->move(j)->landflags) | ||||
|             c->landflags = 1; | ||||
|           else { | ||||
|             auto& da = currentmap->adjacent_dirs(cw); | ||||
|             for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !da[j] && cw.at->move(j)->landflags) | ||||
|               c->landflags = 1; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       else { | ||||
| @@ -1485,7 +1492,7 @@ EX bool good_for_wall(cell *c) { | ||||
|   } | ||||
|  | ||||
| EX bool walls_not_implemented() { | ||||
|   if(WDIM == 3 && !PURE) return true; | ||||
|   // if(WDIM == 3 && !PURE) return true; | ||||
|   if(sphere || quotient || nonisotropic || (kite::in() && !bt::in()) || experimental) return true; | ||||
|   return WDIM == 3 && (cgflags & qIDEAL); | ||||
|   } | ||||
| @@ -1994,8 +2001,8 @@ EX void generate_mines() { | ||||
|   for(cell *c: currentmap->allcells()) | ||||
|     if(c->wall == waMineUnknown)  | ||||
|       candidates.push_back(c); | ||||
|   hrandom_shuffle(candidates); | ||||
|   bounded_mine_max = isize(candidates); | ||||
|   hrandom_shuffle(&candidates[0], bounded_mine_max); | ||||
|   bounded_mine_quantity = int(bounded_mine_max * bounded_mine_percentage + 0.5); | ||||
|   for(int i=0; i<bounded_mine_quantity; i++) candidates[i]->wall = waMineMine; | ||||
|   } | ||||
|   | ||||
							
								
								
									
										8
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -75,6 +75,14 @@ struct hrmap { | ||||
|       } | ||||
|     return currentmap->iadj(c, i); | ||||
|     } | ||||
|  | ||||
|   /** \brief in 3D honeycombs, returns a vector<bool> v, where v[j] iff faces i and j are adjacent */ | ||||
|   virtual const vector<bool>& adjacent_dirs(cell *c, int i) { throw hr_exception("adjacent_dirs called unexpectedly"); } | ||||
|  | ||||
|   /** \brief in 3D honeycombs, returns a cellwalker res at cw->move(j) such that the face pointed at by cw and res share an edge */ | ||||
|   virtual cellwalker strafe(cellwalker cw, int j) { throw hr_exception("strafe called unexpectedly"); } | ||||
|  | ||||
|   const vector<bool>& adjacent_dirs(cellwalker cw) { return adjacent_dirs(cw.at, cw.spin); } | ||||
|   }; | ||||
|  | ||||
| /** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient   | ||||
|   | ||||
| @@ -2510,9 +2510,9 @@ void celldrawer::add_map_effects() { | ||||
|   } | ||||
|  | ||||
| void celldrawer::draw_gravity_particles() { | ||||
|   int u = (int)(size_t)(c); | ||||
|   unsigned int u = (unsigned int)(size_t)(c); | ||||
|   u = ((u * 137) + (u % 1000) * 51) % 1000; | ||||
|   int tt = ticks + u; fractick(ticks, 900); | ||||
|   int tt = ticks + u; | ||||
|   ld r0 = (tt % 900) / 1100.; | ||||
|   ld r1 = (tt % 900 + 200) / 1100.; | ||||
|    | ||||
|   | ||||
| @@ -1847,7 +1847,7 @@ EX namespace hive { | ||||
|         } | ||||
|       } | ||||
|      | ||||
|     hrandom_shuffle(&bugtomove[0], isize(bugtomove)); | ||||
|     hrandom_shuffle(bugtomove); | ||||
|     sort(bugtomove.begin(), bugtomove.end()); | ||||
|      | ||||
|     int battlecount = 0; | ||||
| @@ -3611,7 +3611,7 @@ EX namespace windmap { | ||||
|     vector<bool> inqueue(N, true); | ||||
|     vector<int> tocheck; | ||||
|     for(int i=0; i<N; i++) tocheck.push_back(i); | ||||
|     hrandom_shuffle(&tocheck[0], isize(tocheck)); | ||||
|     hrandom_shuffle(tocheck); | ||||
|      | ||||
|     for(int a=0; a<isize(tocheck); a++) { | ||||
|       if(a >= 200*N) { printf("does not converge\n"); break; } | ||||
|   | ||||
| @@ -852,7 +852,7 @@ EX void ambush(cell *c, int dogs) { | ||||
|   int v = valence(); | ||||
|   if(v > 4) { | ||||
|     for(cell *c: cl.lst) if(cl.getdist(c) == d) around.push_back(c); | ||||
|     hrandom_shuffle(&around[0], isize(around)); | ||||
|     hrandom_shuffle(around); | ||||
|     } | ||||
|   else { | ||||
|     for(int tries=0; tries<10000; tries++) { | ||||
|   | ||||
							
								
								
									
										107
									
								
								config.cpp
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								config.cpp
									
									
									
									
									
								
							| @@ -27,9 +27,9 @@ struct supersaver { | ||||
|   virtual void load(const string& s) = 0; | ||||
|   virtual bool dosave() = 0; | ||||
|   virtual void reset() = 0; | ||||
|   virtual ~supersaver() {} | ||||
|   virtual bool affects(void* v) { return false; } | ||||
|   virtual void set_default() = 0; | ||||
|   virtual ~supersaver() = default; | ||||
|   }; | ||||
|  | ||||
| typedef vector<shared_ptr<supersaver>> saverlist; | ||||
| @@ -56,7 +56,7 @@ struct setting { | ||||
|     return parameter_name + "|" + config_name + "|" + menu_item_name + "|" + help_text; | ||||
|     } | ||||
|   virtual cld get_cld() = 0; | ||||
|   setting() { restrict = auto_restrict; is_editable = false; } | ||||
|   explicit setting() { restrict = auto_restrict; is_editable = false; } | ||||
|   virtual void check_change() { | ||||
|     cld val = get_cld(); | ||||
|     if(val != last_value) { | ||||
| @@ -68,7 +68,7 @@ struct setting { | ||||
|   setting *set_sets(const reaction_t& s) { sets = s; return this; } | ||||
|   setting *set_extra(const reaction_t& r); | ||||
|   setting *set_reaction(const reaction_t& r); | ||||
|   virtual ~setting() {} | ||||
|   virtual ~setting() = default; | ||||
|   virtual void load_from(const string& s) { | ||||
|     println(hlog, "cannot load this parameter"); | ||||
|     exit(1); | ||||
| @@ -100,7 +100,7 @@ struct list_setting : setting { | ||||
|     default_key = key; | ||||
|     return this; | ||||
|     } | ||||
|   virtual void show_edit_option(char key) override; | ||||
|   void show_edit_option(char key) override; | ||||
|   }; | ||||
|  | ||||
| template<class T> struct enum_setting : list_setting { | ||||
| @@ -108,10 +108,10 @@ template<class T> struct enum_setting : list_setting { | ||||
|   T dft; | ||||
|   int get_value() override { return (int) *value; } | ||||
|   void set_value(int i) override { *value = (T) i; } | ||||
|   virtual bool affects(void* v) override { return v == value; } | ||||
|   virtual void add_as_saver() override; | ||||
|   virtual cld get_cld() override { return get_value(); } | ||||
|   virtual void load_from(const string& s) override { | ||||
|   bool affects(void* v) override { return v == value; } | ||||
|   void add_as_saver() override; | ||||
|   cld get_cld() override { return get_value(); } | ||||
|   void load_from(const string& s) override { | ||||
|     *value = (T) parseint(s); | ||||
|     } | ||||
|   }; | ||||
| @@ -134,11 +134,10 @@ struct float_setting : public setting { | ||||
|   function<void(float_setting*)> modify_me; | ||||
|   float_setting *modif(const function<void(float_setting*)>& r) { modify_me = r; return this; } | ||||
|   void add_as_saver() override; | ||||
|   virtual bool affects(void *v) override { return v == value; } | ||||
|   virtual void show_edit_option(char key) override; | ||||
|   virtual cld get_cld() override { return *value; } | ||||
|  | ||||
|   virtual void load_from(const string& s) override; | ||||
|   bool affects(void *v) override { return v == value; } | ||||
|   void show_edit_option(char key) override; | ||||
|   cld get_cld() override { return *value; } | ||||
|   void load_from(const string& s) override; | ||||
|   }; | ||||
|  | ||||
| struct int_setting : public setting { | ||||
| @@ -149,9 +148,9 @@ struct int_setting : public setting { | ||||
|   void add_as_saver() override; | ||||
|   function<void(int_setting*)> modify_me; | ||||
|   int_setting *modif(const function<void(int_setting*)>& r) { modify_me = r; return this; } | ||||
|   virtual bool affects(void *v) override { return v == value; } | ||||
|   virtual void show_edit_option(char key) override; | ||||
|   virtual cld get_cld() override { return *value; } | ||||
|   bool affects(void *v) override { return v == value; } | ||||
|   void show_edit_option(char key) override; | ||||
|   cld get_cld() override { return *value; } | ||||
|   int_setting *editable(int min_value, int max_value, ld step, string menu_item_name, string help_text, char key) { | ||||
|     this->min_value = min_value; | ||||
|     this->max_value = max_value; | ||||
| @@ -162,7 +161,7 @@ struct int_setting : public setting { | ||||
|     return this; | ||||
|     } | ||||
|  | ||||
|   virtual void load_from(const string& s) override { | ||||
|   void load_from(const string& s) override { | ||||
|     *value = parseint(s); | ||||
|     } | ||||
|   }; | ||||
| @@ -176,10 +175,10 @@ struct bool_setting : public setting { | ||||
|     is_editable = true; | ||||
|     menu_item_name = cap; default_key = key; return this;  | ||||
|     }  | ||||
|   virtual bool affects(void *v) override { return v == value; } | ||||
|   virtual void show_edit_option(char key) override; | ||||
|   virtual cld get_cld() override { return *value ? 1 : 0; } | ||||
|   virtual void load_from(const string& s) override { | ||||
|   bool affects(void *v) override { return v == value; } | ||||
|   void show_edit_option(char key) override; | ||||
|   cld get_cld() override { return *value ? 1 : 0; } | ||||
|   void load_from(const string& s) override { | ||||
|     *value = parseint(s); | ||||
|     } | ||||
|   }; | ||||
| @@ -188,9 +187,9 @@ struct custom_setting : public setting { | ||||
|   function<void(char)> custom_viewer; | ||||
|   function<cld()> custom_value; | ||||
|   function<bool(void*)> custom_affect; | ||||
|   virtual void show_edit_option(char key) override { custom_viewer(key); } | ||||
|   virtual cld get_cld() override { return custom_value(); } | ||||
|   virtual bool affects(void *v) override { return custom_affect(v); } | ||||
|   void show_edit_option(char key) override { custom_viewer(key); } | ||||
|   cld get_cld() override { return custom_value(); } | ||||
|   bool affects(void *v) override { return custom_affect(v); } | ||||
|   }; | ||||
|    | ||||
| #if CAP_CONFIG | ||||
| @@ -198,11 +197,11 @@ struct custom_setting : public setting { | ||||
| template<class T> struct dsaver : supersaver { | ||||
|   T& val; | ||||
|   T dft; | ||||
|   bool dosave() { return val != dft; } | ||||
|   void reset() { val = dft; } | ||||
|   dsaver(T& val) : val(val) { } | ||||
|   bool affects(void* v) { return v == &val; } | ||||
|   void set_default() { dft = val; } | ||||
|   bool dosave() override { return val != dft; } | ||||
|   void reset() override { val = dft; } | ||||
|   explicit dsaver(T& val) : val(val) { } | ||||
|   bool affects(void* v) override { return v == &val; } | ||||
|   void set_default() override { dft = val; } | ||||
|   }; | ||||
|  | ||||
| template<class T> struct saver : dsaver<T> {}; | ||||
| @@ -233,13 +232,13 @@ template<class T> void set_saver_default(T& val) { | ||||
| template<class T> struct saverenum : supersaver { | ||||
|   T& val; | ||||
|   T dft; | ||||
|   bool dosave() { return val != dft; } | ||||
|   void reset() { val = dft; } | ||||
|   saverenum<T>(T& v) : val(v) { } | ||||
|   string save() { return its(int(val)); } | ||||
|   void load(const string& s) { val = (T) atoi(s.c_str()); } | ||||
|   virtual bool affects(void* v) { return v == &val; } | ||||
|   virtual void set_default() { dft = val; } | ||||
|   explicit saverenum(T& v) : val(v) { } | ||||
|   bool dosave() override { return val != dft; } | ||||
|   void reset() override { val = dft; } | ||||
|   string save() override { return its(int(val)); } | ||||
|   void load(const string& s) override { val = (T) atoi(s.c_str()); } | ||||
|   bool affects(void* v) override { return v == &val; } | ||||
|   void set_default() override { dft = val; } | ||||
|   }; | ||||
|  | ||||
| template<class T, class U> void addsaverenum(T& i, U name, T dft) { | ||||
| @@ -254,39 +253,39 @@ template<class T, class U> void addsaverenum(T& i, U name) { | ||||
|   } | ||||
|  | ||||
| template<> struct saver<int> : dsaver<int> { | ||||
|   saver<int>(int& val) : dsaver<int>(val) { } | ||||
|   string save() { return its(val); } | ||||
|   void load(const string& s) { val = atoi(s.c_str()); } | ||||
|   explicit saver(int& val) : dsaver<int>(val) { } | ||||
|   string save() override { return its(val); } | ||||
|   void load(const string& s) override { val = atoi(s.c_str()); } | ||||
|   }; | ||||
|  | ||||
| template<> struct saver<char> : dsaver<char> { | ||||
|   saver<char>(char& val) : dsaver<char>(val) { } | ||||
|   string save() { return its(val); } | ||||
|   void load(const string& s) { val = atoi(s.c_str()); } | ||||
|   explicit saver(char& val) : dsaver<char>(val) { } | ||||
|   string save() override { return its(val); } | ||||
|   void load(const string& s) override { val = atoi(s.c_str()); } | ||||
|   }; | ||||
|  | ||||
| template<> struct saver<bool> : dsaver<bool> { | ||||
|   saver<bool>(bool& val) : dsaver<bool>(val) { } | ||||
|   string save() { return val ? "yes" : "no"; } | ||||
|   void load(const string& s) { val = isize(s) && s[0] == 'y'; } | ||||
|   explicit saver(bool& val) : dsaver<bool>(val) { } | ||||
|   string save() override { return val ? "yes" : "no"; } | ||||
|   void load(const string& s) override { val = isize(s) && s[0] == 'y'; } | ||||
|   }; | ||||
|  | ||||
| template<> struct saver<unsigned> : dsaver<unsigned> { | ||||
|   saver<unsigned>(unsigned& val) : dsaver<unsigned>(val) { } | ||||
|   string save() { return itsh(val); } | ||||
|   void load(const string& s) { val = (unsigned) strtoll(s.c_str(), NULL, 16); } | ||||
|   explicit saver(unsigned& val) : dsaver<unsigned>(val) { } | ||||
|   string save() override { return itsh(val); } | ||||
|   void load(const string& s) override { val = (unsigned) strtoll(s.c_str(), NULL, 16); } | ||||
|   }; | ||||
|  | ||||
| template<> struct saver<string> : dsaver<string> { | ||||
|   saver<string>(string& val) : dsaver<string>(val) { } | ||||
|   string save() { return val; } | ||||
|   void load(const string& s) { val = s; } | ||||
|   explicit saver(string& val) : dsaver<string>(val) { } | ||||
|   string save() override { return val; } | ||||
|   void load(const string& s) override { val = s; } | ||||
|   }; | ||||
|  | ||||
| template<> struct saver<ld> : dsaver<ld> { | ||||
|   saver<ld>(ld& val) : dsaver<ld>(val) { } | ||||
|   string save() { return fts(val, 10); } | ||||
|   void load(const string& s) {  | ||||
|   explicit saver(ld& val) : dsaver<ld>(val) { } | ||||
|   string save() override { return fts(val, 10); } | ||||
|   void load(const string& s) override { | ||||
|     if(s == "0.0000000000e+000") ; // ignore! | ||||
|     else val = atof(s.c_str());  | ||||
|     } | ||||
|   | ||||
							
								
								
									
										28
									
								
								drawing.cpp
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								drawing.cpp
									
									
									
									
									
								
							| @@ -56,7 +56,7 @@ struct drawqueueitem { | ||||
|   virtual void draw() = 0; | ||||
|   /** \brief Draw the object as background. */ | ||||
|   virtual void draw_back() {} | ||||
|   virtual ~drawqueueitem() {} | ||||
|   virtual ~drawqueueitem() = default; | ||||
|   /** \brief When minimizing OpenGL calls, we need to group items of the same color, etc. together. This value is used as an extra sorting key. */ | ||||
|   virtual color_t outline_group() = 0; | ||||
|   }; | ||||
| @@ -85,12 +85,12 @@ struct dqi_poly : drawqueueitem { | ||||
|   hyperpoint intester; | ||||
|   /** \brief temporarily cached data */ | ||||
|   float cache; | ||||
|   void draw(); | ||||
|   void draw() override; | ||||
|   #if CAP_GL | ||||
|   void gldraw(); | ||||
|   #endif | ||||
|   void draw_back(); | ||||
|   virtual color_t outline_group() { return outline; } | ||||
|   void draw_back() override; | ||||
|   color_t outline_group() override { return outline; } | ||||
|   }; | ||||
|  | ||||
| /** \brief Drawqueueitem used to draw lines */ | ||||
| @@ -101,9 +101,9 @@ struct dqi_line : drawqueueitem { | ||||
|   int prf; | ||||
|   /** \brief width of this line */ | ||||
|   double width; | ||||
|   void draw(); | ||||
|   void draw_back(); | ||||
|   virtual color_t outline_group() { return color; } | ||||
|   void draw() override; | ||||
|   void draw_back() override; | ||||
|   color_t outline_group() override { return color; } | ||||
|   }; | ||||
|  | ||||
| /** \brief Drawqueueitem used to draw strings, using sccreen coodinates */       | ||||
| @@ -120,8 +120,8 @@ struct dqi_string : drawqueueitem { | ||||
|   int frame; | ||||
|   /** alignment (0-8-16) */ | ||||
|   int align; | ||||
|   void draw(); | ||||
|   virtual color_t outline_group() { return 1; } | ||||
|   void draw() override; | ||||
|   color_t outline_group() override { return 1; } | ||||
|   }; | ||||
|  | ||||
| /** Drawqueueitem used to draw circles, using screen coordinates */ | ||||
| @@ -134,16 +134,16 @@ struct dqi_circle : drawqueueitem { | ||||
|   color_t fillcolor; | ||||
|   /** \brief width of the circle */ | ||||
|   double linewidth; | ||||
|   void draw(); | ||||
|   virtual color_t outline_group() { return 2; } | ||||
|   void draw() override; | ||||
|   color_t outline_group() override { return 2; } | ||||
|   }; | ||||
|  | ||||
| /** \brief Perform an arbitrary action. May temporarily change the model, etc. */ | ||||
| struct dqi_action : drawqueueitem { | ||||
|   reaction_t action; | ||||
|   dqi_action(const reaction_t& a) : action(a) {} | ||||
|   void draw() { action(); } | ||||
|   virtual color_t outline_group() { return 2; } | ||||
|   explicit dqi_action(const reaction_t& a) : action(a) {} | ||||
|   void draw() override { action(); } | ||||
|   color_t outline_group() override { return 2; } | ||||
|   }; | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								game.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								game.cpp
									
									
									
									
									
								
							| @@ -44,7 +44,7 @@ EX int hrand(int i) { | ||||
| #if HDR | ||||
| template<class T, class... U> T pick(T x, U... u) { std::initializer_list<T> i = {x,u...}; return *(i.begin() + hrand(1+sizeof...(u))); } | ||||
| template<class T> void hrandom_shuffle(T* x, int n) { for(int k=1; k<n; k++) swap(x[k], x[hrand(k+1)]); } | ||||
| template<class T> void hrandom_shuffle(T& container) { hrandom_shuffle(&container[0], isize(container)); } | ||||
| template<class T> void hrandom_shuffle(T& container) { hrandom_shuffle(container.data(), isize(container)); } | ||||
| template<class U> auto hrand_elt(U& container) -> decltype(container[0]) { return container[hrand(isize(container))]; } | ||||
| template<class T, class U> T hrand_elt(U& container, T default_value) {  | ||||
|   if(container.empty()) return default_value;  | ||||
|   | ||||
| @@ -105,6 +105,7 @@ struct subcellshape { | ||||
|   vector<hyperpoint> vertices_only; | ||||
|   vector<hyperpoint> vertices_only_local; | ||||
|   vector<hyperpoint> face_centers; | ||||
|   vector<vector<bool>> dirs_adjacent; | ||||
|   hyperpoint cellcenter; | ||||
|   transmatrix to_cellcenter; | ||||
|   transmatrix from_cellcenter; | ||||
| @@ -151,7 +152,7 @@ struct geometry_information { | ||||
|  | ||||
|   ld adjcheck; | ||||
|   ld strafedist; | ||||
|   bool dirs_adjacent[32][32]; | ||||
|   vector<vector<bool>> dirs_adjacent; | ||||
|  | ||||
|   ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part; | ||||
|    | ||||
|   | ||||
| @@ -1860,8 +1860,8 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t | ||||
|       queuepoly(VAHEAD, cgi.shFamiliarHead, darkena(0xC04000, 0, 0xFF)); | ||||
|       // queuepoly(V, cgi.shCatLegs, darkena(0x902000, 0, 0xFF)); | ||||
|       if(true) { | ||||
|         queuepoly(VAHEAD, cgi.shFamiliarEye, darkena(0xFFFF000, 0, 0xFF)); | ||||
|         queuepoly(VAHEAD * Mirror, cgi.shFamiliarEye, darkena(0xFFFF000, 0, 0xFF)); | ||||
|         queuepoly(VAHEAD, cgi.shFamiliarEye, darkena(0xFFFF00, 0, 0xFF)); | ||||
|         queuepoly(VAHEAD * Mirror, cgi.shFamiliarEye, darkena(0xFFFF00, 0, 0xFF)); | ||||
|         } | ||||
|       return true; | ||||
|       } | ||||
| @@ -2096,7 +2096,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t | ||||
|       b--; | ||||
|       if(b < 0) b = 0; | ||||
|       if(b > 6) b = 6; | ||||
|       queuepoly(VHEAD1, cgi.shWightCloak, (0x605040A0 | UNTRANS) + 0x10101000 * b); | ||||
|       queuepoly(VHEAD1, cgi.shWightCloak, color_t(0x605040A0 | UNTRANS) + color_t(0x10101000 * b)); | ||||
|       return true; | ||||
|       } | ||||
|  | ||||
|   | ||||
							
								
								
									
										32
									
								
								hprint.cpp
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								hprint.cpp
									
									
									
									
									
								
							| @@ -122,25 +122,25 @@ struct hstream_exception : hr_exception { hstream_exception() {} }; | ||||
|  | ||||
| struct fhstream : hstream { | ||||
|   color_t vernum; | ||||
|   virtual color_t get_vernum() override { return vernum; } | ||||
|   FILE *f; | ||||
|   virtual void write_char(char c) override { write_chars(&c, 1); } | ||||
|   virtual void write_chars(const char* c, size_t i) override { if(fwrite(c, i, 1, f) != 1) throw hstream_exception(); } | ||||
|   virtual void read_chars(char* c, size_t i) override { if(fread(c, i, 1, f) != 1) throw hstream_exception(); } | ||||
|   virtual char read_char() override { char c; read_chars(&c, 1); return c; } | ||||
|   fhstream() { f = NULL; vernum = VERNUM_HEX; } | ||||
|   fhstream(const string pathname, const char *mode) { f = fopen(pathname.c_str(), mode); vernum = VERNUM_HEX; } | ||||
|   explicit fhstream() { f = NULL; vernum = VERNUM_HEX; } | ||||
|   explicit fhstream(const string pathname, const char *mode) { f = fopen(pathname.c_str(), mode); vernum = VERNUM_HEX; } | ||||
|   ~fhstream() { if(f) fclose(f); } | ||||
|   color_t get_vernum() override { return vernum; } | ||||
|   void write_char(char c) override { write_chars(&c, 1); } | ||||
|   void write_chars(const char* c, size_t i) override { if(fwrite(c, i, 1, f) != 1) throw hstream_exception(); } | ||||
|   void read_chars(char* c, size_t i) override { if(fread(c, i, 1, f) != 1) throw hstream_exception(); } | ||||
|   char read_char() override { char c; read_chars(&c, 1); return c; } | ||||
|   }; | ||||
|  | ||||
| struct shstream : hstream {  | ||||
|   color_t vernum; | ||||
|   virtual color_t get_vernum() override { return vernum; } | ||||
|   string s; | ||||
|   int pos; | ||||
|   shstream(const string& t = "") : s(t) { pos = 0; vernum = VERNUM_HEX; } | ||||
|   virtual void write_char(char c) override { s += c; } | ||||
|   virtual char read_char() override { if(pos == isize(s)) throw hstream_exception(); return s[pos++]; } | ||||
|   explicit shstream(const string& t = "") : s(t) { pos = 0; vernum = VERNUM_HEX; } | ||||
|   color_t get_vernum() override { return vernum; } | ||||
|   void write_char(char c) override { s += c; } | ||||
|   char read_char() override { if(pos == isize(s)) throw hstream_exception(); return s[pos++]; } | ||||
|   }; | ||||
|  | ||||
| inline void print(hstream& hs) {} | ||||
| @@ -243,11 +243,11 @@ int SDL_GetTicks(); | ||||
| struct logger : hstream { | ||||
|   int indentation; | ||||
|   bool doindent; | ||||
|   logger() { doindent = false; } | ||||
|   virtual void write_char(char c) { if(doindent) { doindent = false;  | ||||
|   explicit logger() { doindent = false; } | ||||
|   void write_char(char c) override { if(doindent) { doindent = false;  | ||||
|     if(debugflags & DF_TIME) { int t = SDL_GetTicks(); if(t < 0) t = 999999; t %= 1000000; string s = its(t); while(isize(s) < 6) s = "0" + s; for(char c: s) special_log(c); special_log(' '); } | ||||
|     for(int i=0; i<indentation; i++) special_log(' '); } special_log(c); if(c == 10) doindent = true; if(c == 10 && debugfile) fflush(debugfile); } | ||||
|   virtual char read_char() { throw hstream_exception(); } | ||||
|   char read_char() override { throw hstream_exception(); } | ||||
|   }; | ||||
|  | ||||
| extern logger hlog; | ||||
| @@ -278,11 +278,11 @@ inline void print(hstream& hs, cellwalker cw) { | ||||
| struct indenter { | ||||
|   dynamicval<int> ind; | ||||
|    | ||||
|   indenter(int i = 2) : ind(hlog.indentation, hlog.indentation + (i)) {} | ||||
|   explicit indenter(int i = 2) : ind(hlog.indentation, hlog.indentation + (i)) {} | ||||
|   }; | ||||
|  | ||||
| struct indenter_finish : indenter { | ||||
|   indenter_finish(bool b = true): indenter(b ? 2:0) {} | ||||
|   explicit indenter_finish(bool b = true): indenter(b ? 2:0) {} | ||||
|   ~indenter_finish() { if(hlog.indentation != ind.backup) println(hlog, "(done)"); } | ||||
|   }; | ||||
|  | ||||
|   | ||||
| @@ -19,10 +19,10 @@ template<class T, class R, class... Args> | ||||
| struct function_state : function_state_base<R, Args...> { | ||||
|     T t_; | ||||
|     explicit function_state(T t) : t_(std::move(t)) {} | ||||
|     R call(Args... args) const /*override*/ { | ||||
|     R call(Args... args) const override { | ||||
|         return const_cast<T&>(t_)(static_cast<Args&&>(args)...); | ||||
|     } | ||||
|     function_state_base<R, Args...> *clone() const /*override*/ { | ||||
|     function_state_base<R, Args...> *clone() const override { | ||||
|         return new function_state(*this); | ||||
|     } | ||||
| }; | ||||
|   | ||||
| @@ -21,7 +21,7 @@ EX namespace inforder { | ||||
|  | ||||
|   struct hrmap_inforder : hrmap_hyperbolic { | ||||
|  | ||||
|     heptagon *create_step(heptagon *h, int direction) { | ||||
|     heptagon *create_step(heptagon *h, int direction) override { | ||||
|       int deg = h->type; | ||||
|       if(mixed()) deg = 7 - deg; | ||||
|       auto h1 = init_heptagon(deg); | ||||
|   | ||||
							
								
								
									
										2
									
								
								kite.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								kite.cpp
									
									
									
									
									
								
							| @@ -339,7 +339,7 @@ struct hrmap_kite : hrmap { | ||||
|     return gm * where; | ||||
|     } | ||||
|  | ||||
|   virtual int wall_offset(cell *c) { | ||||
|   int wall_offset(cell *c) override { | ||||
|     if(WDIM == 3) | ||||
|       return kite::getshape(c->master) == kite::pKite ? 10 : 0; | ||||
|     else | ||||
|   | ||||
| @@ -525,7 +525,7 @@ S("(Menu button) and select the ASCII mode, which runs much faster. " | ||||
|  | ||||
| S("(in the MENU). You can reduce the sight range, this should make " | ||||
|  "the animations smoother.", | ||||
|  "(в MENU). Вы можете уменьшить радиус обзора, что сделает анимацию более гладкой. ") | ||||
|  "(в МЕНЮ). Вы можете уменьшить радиус обзора, чтобы сделать анимацию более гладкой.") | ||||
|  | ||||
| S("(press v) and change the wall/monster mode to ASCII, or change " | ||||
|  "the resolution.", | ||||
| @@ -1450,7 +1450,7 @@ S("This Orb allows you to create illusions of yourself. Illusions are targeted " | ||||
|   "так же как Вас, Тамперы и ваших союзников.\n\n" | ||||
|   "Каждая иллюзия требует 5 зарядов для создания и по одному в каждый ход. " | ||||
|   "Также Вы можете кликнуть на иллюзию, чтобы забрать её, потратив 3 заряда.\n\n" | ||||
|   "Если у Вас есть сферы Хитрости и Телепорта, Иллюзия работает первой -- Вы можете" | ||||
|   "Если у Вас есть сферы Хитрости и Телепорта, Иллюзия работает первой -- Вы можете " | ||||
|   "потом телепортироваться на неё, чтобы поменяться с ней местами.") | ||||
|                       // Иллюзии "Хитрости" | ||||
| S("Illusions are targeted by most monsters, just like yourself, Thumpers, and your friends.", | ||||
| @@ -1613,7 +1613,7 @@ S("This land contains high rock formations. Most of the valley is at level 0, " | ||||
|   "or to lose three levels, in a single move, (attacks are possible at any " | ||||
|   "difference, though). Kill Red Trolls and Rock Snakes to make a cell higher.", | ||||
|   | ||||
|   "Эта земля содержт участки высоких скал. Большая часть долины находится на уровне 0, " | ||||
|   "Эта земля содержит участки высоких скал. Большая часть долины находится на уровне 0, " | ||||
|   "а все предметы лежат на уровне 3. Невозможно подняться на 2 или больше уровня " | ||||
|   "или опуститься на 3 уровня за один ход, хотя атаковать можно всегда. " | ||||
|   "Убейте Красного тролля или Каменную змею, чтобы сделать клетку выше.") | ||||
| @@ -1784,7 +1784,7 @@ N("Albatross", GEN_M, "Альбатрос", "Альбатросы", "Альба | ||||
| S( | ||||
|   "Those large seabirds attack you for some reason. At least they are not " | ||||
|   "as fast as Eagles...", | ||||
|   "Эти большие морские птицв почему-то атакуют Вас. Они хотя бы не такие " | ||||
|   "Эти большие морские птицы почему-то атакуют Вас. Они хотя бы не такие " | ||||
|   "быстрые, как Орлы...") | ||||
|   | ||||
| N("stranded boat", GEN_F, "лодка на мели", "лодки на мели", "лодку на мели", "в лодке на мели") | ||||
| @@ -2479,7 +2479,7 @@ S("forbidden to find in %the1", "запрещена %abl1") | ||||
| S("too dangerous to use in %the1", "слишком опасна %abl1") | ||||
| S("useless in %the1", "бесполезна %abl1") | ||||
| S("only native Orbs allowed in %the1", "только родные сферы доступны %abl1") | ||||
| S("this Orb is never unlocked globally (only hubs)", "эта сфера открывается только ы Центрах") | ||||
| S("this Orb is never unlocked globally (only hubs)", "эта сфера открывается только в Центрах") | ||||
| S("collect 25 %2 to unlock it in %the1", "соберите 25x %2, чтобы открыть её %abl1") | ||||
| S("collect 3 %2 to unlock it in %the1","соберите 3x %2, чтобы открыть её %abl1") | ||||
| S("native to %the1 (collect 10 %2)", "родная %abl1 (10x %2)") | ||||
| @@ -2900,7 +2900,7 @@ S( | ||||
|   | ||||
| S("Yendor Challenge", "Миссия Йендора") | ||||
| S("Collect 10 treasures in various lands to unlock the challenges there", | ||||
|   "Собирайте 10 сокровищ в разных землях, чтобы разблокировать миссии здесь") | ||||
|   "Собирайте 10 сокровищ в разных землях, чтобы открыть миссии здесь") | ||||
|   | ||||
| S("easy", "легко") | ||||
| S("challenge", "испытание") | ||||
| @@ -2956,9 +2956,6 @@ S( | ||||
| S("Unlock this challenge by getting the Orb of Yendor!", | ||||
|   "Откройте этот режим, собрав сферу Йендора!") | ||||
|   | ||||
| S("Collect 10 treasures in various lands to unlock the challenges there", | ||||
|   "Собирайте 10 сокровищ в разных землях, чтобы открыть миссии здесь") | ||||
|   | ||||
| // Wild West | ||||
| // ---------- | ||||
|   | ||||
| @@ -3986,9 +3983,6 @@ S("\n\nOnce you collect 10 Bomberbird Eggs, " | ||||
| S("This might be very useful for devices with limited memory.", | ||||
|   "Это может быть полезно для устройств с ограниченной памятью.") | ||||
|    | ||||
| S("(in the MENU). You can reduce the sight range, this should make the animations smoother.", | ||||
|   "(в МЕНЮ). Вы можете уменьшить радиус обзора, чтобы сделать анимацию более гладкой.") | ||||
|  | ||||
| S("Unavailable in the shmup mode.\n", "Недоступно в режиме стрельбы.\n") | ||||
| S("Unavailable in the multiplayer mode.\n", "Недоступно в режиме нескольких игроков.\n") | ||||
| S("Unavailable in the Chaos mode.\n", "Недоступно в режиме Хаоса.\n") | ||||
| @@ -4575,27 +4569,6 @@ S("You gain your protective Shell back!", "Вы вернули свою рако | ||||
|  | ||||
| S("rainbow landscape", "радужный пейзаж") | ||||
| S("Cannot use %the1 here!", "Нельзя использовать %a1 здесь!") | ||||
| S("draw the grid", "нарисовать сетку") | ||||
| S("Escher/3D", "Эшер/3D") | ||||
| S("plain/3D", "простой/3D") | ||||
| S("3D", "3D") | ||||
| S("Welcome to Halloween!", "Добро пожаловать на Хэллоуин!") | ||||
|  | ||||
| S("How long should the messages stay on the screen.", | ||||
|   "Как долго сообщения остаются на экране") | ||||
| S("select this color", "выбери этот цвет") | ||||
| S("sound effects volume", "громкость звуковых эффектов") | ||||
|  | ||||
| S("\n\nSee sounds/credits.txt for credits for sound effects",  | ||||
|   "\n\nБлагодарности за звуковые эффекты: sounds/credits.txt") | ||||
|  | ||||
| S("scrolling speed", "скорость проматывания") | ||||
| S("movement animation speed", "скорость анимации движения") | ||||
| S("+5 = move instantly", "+5 = мгновенное движение") | ||||
| S("extra graphical effects", "дополнительные графические эффекты") | ||||
|  | ||||
| S("rainbow landscape", "радужный пейзаж") | ||||
| S("Cannot use %the1 here!", "Невозможно использовать %a1 here!") | ||||
| S("draw the grid", "рисовать сетку") | ||||
| S("Escher/3D", "Эшер/3D") | ||||
| S("plain/3D", "простой/3D") | ||||
| @@ -4612,15 +4585,13 @@ S("\n\nSee sounds/credits.txt for credits for sound effects", | ||||
|  | ||||
| S("scrolling speed", "скорость прокрутки") | ||||
| S("movement animation speed", "скорость анимации движения") | ||||
| S("+5 = move instantly", "+5 = мгновенный ход") | ||||
| S("+5 = move instantly", "+5 = мгновенное движение") | ||||
| S("extra graphical effects", "дополнительные графические эффекты") | ||||
|  | ||||
| // VERSION 9.3 | ||||
| // =========== | ||||
|   | ||||
| S("SORT", "СОРТИРУЙ") | ||||
| S("PICK", "ВЫБИРАЙ") | ||||
| S("PLAY", "ИГРАЙ") | ||||
| S("PICK", "ВЫБИРАТЬ") | ||||
|   | ||||
| // 3D configuration | ||||
| // ---------------- | ||||
| @@ -5204,7 +5175,7 @@ S("Try the Guided Tour to help with understanding the " | ||||
|   "geometry of HyperRogue (menu -> special modes).\n\n", | ||||
|   "Попробуйте Руководство, чтобы понять геометрию HyperRogue (меню -> специальные режимы.\n\n") | ||||
|   | ||||
| S("guided tour", "Руководство") | ||||
| S("guided tour", "руководство") | ||||
| S("spherical geometry", "сферическая геометрия") | ||||
| S("Euclidean geometry", "евклидова геометрия") | ||||
| S("more curved hyperbolic geometry", "более искривлённая геометрия") | ||||
| @@ -5444,7 +5415,7 @@ S("The game is normally displayed in the so called Poincaré disk model, " | ||||
|   "прямыми линиями.") | ||||
|   | ||||
| S("Curvature", "Кривизна") | ||||
| S("gain Orb of the Sword", "получи Сферу меча") | ||||
| S("gain Orb of the Sword", "дать сферу Меча") | ||||
| S( | ||||
|   "Now, go to the Burial Grounds and find an Orb of the Sword. The Sword appears to " | ||||
|   "always be facing in the same direction whatever you do, and it appears that " | ||||
| @@ -5713,7 +5684,7 @@ S("aura smoothening factor", "сглаживание ауры") | ||||
| S("graphics configuration", "настройка графики") | ||||
| S("special display modes", "специальные режимы отображения") | ||||
| S("openGL mode", "режим OpenGL") | ||||
| S("anti-aliasing", "anti-aliasing") | ||||
| S("anti-aliasing", "сглаживание") | ||||
| S("line width", "широта линии") | ||||
| S("configure panning and general keys", "настроить панораму и общие клавиши") | ||||
|   | ||||
| @@ -5734,7 +5705,6 @@ S("four triangles", "четыре треугольника") | ||||
| S("big triangles: rings", "большие треугольники: кольца") | ||||
|   | ||||
| // missing for the Tutorial | ||||
| S("guided tour", "руководство") | ||||
| S("This Orb is not compatible with the Tutorial.", "Эта сфера не совместима с Руководством.") | ||||
|   | ||||
| // local scores | ||||
| @@ -5971,7 +5941,6 @@ S("puzzles and exploration", "головоломки и изучение") | ||||
|  | ||||
| S("Zebra quotient", "фактор Зебры") | ||||
| S("field quotient", "фактор поля") | ||||
| S("mark heptagons", "пометить семиугольники") | ||||
| S("projection", "проекция") | ||||
| S("compass size", "размер компаса") | ||||
|   | ||||
| @@ -6040,7 +6009,7 @@ S( | ||||
|   | ||||
| S("skip the start menu", "пропустить начальное меню") | ||||
| S("quick mouse", "быстрая мышь") | ||||
| S("This combination is known to be buggy at the moment.", "Эта комбинация пока что работает с ошибками.") | ||||
| S("This combination is known to be buggy at the moment.", "Эта комбинация сейчас может работать с ошибками.") | ||||
|   | ||||
| // extra Princess texts | ||||
| // -------------------- | ||||
| @@ -6483,8 +6452,8 @@ S("Useless in Euclidean geometry.", "Бесполезно в Евклидово | ||||
| S("Not implemented for spherical geometry. Please tell me if you really want this.", | ||||
|   "Не реализовано для сферической геометрии. Напиши мне, если очень хочешь.") | ||||
|   | ||||
| S("score: %1", "Очки: %1") | ||||
| S("kills: %1", "Убийства: %1") | ||||
| S("score: %1", "счёт: %1") | ||||
| S("kills: %1", "убийства: %1") | ||||
|    | ||||
|   | ||||
| // === 10.3 === | ||||
| @@ -6508,9 +6477,6 @@ S("bestiary of %the1", "бестиарий: %1") | ||||
| // for the map editor | ||||
| N("Dragon Head", GEN_F, "Голова Дракона", "Головы Дракона", "Голову Дракона", "Головой Дракона") | ||||
|   | ||||
| S("score: %1", "счет: %1") | ||||
| S("kills: %1", "убийств: %1") | ||||
|   | ||||
| // advanced config of quotient geometry | ||||
| //-------------------------------------- | ||||
|   | ||||
| @@ -6647,7 +6613,6 @@ S("reactivate the texture", "восстановить текстуру") | ||||
| S("open PNG as texture", "открыть PNG как текстуру") | ||||
| S("load texture config", "загрузить настройки текстур") | ||||
| S("warning: unable to find the center", "осторожно: не найден центр") | ||||
| S("texture size", "размер текстура") | ||||
| S("paint a new texture", "нарисовать новую текстуру") | ||||
| S("precision", "точность") | ||||
|   | ||||
| @@ -7199,7 +7164,6 @@ S("This land does not work in the current settings. Reason not available.", | ||||
|   "Эта земля не работает при данных настройках. Причина недоступна.") | ||||
| S("This land does not work well in the current settings. Reason not available.", | ||||
|   "Эта земля плохо работает при данных настройках. Причина недоступна.") | ||||
| S("This combination is known to be buggy at the moment.", "Эта комбинация сейчас может работать с ошибками.") | ||||
| S("Somewhat sloppy pattern.", "Небрежный узор.") | ||||
| S("Fractal landscapes not implemented in this geometry.", "Фракталы не реализованы в этой геометрии.") | ||||
| S("Only simplified walls implemented.", "Реализованы только упрощенные стены.") | ||||
| @@ -7221,21 +7185,10 @@ S("Goldberg", "Гольдберг") | ||||
| S("fisheye", "рыбий глаз") | ||||
| S("extend the ends", "расширить концы") // for the line animation | ||||
|   | ||||
| S( | ||||
|   "This model maps the world so that the distances from two points " | ||||
|   "are kept. This parameter gives the distance from the two points to " | ||||
|   "the center.", | ||||
|   | ||||
|   "Эта модель отображает мир так, что расстояния от двух точек сохраняются. " | ||||
|   "Этот параметр задает расстояние от этих двух точек до центра. ") | ||||
|   | ||||
| // missing texts from the Tutorial | ||||
|   | ||||
| S("enable the Camelot cheat", "включить читы в Камелоте") | ||||
| S("disable the Camelot cheat", "выключить читы в Камелоте") | ||||
| S("gain Orb of the Sword", "дать сферу Меча") | ||||
| S("Static mode enabled.", "Статический режим включен.") | ||||
| S("Static mode disabled.", "Статический режим выключен.") | ||||
|   | ||||
| S("Returned to your game.", "Вернуться в игру.") | ||||
| S("Spherical version of %the1. ", "%1 в сферической версии. ") | ||||
|   | ||||
| @@ -567,7 +567,7 @@ EX int totalbulldistance(cell *c, int k) { | ||||
|   shpos.resize(SHSIZE); | ||||
|   int tbd = 0; | ||||
|   for(int p: player_indices()) { | ||||
|     cell *c2  = shpos[p][(cshpos+SHSIZE-k-1)%SHSIZE]; | ||||
|     cell *c2  = shpos[(cshpos+SHSIZE-k-1)%SHSIZE][p]; | ||||
|     if(c2) tbd += bulldistance(c, c2); | ||||
|     } | ||||
|   return tbd; | ||||
|   | ||||
| @@ -664,10 +664,10 @@ EX namespace patterns { | ||||
|       si.reflect = false; | ||||
|       } | ||||
|     else { | ||||
|       int ids = 0, tids = 0, td = 0; | ||||
|       int ids = 0, td = 0; | ||||
|       for(int i=0; i<S3; i++) { | ||||
|         int d = c->move(2*i)->master->fieldval; | ||||
|         ids |= (1<<d); tids += d; | ||||
|         ids |= (1<<d); | ||||
|         } | ||||
|       for(int i=0; i<S3; i++) { | ||||
|         int d = c->move(2*i)->master->fieldval; | ||||
|   | ||||
| @@ -64,16 +64,16 @@ struct hrmap_quotient : hrmap_standard { | ||||
|    | ||||
|   void build(); | ||||
|    | ||||
|   hrmap_quotient() { | ||||
|   explicit hrmap_quotient() { | ||||
|     generate_connections();     | ||||
|     build(); | ||||
|     } | ||||
|  | ||||
|   hrmap_quotient(const vector<int>& con) : connections(con) { | ||||
|   explicit hrmap_quotient(const vector<int>& con) : connections(con) { | ||||
|     build(); | ||||
|     } | ||||
|  | ||||
|   heptagon *getOrigin() { return allh[0]; } | ||||
|   heptagon *getOrigin() override { return allh[0]; } | ||||
|  | ||||
|   ~hrmap_quotient() { | ||||
|     for(int i=0; i<isize(allh); i++) { | ||||
| @@ -82,7 +82,7 @@ struct hrmap_quotient : hrmap_standard { | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   vector<cell*>& allcells() { return celllist; } | ||||
|   vector<cell*>& allcells() override { return celllist; } | ||||
|   }; | ||||
| #endif | ||||
|    | ||||
|   | ||||
| @@ -331,7 +331,7 @@ void find_track(cell *start, int sign, int len) { | ||||
|   } | ||||
|  | ||||
| EX void block_cells(vector<cell*> to_block, function<bool(cell*)> blockbound) { | ||||
|   hrandom_shuffle(&to_block[0], isize(to_block)); | ||||
|   hrandom_shuffle(to_block); | ||||
|    | ||||
|   for(cell *c: to_block) switch(specialland) { | ||||
|     case laIce: | ||||
|   | ||||
							
								
								
									
										127
									
								
								reg3.cpp
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								reg3.cpp
									
									
									
									
									
								
							| @@ -256,9 +256,13 @@ EX namespace reg3 { | ||||
|     adjcheck = hdist(tC0(cgi.adjmoves[0]), tC0(cgi.adjmoves[1])) * 1.0001; | ||||
|  | ||||
|     int numedges = 0; | ||||
|     for(int a=0; a<S7; a++) for(int b=0; b<S7; b++) { | ||||
|       dirs_adjacent[a][b] = a != b && hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck; | ||||
|       if(dirs_adjacent[a][b]) numedges++; | ||||
|     dirs_adjacent.resize(S7); | ||||
|     for(int a=0; a<S7; a++) { | ||||
|       dirs_adjacent[a].resize(S7); | ||||
|       for(int b=0; b<S7; b++) { | ||||
|         dirs_adjacent[a][b] = a != b && hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck; | ||||
|         if(dirs_adjacent[a][b]) numedges++; | ||||
|         } | ||||
|       } | ||||
|     DEBB(DF_GEOM, ("numedges = ", numedges)); | ||||
|      | ||||
| @@ -612,6 +616,20 @@ EX namespace reg3 { | ||||
|       ss.faces_local = ss.faces; | ||||
|       for(auto& face: ss.faces_local) for(auto& v: face) v = ss.from_cellcenter * v; | ||||
|       for(auto& v: ss.vertices_only_local) v = ss.from_cellcenter * v; | ||||
|        | ||||
|       int N = isize(ss.faces); | ||||
|       ss.dirs_adjacent.resize(N); | ||||
|       for(int i=0; i<N; i++) { | ||||
|         auto& da = ss.dirs_adjacent[i]; | ||||
|         da.resize(N, false); | ||||
|         set<unsigned> cface; | ||||
|         for(auto& v: ss.faces[i]) cface.insert(bucketer(v)); | ||||
|         for(int j=0; j<N; j++) { | ||||
|           int mutual = 0; | ||||
|           for(auto& w: ss.faces[j]) if(cface.count(bucketer(w))) mutual++; | ||||
|           da[j] = mutual == 2; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     println(hlog, "subcells generated = ", isize(cgi.subshapes)); | ||||
| @@ -631,12 +649,13 @@ EX namespace reg3 { | ||||
|     int h_id; | ||||
|     /** transition matrix to that heptagon */ | ||||
|     transmatrix T; | ||||
|     /** the sequence of moves we need to make to get there */; | ||||
|     /** the sequence of moves we need to make to get there */ | ||||
|     vector<int> move_sequence; | ||||
|     }; | ||||
|    | ||||
|   struct hrmap_closed3 : hrmap { | ||||
|     vector<heptagon*> allh; | ||||
|     vector<vector<vector<int>>> strafe_data; | ||||
|     vector<vector<transmatrix>> tmatrices;     | ||||
|     vector<vector<transmatrix>> tmatrices_cell; | ||||
|     vector<cell*> acells; | ||||
| @@ -661,7 +680,7 @@ EX namespace reg3 { | ||||
|       return cgi.subshapes[id].vertices_only_local; | ||||
|       } | ||||
|  | ||||
|     transmatrix master_relative(cell *c, bool get_inverse) { | ||||
|     transmatrix master_relative(cell *c, bool get_inverse) override { | ||||
|       int id = local_id.at(c).second; | ||||
|       auto& ss = cgi.subshapes[id]; | ||||
|       return get_inverse ? ss.from_cellcenter : ss.to_cellcenter; | ||||
| @@ -670,9 +689,19 @@ EX namespace reg3 { | ||||
|     void make_subconnections(); | ||||
|      | ||||
|     int wall_offset(cell *c) override; | ||||
|     int shvid(cell *c) { return local_id.at(c).second; } | ||||
|     int shvid(cell *c) override { return local_id.at(c).second; } | ||||
|      | ||||
|     virtual transmatrix ray_iadj(cell *c, int i) override; | ||||
|     transmatrix ray_iadj(cell *c, int i) override; | ||||
|  | ||||
|     const vector<bool>& adjacent_dirs(cell *c, int i) override { | ||||
|       int id = local_id.at(c).second; | ||||
|       return cgi.subshapes[id].dirs_adjacent[i]; | ||||
|       } | ||||
|  | ||||
|     cellwalker strafe(cellwalker cw, int j) override { | ||||
|       int id = local_id.at(cw.at).first; | ||||
|       return cellwalker(cw.at->cmove(j), strafe_data[id][j][cw.spin]); | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|   struct hrmap_quotient3 : hrmap_closed3 { }; | ||||
| @@ -795,11 +824,15 @@ EX namespace reg3 { | ||||
|         which_cell[c->master->fieldval][bucketer(ss[id].face_centers[i])].emplace_back(c, i); | ||||
|       } | ||||
|      | ||||
|     strafe_data.resize(isize(acells)); | ||||
|      | ||||
|     for(cell *c: acells) { | ||||
|       int id = local_id[c].second;       | ||||
|       auto& tmcell = tmatrices_cell[local_id[c].first]; | ||||
|       int cid = local_id[c].first; | ||||
|       auto& tmcell = tmatrices_cell[cid]; | ||||
|       vector<int> foundtab; | ||||
|       vector<tuple<int, int, int>> foundtab_ids; | ||||
|       strafe_data[cid].resize(c->type); | ||||
|       for(int i=0; i<c->type; i++) { | ||||
|         int found = 0; | ||||
|         hyperpoint ctr = ss[id].face_centers[i]; | ||||
| @@ -837,6 +870,25 @@ EX namespace reg3 { | ||||
|                 auto& ms = move_sequences[local_id[c].first]; | ||||
|                 ms.push_back(path); | ||||
|                 for(auto dir: va.move_sequence) ms.back().push_back(dir); | ||||
|  | ||||
|                 auto& sd = strafe_data[cid][i];                 | ||||
|                 sd.resize(c->type, -1); | ||||
|                  | ||||
|                 for(int i1=0; i1<c->type; i1++) { | ||||
|                   set<unsigned> facevertices; | ||||
|                   for(auto v: ss[id].faces[i1]) facevertices.insert(bucketer(v)); | ||||
|                   if(ss[id].dirs_adjacent[i][i1]) { | ||||
|                     int found_strafe = 0; | ||||
|                     for(int j1=0; j1<c1->type; j1++) if(j1 != j) { | ||||
|                       int num = 0; | ||||
|                       for(auto v: ss[id1].faces[j1]) | ||||
|                         if(facevertices.count(bucketer(T2*v))) | ||||
|                           num++; | ||||
|                       if(num == 2) sd[i1] = j1, found_strafe++; | ||||
|                       } | ||||
|                     if(found_strafe != 1) println(hlog, "found_strafe = ", found_strafe); | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               foundtab_ids.emplace_back(va.h_id, id1, j); | ||||
|               found++; | ||||
| @@ -949,7 +1001,7 @@ EX namespace reg3 { | ||||
|       plane.insert(cw); | ||||
|       for(int i=0; i<S7; i++) | ||||
|         if(cgi.dirs_adjacent[i][cw.spin]) | ||||
|           make_plane(reg3::strafe(cw, i)); | ||||
|           make_plane(strafe(cw, i)); | ||||
|       } | ||||
|      | ||||
|      | ||||
| @@ -1437,6 +1489,21 @@ EX namespace reg3 { | ||||
|     vector<hyperpoint> get_vertices(cell* c) override { | ||||
|       return cgi.vertices_only; | ||||
|       } | ||||
|  | ||||
|     const vector<bool>& adjacent_dirs(cell *c, int i) override { | ||||
|       return cgi.dirs_adjacent[i]; | ||||
|       } | ||||
|  | ||||
|     cellwalker strafe(cellwalker cw, int j) override { | ||||
|       hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]); | ||||
|       cw.at->cmove(j); | ||||
|       transmatrix T = currentmap->adj(cw.at, j); | ||||
|       for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j)) | ||||
|         if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01) | ||||
|           return cellwalker(cw.at->cmove(j), i); | ||||
|       throw hr_exception("incorrect strafe"); | ||||
|       } | ||||
|  | ||||
|     }; | ||||
|  | ||||
|   struct hrmap_sphere3 : hrmap_closed3 { | ||||
| @@ -1515,7 +1582,7 @@ EX namespace reg3 { | ||||
|       clearfrom(allh[0]); | ||||
|       }     | ||||
|  | ||||
|     virtual struct transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override { | ||||
|     struct transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override { | ||||
|       return iso_inverse(locations[h1->fieldval]) * locations[h2->fieldval]; | ||||
|       } | ||||
|  | ||||
| @@ -1834,13 +1901,13 @@ EX namespace reg3 { | ||||
|       return relative_matrix_via_masters(c2, c1, hint); | ||||
|       } | ||||
|      | ||||
|     transmatrix master_relative(cell *c, bool get_inverse) { | ||||
|     transmatrix master_relative(cell *c, bool get_inverse) override { | ||||
|       if(PURE) return Id; | ||||
|       int aid = cell_id.at(c); | ||||
|       return quotient_map->master_relative(quotient_map->acells[aid], get_inverse); | ||||
|       } | ||||
|  | ||||
|     int shvid(cell *c) { | ||||
|     int shvid(cell *c) override { | ||||
|       if(PURE) return 0; | ||||
|       if(!cell_id.count(c)) return quotient_map->shvid(c); | ||||
|       int aid = cell_id.at(c); | ||||
| @@ -1896,12 +1963,36 @@ EX namespace reg3 { | ||||
|       c->c.connect(d, c1, ac->c.spin(d), false); | ||||
|       } | ||||
|  | ||||
|     virtual transmatrix ray_iadj(cell *c, int i) { | ||||
|     transmatrix ray_iadj(cell *c, int i) override { | ||||
|       if(PURE) return iadj(c, i); | ||||
|       if(!cell_id.count(c)) return quotient_map->ray_iadj(c, i); /* necessary because ray samples are from quotient_map */ | ||||
|       int aid = cell_id.at(c); | ||||
|       return quotient_map->ray_iadj(quotient_map->acells[aid], i); | ||||
|       } | ||||
|  | ||||
|     const vector<bool>& adjacent_dirs(cell *c, int i) override {  | ||||
|       if(PURE) return cgi.dirs_adjacent[i]; | ||||
|       int aid = cell_id.at(c); | ||||
|       return quotient_map->adjacent_dirs(quotient_map->acells[aid], i); | ||||
|       } | ||||
|  | ||||
|     cellwalker strafe(cellwalker cw, int j) override { | ||||
|  | ||||
|       hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]); | ||||
|       cw.at->cmove(j); | ||||
|       transmatrix T = currentmap->adj(cw.at, j); | ||||
|       cellwalker res1; | ||||
|       for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j)) | ||||
|         if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01) | ||||
|           res1 = cellwalker(cw.at->cmove(j), i); | ||||
|  | ||||
|       int aid = PURE ? cw.at->master->fieldval : cell_id.at(cw.at); | ||||
|       auto res = quotient_map->strafe(cellwalker(quotient_map->acells[aid], cw.spin), j); | ||||
|       cellwalker res2 = cellwalker(cw.at->cmove(j), res.spin); | ||||
|        | ||||
|       if(PURE && res1 != res2) println(hlog, "h3: ", res1, " vs ", res2); | ||||
|       return res2; | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|   struct hrmap_h3_rule_alt : hrmap { | ||||
| @@ -2229,16 +2320,6 @@ int dist_alt(cell *c) { | ||||
| // as possible to cw.spin. Assume that j and cw.spin are adjacent | ||||
|  | ||||
| #if MAXMDIM >= 4 | ||||
| EX cellwalker strafe(cellwalker cw, int j) { | ||||
|   hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]); | ||||
|   cw.at->cmove(j); | ||||
|   transmatrix T = currentmap->adj(cw.at, j); | ||||
|   for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j)) | ||||
|     if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01) | ||||
|       return cellwalker(cw.at->cmove(j), i); | ||||
|   throw hr_exception("incorrect strafe"); | ||||
|   } | ||||
|  | ||||
| EX int matrix_order(const transmatrix A) { | ||||
|   transmatrix T = A; | ||||
|   int res = 1; | ||||
|   | ||||
| @@ -1253,7 +1253,7 @@ void fillgroups() { | ||||
|   do_classify(); | ||||
|   vector<int> samples_to_sort; | ||||
|   for(int i=0; i<samples; i++) samples_to_sort.push_back(i); | ||||
|   hrandom_shuffle(&samples_to_sort[0], samples); | ||||
|   hrandom_shuffle(samples_to_sort); | ||||
|   for(int i=0; i<samples; i++) if(net[bids[i]].drawn_samples < net[bids[i]].max_group_here) | ||||
|     showsample(i); | ||||
|   distribute_neurons(); | ||||
|   | ||||
							
								
								
									
										8
									
								
								sky.cpp
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								sky.cpp
									
									
									
									
									
								
							| @@ -24,11 +24,11 @@ struct sky_item { | ||||
|  | ||||
| struct dqi_sky : drawqueueitem { | ||||
|   vector<sky_item> sky; | ||||
|   void draw(); | ||||
|   virtual color_t outline_group() { return 3; } | ||||
|   void draw() override; | ||||
|   color_t outline_group() override { return 3; } | ||||
|   // singleton | ||||
|   dqi_sky() { hr::sky = this; } | ||||
|   ~dqi_sky() { hr::sky = NULL; } | ||||
|   explicit dqi_sky() { hr::sky = this; } | ||||
|   ~dqi_sky() override { hr::sky = NULL; } | ||||
|   }; | ||||
|    | ||||
| EX struct dqi_sky *sky; | ||||
|   | ||||
| @@ -139,14 +139,14 @@ struct hrmap_spherical : hrmap_standard { | ||||
|     #endif | ||||
|     } | ||||
|  | ||||
|   heptagon *getOrigin() { return dodecahedron[0]; } | ||||
|   heptagon *getOrigin() override { return dodecahedron[0]; } | ||||
|  | ||||
|   ~hrmap_spherical() { | ||||
|     for(int i=0; i<spherecells(); i++) clearHexes(dodecahedron[i]); | ||||
|     for(int i=0; i<spherecells(); i++) tailored_delete(dodecahedron[i]); | ||||
|     }     | ||||
|  | ||||
|   void verify() { | ||||
|   void verify() override { | ||||
|     for(int i=0; i<spherecells(); i++) for(int k=0; k<S7; k++) { | ||||
|       heptspin hs(dodecahedron[i], k, false); | ||||
|       heptspin hs2 = hs + wstep + (S7-1) + wstep + (S7-1) + wstep + (S7-1); | ||||
| @@ -172,7 +172,7 @@ struct hrmap_spherical : hrmap_standard { | ||||
|     return Id; | ||||
|     } | ||||
|    | ||||
|   transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) { | ||||
|   transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) override { | ||||
|     transmatrix T = iso_inverse(get_where(c1)) * get_where(c2); | ||||
|     if(elliptic) fixelliptic(T); | ||||
|     return T; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue