mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-26 10:00:42 +00:00
customize land mode
This commit is contained in:
parent
e840e39ba0
commit
4421143ae5
@ -166,11 +166,11 @@ EX namespace brownian {
|
|||||||
ONEMPTY {
|
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)
|
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;
|
c->item = itBrownian;
|
||||||
if(hrand_monster(8000) < 15 + items[itBrownian])
|
if(hrand_monster_in(laBrownian, 8000) < 15 + items[itBrownian])
|
||||||
c->monst = moAcidBird;
|
c->monst = moAcidBird;
|
||||||
else if(hrand_monster(8000) < 15)
|
else if(hrand_monster_in(laBrownian, 8000) < 15)
|
||||||
c->monst = moAlbatross;
|
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->monst = moBrownBug;
|
||||||
c->hitpoints = 3;
|
c->hitpoints = 3;
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ extern array<feature, 21> features;
|
|||||||
|
|
||||||
#define VF [] (cell *c)
|
#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 {{
|
array<feature, 21> features {{
|
||||||
feature{(color_t)(-0x202020), 5, moNecromancer, VF {
|
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_i(stamplen, "stamplen");
|
||||||
param_f(anims::period, "animperiod");
|
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() {
|
EX bool inSpecialMode() {
|
||||||
|
24
help.cpp
24
help.cpp
@ -1089,16 +1089,7 @@ EX void describeMouseover() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void showHelp() {
|
EX void addHelpWithTitle() {
|
||||||
cmode = sm::HELP | sm::DOTOUR | sm::DARKEN;
|
|
||||||
getcstat = SDLK_ESCAPE;
|
|
||||||
if(help == "HELPFUN") {
|
|
||||||
help_delegate();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gamescreen();
|
|
||||||
string help2;
|
|
||||||
if(help[0] == '@') {
|
if(help[0] == '@') {
|
||||||
int iv = help.find("\t");
|
int iv = help.find("\t");
|
||||||
int id = help.find("\n");
|
int id = help.find("\n");
|
||||||
@ -1109,6 +1100,19 @@ EX void showHelp() {
|
|||||||
dialog::init("help", forecolor, 120, 100);
|
dialog::init("help", forecolor, 120, 100);
|
||||||
dialog::addHelp(help);
|
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;
|
bool in_list = false;
|
||||||
|
|
||||||
|
2
hyper.h
2
hyper.h
@ -566,7 +566,7 @@ typedef function<int(struct cell*)> cellfunction;
|
|||||||
// passable flags
|
// passable flags
|
||||||
|
|
||||||
#define SAGEMELT .1
|
#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 ROCKSNAKELENGTH 50
|
||||||
#define WORMLENGTH 15
|
#define WORMLENGTH 15
|
||||||
#define PRIZEMUL 7
|
#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;
|
else if(c->land == laEEarth) c->wall = waStone;
|
||||||
}
|
}
|
||||||
|
|
||||||
// automatically adjust monster generation for 3D geometries
|
// automatically adjust monster generation for 3D geometries and custom difficulty
|
||||||
EX int hrand_monster(int x) {
|
EX int hrand_monster_in(eLand l, int x) {
|
||||||
// dual geometry mode is much harder, so generate less monsters to balance it
|
// dual geometry mode is much harder, so generate less monsters to balance it
|
||||||
if(dual::state) x *= 3;
|
if(dual::state) x *= 3;
|
||||||
// in 3D monster generation depends on the sight range
|
// in 3D monster generation depends on the sight range
|
||||||
@ -180,9 +180,15 @@ EX int hrand_monster(int x) {
|
|||||||
int t = isize(gmatrix);
|
int t = isize(gmatrix);
|
||||||
if(t > 500) x = int(((long long)(x)) * t / 500);
|
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);
|
return hrand(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define hrand_monster(x) hrand_monster_in(c->land, x)
|
||||||
|
|
||||||
EX bool is_zebra_trapdoor(cell *c) {
|
EX bool is_zebra_trapdoor(cell *c) {
|
||||||
if(euclid && closed_or_bounded) return false;
|
if(euclid && closed_or_bounded) return false;
|
||||||
#if CAP_ARCM
|
#if CAP_ARCM
|
||||||
@ -280,6 +286,12 @@ EX void gen_baby_tortoise(cell *c) {
|
|||||||
tortoise::babymap[c] = tortoise::getb(c) ^ tortoise::getRandomBits();
|
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) {
|
EX void giantLandSwitch(cell *c, int d, cell *from) {
|
||||||
bool fargen = d == 9;
|
bool fargen = d == 9;
|
||||||
switch(c->land) {
|
switch(c->land) {
|
||||||
@ -3139,4 +3151,6 @@ EX void setdist(cell *c, int d, cell *from) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef hrand_monster
|
||||||
|
|
||||||
}
|
}
|
||||||
|
113
landlock.cpp
113
landlock.cpp
@ -712,8 +712,15 @@ EX eLand getLandForList(cell *c) {
|
|||||||
return l;
|
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) {
|
EX bool isLandIngame(eLand l) {
|
||||||
if(isElemental(l)) l = laElementalWall;
|
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(dual::state == 2 && !dual::check_side(l)) return false;
|
||||||
if((eubinary || sol) && isCyclic(l) && l != specialland) return false;
|
if((eubinary || sol) && isCyclic(l) && l != specialland) return false;
|
||||||
if(l == laCamelot && hyperbolic && WDIM == 3) 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 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
|
// check if the given land should appear in lists
|
||||||
EX land_validity_t& land_validity(eLand l) {
|
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(int(geometry) > 3 || int(variation) > 1) return UNKNOWN;
|
||||||
if(casual) return UNKNOWN;
|
if(casual) return UNKNOWN;
|
||||||
if(bow::weapon) return UNKNOWN;
|
if(bow::weapon) return UNKNOWN;
|
||||||
|
if(use_custom_land_list) return UNKNOWN;
|
||||||
|
|
||||||
bool is_default_land_structure =
|
bool is_default_land_structure =
|
||||||
(princess::challenge || tactic::on) ? ls::single() :
|
(princess::challenge || tactic::on) ? ls::single() :
|
||||||
|
@ -685,6 +685,9 @@ EX void showChangeMode() {
|
|||||||
multi::cpid = 0;
|
multi::cpid = 0;
|
||||||
menuitem_land_structure('l');
|
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::addBoolItem(XLAT("weapon selection"), bow::weapon, 'b');
|
||||||
dialog::add_action_push(bow::showMenu);
|
dialog::add_action_push(bow::showMenu);
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ EX int reptilemax() {
|
|||||||
return r;
|
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;
|
of *= 10;
|
||||||
a += yendor::hardness() + 1;
|
a += yendor::hardness() + 1;
|
||||||
if(isCrossroads(cwt.at->land))
|
if(isCrossroads(cwt.at->land))
|
||||||
@ -206,6 +206,11 @@ bool wchance(int a, int of, int reduction = 0) {
|
|||||||
a -= reduction;
|
a -= reduction;
|
||||||
if(a < 0) return false;
|
if(a < 0) return false;
|
||||||
|
|
||||||
|
if(use_custom_land_list) {
|
||||||
|
of *= 100;
|
||||||
|
a *= custom_land_wandering[l];
|
||||||
|
}
|
||||||
|
|
||||||
return hrand(a+of) < a;
|
return hrand(a+of) < a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,7 +342,7 @@ EX void wandering() {
|
|||||||
if(closed_or_bounded && specialland == laClearing)
|
if(closed_or_bounded && specialland == laClearing)
|
||||||
clearing::new_root();
|
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);
|
wanderingZebra(cwt.at);
|
||||||
|
|
||||||
bool smallbounded_generation = smallbounded || (closed_manifold && specialland == laClearing);
|
bool smallbounded_generation = smallbounded || (closed_manifold && specialland == laClearing);
|
||||||
@ -371,6 +376,8 @@ EX void wandering() {
|
|||||||
if(!valid(c)) continue;
|
if(!valid(c)) continue;
|
||||||
if(isPlayerOn(c)) break;
|
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) {
|
if(specialland == laStorms) {
|
||||||
// place the sandstone wall completely randomly (but not on the player)
|
// place the sandstone wall completely randomly (but not on the player)
|
||||||
vector<cell*>& ac = currentmap->allcells();
|
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::weapon);
|
||||||
f.write<char>(bow::style);
|
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) {
|
EX modecode_t modecode(int mode) {
|
||||||
|
Loading…
Reference in New Issue
Block a user