mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2026-03-03 20:29:44 +00:00
Merge branch 'master' of https://github.com/zenorogue/hyperrogue
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "rogueviz/seuphorica"]
|
||||
path = rogueviz/seuphorica
|
||||
url = https://github.com/zenorogue/seuphorica.git
|
||||
@@ -189,13 +189,13 @@ EX bool petrify(cell *c, eWall walltype, eMonster m) {
|
||||
|
||||
if(c->land == laWestWall) return false;
|
||||
|
||||
if(do_not_touch_this_wall(c)) return false;
|
||||
|
||||
if(isWateryOrBoat(c) && c->land == laWhirlpool) {
|
||||
c->wall = waSea;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(c->wall == waRoundTable) return false;
|
||||
|
||||
if(walltype == waGargoyle && cellUnstableOrChasm(c))
|
||||
walltype = waGargoyleFloor;
|
||||
else if(walltype == waGargoyle && isWatery(c))
|
||||
|
||||
22
barriers.cpp
22
barriers.cpp
@@ -844,16 +844,18 @@ EX bool buildBarrier6(cellwalker cw, eLand m0, eLand m1) {
|
||||
setland((b[d+1]-2).cpeek(), m1);
|
||||
setland((b[d+1]+2).cpeek(), m0);
|
||||
}
|
||||
int cp = curse_percentage;
|
||||
if(m0 == laCrossroads6 || m1 == laCrossroads6) {
|
||||
cp = 25;
|
||||
if(m0 == laCursed || m1 == laCursed) cp = 100;
|
||||
}
|
||||
if(hrand(100) < cp) {
|
||||
setland(cw.at, laCursed);
|
||||
cw.at->wall = waRubble;
|
||||
cw.at->monst = moHexer;
|
||||
cw.at->item = random_curse();
|
||||
if(isLandIngame(laCursed)) {
|
||||
int cp = curse_percentage;
|
||||
if(m0 == laCrossroads6 || m1 == laCrossroads6) {
|
||||
cp = 25;
|
||||
if(m0 == laCursed || m1 == laCursed) cp = 100;
|
||||
}
|
||||
if(hrand(100) < cp) {
|
||||
setland(cw.at, laCursed);
|
||||
cw.at->wall = waRubble;
|
||||
cw.at->monst = moHexer;
|
||||
cw.at->item = random_curse();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -2721,7 +2721,7 @@ EX namespace dragon {
|
||||
c->monst = moNone;
|
||||
if(checkOrb(who, itOrbUndeath))
|
||||
c->monst = moFriendlyGhost;
|
||||
if(checkOrb(who, itOrbStone))
|
||||
if(!do_not_touch_this_wall(c) && checkOrb(who, itOrbStone))
|
||||
c->wparam = m, c->wall = waPetrified;
|
||||
else if(c->wall == waFire) {
|
||||
if(delay) delay = false;
|
||||
@@ -2993,13 +2993,13 @@ EX namespace kraken {
|
||||
if(checkOrb(who, itOrbUndeath)) c->monst = moFriendlyGhost;
|
||||
if(c->land == laKraken && !c->item) c->item = itKraken;
|
||||
kills[moKrakenH]++;
|
||||
if(checkOrb(who, itOrbStone)) c->wall = waNone;
|
||||
if(!do_not_touch_this_wall(c) && checkOrb(who, itOrbStone)) c->wall = waNone;
|
||||
forCellEx(c1, c)
|
||||
if(c1->monst == moKrakenT) {
|
||||
changes.ccell(c1);
|
||||
drawParticles(c, minf[moKrakenT].color, 16);
|
||||
c1->monst = moNone;
|
||||
if(checkOrb(who, itOrbStone)) {
|
||||
if(!do_not_touch_this_wall(c1) && checkOrb(who, itOrbStone)) {
|
||||
if(isWatery(c1))
|
||||
c1->wall = waNone;
|
||||
else
|
||||
|
||||
17
config.cpp
17
config.cpp
@@ -1207,6 +1207,14 @@ EX void initConfig() {
|
||||
|
||||
param_b(keybd_subdir_enabled, "keybd_subdir_enabled", 0)->editable("control the pushing direction with TAB", 'P')->help("If set, you control the off-heptagon pushing direction with TAB. Otherwise, you control it by rotating the screen.");
|
||||
|
||||
param_str(pinnedglyphs, "pinned_glyphs", "")
|
||||
->set_standard_editor(true)
|
||||
->editable("pinned glyphs",
|
||||
"A list of glyphs to always sort at the front, "
|
||||
"and reserve space for even when they're not being displayed.",
|
||||
'p')
|
||||
->set_reaction(updateglyphpinned);
|
||||
|
||||
param_enum(glyphsortorder, parameter_names("glyph_sort", "glyph sort order"), glyphsortorder)
|
||||
->editable({
|
||||
{"first on top", ""},
|
||||
@@ -1224,6 +1232,11 @@ EX void initConfig() {
|
||||
{"icons", ""},
|
||||
}, "orb display mode", 'o');
|
||||
|
||||
param_b(orb_treasure_gap, "orb_treasure_gap", false)
|
||||
->editable("gap between orbs and treasures", 'G')
|
||||
-> help("If set, a gap row will be left between orbs and treasures in the HUD")
|
||||
-> set_reaction([] { vid.killreduction = 0; });
|
||||
|
||||
param_b(less_in_landscape, "less_in_landscape", false)
|
||||
->editable("less items/kills in landscape", 'L')
|
||||
-> help("If set, only the important items and kills will be shown")
|
||||
@@ -2564,6 +2577,7 @@ EX void configureInterface() {
|
||||
if(hr_hud_enabled) {
|
||||
add_edit(glyphsortorder);
|
||||
add_edit(vid.graphglyph);
|
||||
add_edit(orb_treasure_gap);
|
||||
add_edit(less_in_landscape);
|
||||
add_edit(less_in_portrait);
|
||||
add_edit(display_yasc_codes);
|
||||
@@ -3522,6 +3536,9 @@ EX int config3 = addHook(hooks_configfile, 100, [] {
|
||||
->set_sets([] { dialog::bound_low(1); })
|
||||
->set_reaction([] { if(game_active) { stop_game(); start_game(); } });
|
||||
|
||||
param_enum(warn_before_killing_friends, "warn_before_killing_friends", 2)
|
||||
->editable({{"OFF", "never warn"}, {"TAME_BOMBERBIRDS", "warn only for Tame Bomberbirds"}, {"ON", "always warn"}}, "warn before killing friendly monsters", 'W');
|
||||
|
||||
param_i(curse_percentage, "curse_percentage")->editable(0, 100, 1,
|
||||
"curse percentage",
|
||||
"The percentage of towers in Cursed Walls mode to be manned by Canyon Hags", 'R')
|
||||
|
||||
12
debug.cpp
12
debug.cpp
@@ -123,6 +123,18 @@ vector<cheatkey> cheats = {
|
||||
kills[moCultist] = qkills;
|
||||
kills[moTroll] = qkills;
|
||||
}},
|
||||
cheatkey{'H', "toggle hold of orb powers", [] {
|
||||
if(cheat_items_enabled) {
|
||||
cheat_items_enabled = false;
|
||||
addMessage(XLAT("Hold of orb powers disabled!"));
|
||||
}
|
||||
else {
|
||||
cheat_items = items;
|
||||
cheat_items_enabled = true;
|
||||
cheater++;
|
||||
addMessage(XLAT("Hold of orb powers enabled!"));
|
||||
}
|
||||
}},
|
||||
cheatkey{'M', "deplete orb powers", [] {
|
||||
for(int i=0; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_ORB)
|
||||
|
||||
@@ -262,10 +262,6 @@ EX bool haveRangedOrb() {
|
||||
items[itOrbMorph] || items[itOrbPhasing];
|
||||
}
|
||||
|
||||
EX bool isFriendlyGhost(eMonster m) {
|
||||
return m == moFriendlyGhost || (markEmpathy(itOrbAether) && isFriendly(m));
|
||||
}
|
||||
|
||||
EX bool isGhostAether(eMonster m) {
|
||||
return isGhost(m) || checkOrb(m, itOrbAether);
|
||||
}
|
||||
|
||||
41
hud.cpp
41
hud.cpp
@@ -58,6 +58,8 @@ enum eGlyphsortorder {
|
||||
#endif
|
||||
|
||||
EX eGlyphsortorder glyphsortorder;
|
||||
EX string pinnedglyphs;
|
||||
EX bool glyphpinned[int(ittypes) + int(motypes)];
|
||||
|
||||
int zero = 0;
|
||||
|
||||
@@ -80,6 +82,27 @@ int glyphorder[glyphs];
|
||||
int glyphphase[glyphs];
|
||||
int glyph_lastticks;
|
||||
|
||||
EX void updateglyphpinned() {
|
||||
for(int i=0; i<glyphs; i++) glyphpinned[i] = false;
|
||||
if(!pinnedglyphs.empty()) {
|
||||
exp_parser ep;
|
||||
ep.s = pinnedglyphs;
|
||||
do {
|
||||
int i = ep.iparse();
|
||||
if(i >= 0 && i < glyphs) glyphpinned[i] = true;
|
||||
} while(ep.eat(","));
|
||||
}
|
||||
}
|
||||
|
||||
EX void updatepinnedglyphs() {
|
||||
std::stringstream ss;
|
||||
for(int i=0; i<glyphs; i++) {
|
||||
if(glyphpinned[i]) ss << i << ",";
|
||||
}
|
||||
pinnedglyphs = ss.str();
|
||||
if(!pinnedglyphs.empty()) pinnedglyphs.pop_back();
|
||||
}
|
||||
|
||||
void updatesort() {
|
||||
for(int i=0; i<glyphs; i++) {
|
||||
int ik = ikmerge(i);
|
||||
@@ -123,6 +146,8 @@ int glyphcorner(int i) {
|
||||
}
|
||||
|
||||
bool glyphsort(int i, int j) {
|
||||
if(glyphpinned[i] != glyphpinned[j])
|
||||
return glyphpinned[i] > glyphpinned[j];
|
||||
if(subclass(i) != subclass(j))
|
||||
return subclass(i) < subclass(j);
|
||||
if(glyphsortorder == gsoFirstTop)
|
||||
@@ -462,7 +487,7 @@ EX void draw_crosshair() {
|
||||
return;
|
||||
}
|
||||
|
||||
EX bool less_in_portrait, less_in_landscape;
|
||||
EX bool less_in_portrait, less_in_landscape, orb_treasure_gap;
|
||||
|
||||
EX string mode_description() {
|
||||
string md;
|
||||
@@ -560,7 +585,7 @@ EX void drawStats() {
|
||||
else if(cornermode) {
|
||||
int bycorner[4];
|
||||
for(int u=0; u<4; u++) bycorner[u] = 0;
|
||||
for(int i=0; i<glyphs; i++) if(ikappear(i) && (glyphflags(i) & GLYPH_INSQUARE))
|
||||
for(int i=0; i<glyphs; i++) if((ikappear(i) || glyphpinned[i]) && (glyphflags(i) & GLYPH_INSQUARE))
|
||||
bycorner[glyphcorner(i)]++;
|
||||
updatesort();
|
||||
stable_sort(glyphorder, glyphorder+glyphs, glyphsort);
|
||||
@@ -579,7 +604,7 @@ EX void drawStats() {
|
||||
vector<int> glyphstoshow;
|
||||
for(int i=0; i<glyphs; i++) {
|
||||
int g = glyphorder[i];
|
||||
if(ikappear(g) && (glyphflags(g) & GLYPH_INSQUARE) && glyphcorner(g) == cor)
|
||||
if((ikappear(g) || glyphpinned[g]) && (glyphflags(g) & GLYPH_INSQUARE) && glyphcorner(g) == cor)
|
||||
glyphstoshow.push_back(g);
|
||||
}
|
||||
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
|
||||
@@ -592,7 +617,8 @@ EX void drawStats() {
|
||||
if(cor&1) cx = vid.xres-1-s-cx;
|
||||
if(cor&2) cy = vid.yres-1-cy;
|
||||
|
||||
displayglyph2(cx, cy, s, glyphstoshow[next++]);
|
||||
int g = glyphstoshow[next++];
|
||||
if(ikappear(g)) displayglyph2(cx, cy, s, g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -616,7 +642,7 @@ EX void drawStats() {
|
||||
|
||||
flagtype flag = portrait ? GLYPH_INPORTRAIT : GLYPH_INLANDSCAPE;
|
||||
|
||||
for(int i=0; i<glyphs; i++) if(ikappear(i))
|
||||
for(int i=0; i<glyphs; i++) if(ikappear(i) || glyphpinned[i])
|
||||
if(glyphflags(i) & flag)
|
||||
maxbyclass[glyphclass(i)]++;
|
||||
int buttonsize;
|
||||
@@ -629,6 +655,7 @@ EX void drawStats() {
|
||||
rows = rowspace / buttonsize; if(!rows) return;
|
||||
int coltaken = 0;
|
||||
for(int z=0; z<4; z++) {
|
||||
if(z == 1 && orb_treasure_gap) coltaken++;
|
||||
if(z == 2 && !portrait) {
|
||||
if(coltaken > columns) { vid.killreduction++; continue; }
|
||||
coltaken = 0;
|
||||
@@ -651,7 +678,7 @@ EX void drawStats() {
|
||||
|
||||
for(int i0=0; i0<glyphs; i0++) {
|
||||
int i = glyphorder[i0];
|
||||
if(!ikappear(i)) continue;
|
||||
if(!ikappear(i) && !glyphpinned[i]) continue;
|
||||
int z = glyphclass(i);
|
||||
int imp = glyphflags(i);
|
||||
if(!(imp & flag)) continue;
|
||||
@@ -667,7 +694,7 @@ EX void drawStats() {
|
||||
|
||||
rowid[z]++; if(rowid[z] >= rows) rowid[z] = 0, colid[z]++;
|
||||
|
||||
displayglyph2(cx, cy, buttonsize, i);
|
||||
if(ikappear(i)) displayglyph2(cx, cy, buttonsize, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ EX int currentLocalTreasure;
|
||||
/** for treasures, the number collected; for orbs, the number of charges */
|
||||
EX array<int, ittypes> items;
|
||||
|
||||
EX array<int, ittypes> cheat_items;
|
||||
EX bool cheat_items_enabled;
|
||||
|
||||
EX map<modecode_t, array<int, ittypes> > hiitems;
|
||||
|
||||
EX bool pickable_from_water(eItem it) {
|
||||
@@ -30,6 +33,8 @@ EX bool canPickupItemWithMagnetism(cell *c, cell *from) {
|
||||
return false;
|
||||
if(c->item == itCompass && from->item)
|
||||
return false;
|
||||
if(saved_tortoise_on(c))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,7 +46,7 @@ EX bool doPickupItemsWithMagnetism(cell *c) {
|
||||
cw += wstep;
|
||||
for(int j=1; j<c3->type; j++) {
|
||||
cell *c4 = (cw+j).peek();
|
||||
if(!isNeighbor(c, c4) && c3->item && !c4->item && passable(c4, c3, ZERO)) {
|
||||
if(!isNeighbor(c, c4) && c3->item && !c4->item && !saved_tortoise_on(c3) && passable(c4, c3, ZERO)) {
|
||||
changes.ccell(c3);
|
||||
changes.ccell(c4);
|
||||
moveItem(c3, c4, false);
|
||||
|
||||
@@ -221,11 +221,15 @@ EX bool landUnlockedRPM(eLand n) {
|
||||
}
|
||||
|
||||
EX int lands_for_hell() {
|
||||
return casual ? 40 : 9;
|
||||
int desired = casual ? 40 : 9;
|
||||
int available = std::count_if(land_over.begin(), land_over.end(), [] (eLand l) { return !among(l, laHell, laCocytus, laPower) && !isCrossroads(l) && isLandIngame(l); });
|
||||
return min(desired, available);
|
||||
}
|
||||
|
||||
EX int lands_for_cr3() {
|
||||
return casual ? 20 : 9;
|
||||
int desired = casual ? 20 : 9;
|
||||
int available = std::count_if(land_over.begin(), land_over.end(), [] (eLand l) { return !isCrossroads(l) && isLandIngame(l); });
|
||||
return min(desired, available);
|
||||
}
|
||||
|
||||
EX int variant_unlock_value() {
|
||||
|
||||
@@ -1096,7 +1096,7 @@ EX namespace mapstream {
|
||||
|
||||
if(shmup::on) shmup::init();
|
||||
|
||||
timerstart = time(NULL); turncount = 0;
|
||||
timerstart = time(NULL); turncount = 0; lastexplore = 0;
|
||||
sagephase = 0; hardcoreAt = 0;
|
||||
timerstopped = false;
|
||||
savecount = 0; savetime = 0;
|
||||
|
||||
@@ -160,7 +160,7 @@ EX bool earthFloor(cell *c) {
|
||||
if(c->monst) return false;
|
||||
if(c->wall == waDeadwall) { c->wall = waDeadfloor; return true; }
|
||||
if(c->wall == waDune) { c->wall = waNone; return true; }
|
||||
if(c->wall == waStone && c->land != laTerracotta) { c->wall = waNone; return true; }
|
||||
if(c->wall == waStone && !among(c->land, laTerracotta, laMercuryRiver, laVariant)) { c->wall = waNone; return true; }
|
||||
if(c->wall == waAncientGrave || c->wall == waFreshGrave || c->wall == waRuinWall) {
|
||||
c->wall = waNone;
|
||||
return true;
|
||||
@@ -259,11 +259,11 @@ EX bool earthWall(cell *c) {
|
||||
c->wall = waChasm;
|
||||
return true;
|
||||
}
|
||||
if(c->wall == waNone && c->land == laTerracotta) {
|
||||
if(c->wall == waNone && among(c->land, laTerracotta, laMercuryRiver)) {
|
||||
c->wall = waMercury;
|
||||
return true;
|
||||
}
|
||||
if(c->wall == waArrowTrap && c->land == laTerracotta) {
|
||||
if(c->wall == waArrowTrap && among(c->land, laTerracotta, laMercuryRiver)) {
|
||||
destroyTrapsOn(c);
|
||||
c->wall = waMercury;
|
||||
return true;
|
||||
|
||||
@@ -181,6 +181,11 @@ EX void showOverview() {
|
||||
}
|
||||
else if(udiv == 2 && umod < ittypes) {
|
||||
gotoHelp(generateHelpForItem(eItem(umod)));
|
||||
help_extensions.push_back(help_extension{'p', glyphpinned[umod] ? XLAT("unpin from HUD") : XLAT("pin to HUD"), [umod] () {
|
||||
glyphpinned[umod] ^= true;
|
||||
updatepinnedglyphs();
|
||||
popScreen();
|
||||
}});
|
||||
if(cheater) {
|
||||
dialog::helpToEdit(items[umod], 0, 200, 10, 10);
|
||||
dialog::get_ne().reaction = [] () {
|
||||
|
||||
10
orbs.cpp
10
orbs.cpp
@@ -50,7 +50,7 @@ EX void useupOrb(eItem it, int qty) {
|
||||
}
|
||||
|
||||
EX void drainOrb(eItem it, int target IS(0)) {
|
||||
if(items[it] > target) useupOrb(it, items[it] - target);
|
||||
if(!cheat_items_enabled && items[it] > target) useupOrb(it, items[it] - target);
|
||||
}
|
||||
|
||||
EX void empathyMove(const movei& mi) {
|
||||
@@ -233,6 +233,14 @@ EX void reduceOrbPowers() {
|
||||
else
|
||||
items[itCrossbow]--;
|
||||
}
|
||||
if(cheat_items_enabled)
|
||||
for(int i=0; i<ittypes; i++) {
|
||||
if(i == itOrbSpeed) {
|
||||
if(items[i] < cheat_items[i]) items[i] = cheat_items[i] + 1; // Orb of Speed always needs to alternate between an odd and even number to work right
|
||||
}
|
||||
else if(itemclass(eItem(i)) == IC_ORB && i != itOrbSafety)
|
||||
items[i] = cheat_items[i];
|
||||
}
|
||||
}
|
||||
|
||||
eWall orig_wall;
|
||||
|
||||
@@ -1474,7 +1474,10 @@ EX bool warningprotection(const string& s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
EX int warn_before_killing_friends;
|
||||
|
||||
EX bool warningprotection_hit(eMonster m) {
|
||||
if(warn_before_killing_friends < (m == moTameBomberbird ? 1 : 2)) return false;
|
||||
if(m && warningprotection(XLAT("Are you sure you want to hit %the1?", m)))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
1
rogueviz/seuphorica
Submodule
1
rogueviz/seuphorica
Submodule
Submodule rogueviz/seuphorica added at 1ed348d47e
@@ -184,6 +184,7 @@ EX void reset_cheats() {
|
||||
cheater = 0;
|
||||
reptilecheat = false;
|
||||
shadingcheat = false;
|
||||
cheat_items_enabled = false;
|
||||
timerghost = true;
|
||||
gen_wandering = true;
|
||||
}
|
||||
@@ -407,7 +408,7 @@ EX void initgame() {
|
||||
|
||||
if(!safety) {
|
||||
usedSafety = false;
|
||||
timerstart = time(NULL); turncount = 0; rosewave = 0; rosephase = 0;
|
||||
timerstart = time(NULL); turncount = 0; lastexplore = 0; rosewave = 0; rosephase = 0;
|
||||
tickstart = ticks;
|
||||
noiseuntil = 0;
|
||||
sagephase = 0; hardcoreAt = 0;
|
||||
|
||||
@@ -220,7 +220,7 @@ EX void invoke() {
|
||||
c->wall = p.first[0];
|
||||
c->wparam = p.first[0];
|
||||
forCellEx(c1, c) {
|
||||
if(c1->wall != waBarrier)
|
||||
if(c1->wall != waBarrier && c1->land == c->land)
|
||||
c1->wparam = c1->wall = p.first[idx];
|
||||
idx++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user