mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-26 19:37:40 +00:00 
			
		
		
		
	customize land mode
This commit is contained in:
		| @@ -166,11 +166,11 @@ EX namespace brownian { | ||||
|     ONEMPTY { | ||||
|       if(hrand(10000) < min(250, 100 + 2 * PT(kills[moAcidBird] + kills[moBrownBug], 50)) * (25 + min(items[itBrownian], 100)) / 25 && c->landparam >= 4 && c->landparam < 24) | ||||
|         c->item = itBrownian; | ||||
|       if(hrand_monster(8000) < 15 + items[itBrownian]) | ||||
|       if(hrand_monster_in(laBrownian, 8000) < 15 + items[itBrownian]) | ||||
|         c->monst = moAcidBird; | ||||
|       else if(hrand_monster(8000) < 15) | ||||
|       else if(hrand_monster_in(laBrownian, 8000) < 15) | ||||
|         c->monst = moAlbatross; | ||||
|       else if(hrand_monster(8000) < 15 + items[itBrownian]) { | ||||
|       else if(hrand_monster_in(laBrownian, 8000) < 15 + items[itBrownian]) { | ||||
|         c->monst = moBrownBug; | ||||
|         c->hitpoints = 3; | ||||
|         } | ||||
| @@ -291,7 +291,7 @@ extern array<feature, 21> features; | ||||
|  | ||||
| #define VF [] (cell *c) | ||||
|  | ||||
| bool hrand_var(int i) { return hrand_monster(i) < 25 + items[itVarTreasure] + yendor::hardness(); } | ||||
| bool hrand_var(int i) { return hrand_monster_in(laVariant, i) < 25 + items[itVarTreasure] + yendor::hardness(); } | ||||
|  | ||||
| array<feature, 21> features {{ | ||||
|   feature{(color_t)(-0x202020), 5, moNecromancer, VF { | ||||
|   | ||||
							
								
								
									
										12
									
								
								config.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								config.cpp
									
									
									
									
									
								
							| @@ -1663,6 +1663,18 @@ EX void initConfig() { | ||||
|    | ||||
|   param_i(stamplen, "stamplen"); | ||||
|   param_f(anims::period, "animperiod"); | ||||
|  | ||||
|   addsaver(use_custom_land_list, "customland_use"); | ||||
|   for(int i=0; i<landtypes; i++) { | ||||
|     custom_land_list[i] = true; | ||||
|     custom_land_treasure[i] = 100; | ||||
|     custom_land_difficulty[i] = 100; | ||||
|     custom_land_wandering[i] = 100; | ||||
|     addsaver(custom_land_list[i], "customland" + its(i) + "i", true); | ||||
|     addsaver(custom_land_treasure[i], "customland" + its(i) + "t", 100); | ||||
|     addsaver(custom_land_difficulty[i], "customland" + its(i) + "d", 100); | ||||
|     addsaver(custom_land_wandering[i], "customland" + its(i) + "w", 100); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| EX bool inSpecialMode() { | ||||
|   | ||||
							
								
								
									
										24
									
								
								help.cpp
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								help.cpp
									
									
									
									
									
								
							| @@ -1089,16 +1089,7 @@ EX void describeMouseover() { | ||||
|   #endif | ||||
|   } | ||||
|  | ||||
| EX void showHelp() { | ||||
|   cmode = sm::HELP | sm::DOTOUR | sm::DARKEN; | ||||
|   getcstat = SDLK_ESCAPE; | ||||
|   if(help == "HELPFUN") { | ||||
|     help_delegate(); | ||||
|     return; | ||||
|     } | ||||
|  | ||||
|   gamescreen(); | ||||
|   string help2; | ||||
| EX void addHelpWithTitle() { | ||||
|   if(help[0] == '@') { | ||||
|     int iv = help.find("\t"); | ||||
|     int id = help.find("\n"); | ||||
| @@ -1109,6 +1100,19 @@ EX void showHelp() { | ||||
|     dialog::init("help", forecolor, 120, 100); | ||||
|     dialog::addHelp(help); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| EX void showHelp() { | ||||
|   cmode = sm::HELP | sm::DOTOUR | sm::DARKEN; | ||||
|   getcstat = SDLK_ESCAPE; | ||||
|   if(help == "HELPFUN") { | ||||
|     help_delegate(); | ||||
|     return; | ||||
|     } | ||||
|  | ||||
|   gamescreen(); | ||||
|   string help2; | ||||
|   addHelpWithTitle(); | ||||
|    | ||||
|   bool in_list = false; | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -566,7 +566,7 @@ typedef function<int(struct cell*)> cellfunction; | ||||
| // passable flags | ||||
|  | ||||
| #define SAGEMELT .1 | ||||
| #define PT(x, y) ((tactic::on || quotient == 2 || daily::on) ? (y) : inv::on ? min(2*(y),x) : (x)) | ||||
| #define PT(x, y) rebalance_treasure(x, y, c->land) | ||||
| #define ROCKSNAKELENGTH 50 | ||||
| #define WORMLENGTH 15 | ||||
| #define PRIZEMUL 7 | ||||
|   | ||||
							
								
								
									
										18
									
								
								landgen.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								landgen.cpp
									
									
									
									
									
								
							| @@ -171,8 +171,8 @@ EX void place_elemental_wall(cell *c) { | ||||
|   else if(c->land == laEEarth) c->wall = waStone; | ||||
|   } | ||||
|  | ||||
| // automatically adjust monster generation for 3D geometries | ||||
| EX int hrand_monster(int x) { | ||||
| // automatically adjust monster generation for 3D geometries and custom difficulty | ||||
| EX int hrand_monster_in(eLand l, int x) { | ||||
|   // dual geometry mode is much harder, so generate less monsters to balance it | ||||
|   if(dual::state) x *= 3; | ||||
|   // in 3D monster generation depends on the sight range | ||||
| @@ -180,9 +180,15 @@ EX int hrand_monster(int x) { | ||||
|     int t = isize(gmatrix); | ||||
|     if(t > 500) x = int(((long long)(x)) * t / 500); | ||||
|     } | ||||
|   if(use_custom_land_list) { | ||||
|     x = x * 100 / custom_land_difficulty[l]; | ||||
|     if(x == 0) x = 1; | ||||
|     } | ||||
|   return hrand(x); | ||||
|   } | ||||
|  | ||||
| #define hrand_monster(x) hrand_monster_in(c->land, x) | ||||
|  | ||||
| EX bool is_zebra_trapdoor(cell *c) { | ||||
|   if(euclid && closed_or_bounded) return false; | ||||
|   #if CAP_ARCM | ||||
| @@ -280,6 +286,12 @@ EX void gen_baby_tortoise(cell *c) { | ||||
|   tortoise::babymap[c] = tortoise::getb(c) ^ tortoise::getRandomBits(); | ||||
|   } | ||||
|  | ||||
| EX int rebalance_treasure(int x, int y, eLand l) { | ||||
|   int res = ((tactic::on || quotient == 2 || daily::on) ? (y) : inv::on ? min(2*(y),x) : (x)); | ||||
|   if(use_custom_land_list) res = (res * custom_land_treasure[l] + 50) / 100; | ||||
|   return res; | ||||
|   } | ||||
|  | ||||
| EX void giantLandSwitch(cell *c, int d, cell *from) { | ||||
|   bool fargen = d == 9; | ||||
|   switch(c->land) { | ||||
| @@ -3139,4 +3151,6 @@ EX void setdist(cell *c, int d, cell *from) { | ||||
| #endif | ||||
|   } | ||||
|  | ||||
| #undef hrand_monster | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										113
									
								
								landlock.cpp
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								landlock.cpp
									
									
									
									
									
								
							| @@ -712,8 +712,15 @@ EX eLand getLandForList(cell *c) { | ||||
|   return l; | ||||
|   } | ||||
|  | ||||
| EX bool use_custom_land_list; | ||||
| EX array<bool, landtypes> custom_land_list; | ||||
| EX array<int, landtypes> custom_land_treasure; | ||||
| EX array<int, landtypes> custom_land_difficulty; | ||||
| EX array<int, landtypes> custom_land_wandering; | ||||
|  | ||||
| EX bool isLandIngame(eLand l) { | ||||
|   if(isElemental(l)) l = laElementalWall; | ||||
|   if(use_custom_land_list) return custom_land_list[l]; | ||||
|   if(dual::state == 2 && !dual::check_side(l)) return false; | ||||
|   if((eubinary || sol) && isCyclic(l) && l != specialland) return false; | ||||
|   if(l == laCamelot && hyperbolic && WDIM == 3) return false; | ||||
| @@ -802,6 +809,112 @@ EX const int cursed_when = 386; | ||||
|  | ||||
| EX const int walls_when = 388; | ||||
|  | ||||
| EX void mark_tamper() { cheater++; } | ||||
|  | ||||
| EX void customize_land_in_list(eLand l) { | ||||
|   cmode = sm::DARKEN; gamescreen(); | ||||
|  | ||||
|   dialog::init(XLATN(linf[l].name), linf[l].color); | ||||
|  | ||||
|   help = generateHelpForLand(l); | ||||
|   addHelpWithTitle(); | ||||
|  | ||||
|   dialog::addBreak(100); | ||||
|  | ||||
|   dialog::addBoolItem(XLAT("land in game"), custom_land_list[l], 'a'); | ||||
|   dialog::add_action([l] { | ||||
|     custom_land_list[l] = !custom_land_list[l]; | ||||
|     cheater++; | ||||
|     }); | ||||
|  | ||||
|   dialog::addSelItem(XLAT("treasure rate"), its(custom_land_treasure[l]), 't'); | ||||
|   dialog::add_action([l] { | ||||
|     dialog::editNumber(custom_land_treasure[l], 0, 1000, 10, 100, XLAT("treasure rate in %the1", linf[l].name), ""); | ||||
|     dialog::get_ne().reaction = mark_tamper; | ||||
|     }); | ||||
|  | ||||
|   dialog::addSelItem(XLAT("difficulty"), its(custom_land_difficulty[l]), 'd'); | ||||
|   dialog::add_action([l] { | ||||
|     dialog::editNumber(custom_land_difficulty[l], 0, 1000, 10, 100, XLAT("difficulty of %the1", linf[l].name), ""); | ||||
|     dialog::get_ne().reaction = mark_tamper; | ||||
|     }); | ||||
|  | ||||
|   dialog::addSelItem(XLAT("wandering"), its(custom_land_wandering[l]), 'w'); | ||||
|   dialog::add_action([l] { | ||||
|     dialog::editNumber(custom_land_wandering[l], 0, 1000, 10, 100, XLAT("difficulty of %the1", linf[l].name), ""); | ||||
|     dialog::get_ne().reaction = mark_tamper; | ||||
|     }); | ||||
|  | ||||
|   dialog::addBack(); | ||||
|   dialog::display(); | ||||
|   } | ||||
|  | ||||
| EX void customize_land_list() { | ||||
|   cmode = sm::DARKEN; gamescreen(); | ||||
|   dialog::init(XLAT("custom land list")); | ||||
|   if(dialog::infix != "") mouseovers = dialog::infix; | ||||
|  | ||||
|   generateLandList([] (eLand l) { | ||||
|     if(!use_custom_land_list) { | ||||
|       custom_land_list[l] = isLandIngame(l); | ||||
|       custom_land_treasure[l] = 100; | ||||
|       custom_land_difficulty[l] = 100; | ||||
|       custom_land_wandering[l] = 100; | ||||
|       } | ||||
|     if(dialog::infix != "" && !dialog::hasInfix(linf[l].name)) return false; | ||||
|     if(l == laCanvas) return true; | ||||
|     return !!(land_validity(l).flags & lv::appears_in_geom_exp); | ||||
|     }); | ||||
|   stable_sort(landlist.begin(), landlist.end(), [] (eLand l1, eLand l2) { return land_validity(l1).quality_level > land_validity(l2).quality_level; }); | ||||
|  | ||||
|   dialog::start_list(900, 900, '1'); | ||||
|   for(eLand l: landlist) { | ||||
|     dialog::addBoolItem(XLAT1(linf[l].name), custom_land_list[l], dialog::list_fake_key++); | ||||
|     string s; | ||||
|     if(custom_land_treasure[l] != 100) s += "$" + its(custom_land_treasure[l]) + " "; | ||||
|     if(custom_land_difficulty[l] != 100) s += "!" + its(custom_land_difficulty[l]) + " "; | ||||
|     if(custom_land_wandering[l] != 100) s += "^" + its(custom_land_wandering[l]) + " "; | ||||
|     if(s != "") dialog::lastItem().value = s; | ||||
|     dialog::add_action_confirmed([l] { | ||||
|       stop_game(); | ||||
|       use_custom_land_list = true; | ||||
|       start_game(); | ||||
|       pushScreen([l] { customize_land_in_list(l); }); | ||||
|       }); | ||||
|     } | ||||
|   dialog::end_list(); | ||||
|  | ||||
|   dialog::addInfo(XLAT("press letters to search")); | ||||
|   dialog::addBoolItem("custom land list mode", use_custom_land_list, 'U'); | ||||
|   dialog::add_action_confirmed([] { | ||||
|     stop_game(); | ||||
|     use_custom_land_list = !use_custom_land_list; | ||||
|     start_game(); | ||||
|     }); | ||||
|  | ||||
|   dialog::addHelp(); | ||||
|   dialog::add_action([] { | ||||
|     gotoHelp(XLAT( | ||||
|       "In this mode, you can choose the lands you want to be in game. You can also customize their treasure rate and difficulty.\n\n" | ||||
|       "While the game automatically selects a list of lands by default, " | ||||
|       "based on whether it thinks they work well in the currently selected tiling, " | ||||
|       "you might not agree with this selection.\n\n" | ||||
|       "Note that, often, lands are enabled or disabled for a GOOD reason! Use at your own risk.\n\n" | ||||
|       "Just click on a land to configure it. If you are not in the custom land list mode, " | ||||
|       "this will restart the game. You can change the settings during a custom game, but it counts as a cheat." | ||||
|       )); | ||||
|     }); | ||||
|   dialog::addBack(); | ||||
|   dialog::display(); | ||||
|  | ||||
|   keyhandler = [] (int sym, int uni) { | ||||
|     dialog::handleNavigation(sym, uni); | ||||
|  | ||||
|     if(dialog::editInfix(uni)) dialog::list_skip = 0; | ||||
|     else if(doexiton(sym, uni)) popScreen(); | ||||
|     }; | ||||
|   } | ||||
|  | ||||
| // check if the given land should appear in lists | ||||
| EX land_validity_t& land_validity(eLand l) { | ||||
|  | ||||
|   | ||||
| @@ -206,6 +206,7 @@ EX modecode_t legacy_modecode() { | ||||
|   if(int(geometry) > 3 || int(variation) > 1) return UNKNOWN; | ||||
|   if(casual) return UNKNOWN; | ||||
|   if(bow::weapon) return UNKNOWN; | ||||
|   if(use_custom_land_list) return UNKNOWN; | ||||
|  | ||||
|   bool is_default_land_structure = | ||||
|     (princess::challenge || tactic::on) ? ls::single() : | ||||
|   | ||||
| @@ -685,6 +685,9 @@ EX void showChangeMode() { | ||||
|   multi::cpid = 0; | ||||
|   menuitem_land_structure('l'); | ||||
|  | ||||
|   dialog::addBoolItem(XLAT("custom land list"), use_custom_land_list, 'L'); | ||||
|   dialog::add_action_push(customize_land_list); | ||||
|  | ||||
|   dialog::addBoolItem(XLAT("weapon selection"), bow::weapon, 'b'); | ||||
|   dialog::add_action_push(bow::showMenu); | ||||
|  | ||||
|   | ||||
| @@ -192,7 +192,7 @@ EX int reptilemax() { | ||||
|   return r; | ||||
|   } | ||||
|  | ||||
| bool wchance(int a, int of, int reduction = 0) { | ||||
| bool wchance_in(eLand l, int a, int of, int reduction = 0) { | ||||
|   of *= 10;  | ||||
|   a += yendor::hardness() + 1; | ||||
|   if(isCrossroads(cwt.at->land))  | ||||
| @@ -206,6 +206,11 @@ bool wchance(int a, int of, int reduction = 0) { | ||||
|   a -= reduction; | ||||
|   if(a < 0) return false; | ||||
|  | ||||
|   if(use_custom_land_list) { | ||||
|     of *= 100; | ||||
|     a *= custom_land_wandering[l]; | ||||
|     } | ||||
|  | ||||
|   return hrand(a+of) < a; | ||||
|   } | ||||
|  | ||||
| @@ -337,7 +342,7 @@ EX void wandering() { | ||||
|   if(closed_or_bounded && specialland == laClearing) | ||||
|     clearing::new_root(); | ||||
|  | ||||
|   if(cwt.at->land == laZebra && cwt.at->wall == waNone && wchance(items[itZebra], 20)) | ||||
|   if(cwt.at->land == laZebra && cwt.at->wall == waNone && wchance_in(laZebra, items[itZebra], 20)) | ||||
|     wanderingZebra(cwt.at); | ||||
|  | ||||
|   bool smallbounded_generation = smallbounded || (closed_manifold && specialland == laClearing); | ||||
| @@ -371,6 +376,8 @@ EX void wandering() { | ||||
|     if(!valid(c)) continue; | ||||
|     if(isPlayerOn(c)) break; | ||||
|  | ||||
|     auto wchance = [c] (int a, int of, int reduction = 0) { return wchance_in(c->land, a, of, reduction); }; | ||||
|      | ||||
|     if(specialland == laStorms) { | ||||
|       // place the sandstone wall completely randomly (but not on the player) | ||||
|       vector<cell*>& ac = currentmap->allcells(); | ||||
|   | ||||
							
								
								
									
										10
									
								
								yendor.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								yendor.cpp
									
									
									
									
									
								
							| @@ -986,6 +986,16 @@ void save_mode_data(hstream& f) { | ||||
|     f.write<char>(bow::weapon); | ||||
|     f.write<char>(bow::style); | ||||
|     } | ||||
|   if(use_custom_land_list) { | ||||
|     f.write<char>(3); | ||||
|     f.write<int>(landtypes); | ||||
|     for(int i=0; i<landtypes; i++) { | ||||
|       f.write<char>(custom_land_list[i]); | ||||
|       f.write<int>(custom_land_treasure[i]); | ||||
|       f.write<int>(custom_land_difficulty[i]); | ||||
|       f.write<int>(custom_land_wandering[i]); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| EX modecode_t modecode(int mode) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue