Compare commits
16 Commits
dea9fea67f
...
9bc4e21f10
Author | SHA1 | Date |
---|---|---|
Zeno Rogue | 9bc4e21f10 | |
Zeno Rogue | a328568ee5 | |
Zeno Rogue | 494fc4ec11 | |
Zeno Rogue | 6f7e5b4d6a | |
Zeno Rogue | ccea416237 | |
Zeno Rogue | 4a908273d0 | |
Zeno Rogue | 5efacd787d | |
Zeno Rogue | b07987b2f4 | |
Zeno Rogue | 84ada5184f | |
Zeno Rogue | 14b68f0b64 | |
Zeno Rogue | 960485ec8e | |
Zeno Rogue | e032e619c0 | |
Zeno Rogue | 57f6fb5f71 | |
Zeno Rogue | d2cd6fa2c1 | |
Zeno Rogue | 8a407f4505 | |
Zeno Rogue | 6abb82174e |
10
attack.cpp
10
attack.cpp
|
@ -757,7 +757,7 @@ EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) {
|
|||
// a reward for killing him before he shoots!
|
||||
c->item = itOrbDragon;
|
||||
}
|
||||
if(m == moAsteroid && !shmup::on && c->item == itNone && c->wall != waChasm) {
|
||||
if(m == moAsteroid && !shmup::on && c->item == itNone && c->wall != waChasm && c->land == laAsteroids) {
|
||||
c->item = itAsteroid;
|
||||
changes.value_add(splitrocks, 2);
|
||||
}
|
||||
|
@ -944,6 +944,14 @@ EX void fightmessage(eMonster victim, eMonster attacker, bool stun, flagtype fla
|
|||
else
|
||||
addMessage(XLAT("You pierce %the1.", victim)); // normal
|
||||
}
|
||||
else if(items[itOrbSlaying]) {
|
||||
playSound(NULL, "hit-crush"+pick123());
|
||||
addMessage(XLAT("You crush %the1!", victim)); // normal
|
||||
}
|
||||
else if(stun && items[itCurseWeakness]) {
|
||||
playSound(NULL, "click");
|
||||
addMessage(XLAT("You punch %the1.", victim)); // normal
|
||||
}
|
||||
else if(!peace::on) {
|
||||
playSound(NULL, "hit-sword"+pick123());
|
||||
addMessage(XLAT("You kill %the1.", victim)); // normal
|
||||
|
|
17
bigstuff.cpp
17
bigstuff.cpp
|
@ -1005,7 +1005,7 @@ EX void buildEquidistant(cell *c) {
|
|||
if(c->landparam > 30 && b == laOcean && !generatingEquidistant && !mhybrid && hrand(10) < 5 && chance)
|
||||
buildAnotherEquidistant(c);
|
||||
|
||||
if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !mhybrid && hrand(100) < (PURE?25:5) && items[itBone] >= U10 && chance)
|
||||
if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !mhybrid && hrand(100) < (PURE?25:5) && landUnlockedIngame(laHaunted) && chance)
|
||||
buildAnotherEquidistant(c);
|
||||
}
|
||||
|
||||
|
@ -1876,13 +1876,13 @@ EX void build_horocycles(cell *c, cell *from) {
|
|||
items[itEmerald] >= U5)))
|
||||
start_camelot(c);
|
||||
|
||||
if(c->land == laRlyeh && can_start_horo(c) && (quickfind(laTemple) || peace::on || (hrand(I2000) < 100 && items[itStatue] >= U5)))
|
||||
if(c->land == laRlyeh && can_start_horo(c) && (quickfind(laTemple) || (hrand(I2000) < 100 && landUnlockedIngame(laTemple))))
|
||||
create_altmap(c, horo_gen_distance(), hsA);
|
||||
|
||||
if(c->land == laJungle && can_start_horo(c) && (quickfind(laMountain) || (hrand(I2000) < 100 && landUnlocked(laMountain))))
|
||||
if(c->land == laJungle && can_start_horo(c) && (quickfind(laMountain) || (hrand(I2000) < 100 && landUnlockedIngame(laMountain))))
|
||||
create_altmap(c, horo_gen_distance(), hsA);
|
||||
|
||||
if(c->land == laOvergrown && can_start_horo(c) && (quickfind(laClearing) || (hrand(I2000) < 25 && items[itMutant] >= U5 && isLandIngame(laClearing)))) {
|
||||
if(c->land == laOvergrown && can_start_horo(c) && (quickfind(laClearing) || (hrand(I2000) < 25 && landUnlockedIngame(laClearing)))) {
|
||||
heptagon *h = create_altmap(c, horo_gen_distance(), hsA);
|
||||
if(h) clearing::bpdata[h].root = NULL;
|
||||
}
|
||||
|
@ -1894,11 +1894,12 @@ EX void build_horocycles(cell *c, cell *from) {
|
|||
|
||||
if(c->land == laOcean && deepOcean && !generatingEquidistant && !peace::on && can_start_horo(c) &&
|
||||
(quickfind(laWhirlpool) || (
|
||||
hrand(2000) < (PURE ? 500 : 1000))))
|
||||
hrand(2000) < (PURE ? 500 : 1000) && landUnlockedIngame(laWhirlpool))))
|
||||
create_altmap(c, horo_gen_distance(), hsA);
|
||||
|
||||
#if CAP_COMPLEX2
|
||||
if(c->land == laOcean && deepOcean && !generatingEquidistant && hrand(10000) < 20 && no_barriers_in_radius(c, 2) && hyperbolic && !quotient && !tactic::on && !safety && !ls::hv_structure())
|
||||
if(c->land == laOcean && deepOcean && !generatingEquidistant && hrand(10000) < 20 && no_barriers_in_radius(c, 2) && hyperbolic && !quotient && !tactic::on && !safety && !ls::hv_structure()
|
||||
&& landUnlockedIngame(laBrownian))
|
||||
brownian::init_further(c);
|
||||
#endif
|
||||
|
||||
|
@ -1919,7 +1920,7 @@ EX void build_horocycles(cell *c, cell *from) {
|
|||
if(c->land == laPalace && can_start_horo(c) && !princess::generating && !shmup::on && multi::players == 1 && !weirdhyperbolic &&
|
||||
(princess::forceMouse ? canReachPlayer(from, moMouse) :
|
||||
(hrand(2000) < (peace::on ? 100 : 20))) &&
|
||||
(princess::challenge || kills[moVizier] || peace::on)) {
|
||||
landUnlockedIngame(laPrincessQuest)) {
|
||||
create_altmap(c, PRADIUS0, hsOrigin, waPalace);
|
||||
celllister cl(c, 5, 1000000, NULL);
|
||||
for(cell *c: cl.lst) if(c->master->alt) currentmap->extend_altmap(c->master);
|
||||
|
@ -2318,7 +2319,7 @@ EX void pregen() {
|
|||
currentlands.clear();
|
||||
if(ls::any_chaos() && !ls::std_chaos())
|
||||
for(eLand l: land_over)
|
||||
if(landUnlocked(l) && isLandIngame(l))
|
||||
if(landUnlockedIngame(l))
|
||||
currentlands.push_back(l);
|
||||
}
|
||||
|
||||
|
|
|
@ -5181,3 +5181,25 @@ Bug fixes:
|
|||
* Fixed troll nests in Horodisk/Voronoi.
|
||||
* Fixed a crash when running away from Clearing in single-land mode.
|
||||
* Some values are tracked in savefiles while previously they did not (fatigue, snake oil, crossbow reload time, gun ammo, etc.) (Thanks to jlm)
|
||||
|
||||
2024-03-24 20:10 Update 13.0e:
|
||||
|
||||
* in Steam, option `-achievement-always` to always display achievements, even if you already got them.
|
||||
* rosebushes now show up on the radar in 3D geometries, and they now blink if they are close to going off
|
||||
* if you are in water (and have no Fish), you can now see Orbs of Fish and Aether in adjacent water tiles, and also you can move there and pick them up
|
||||
* crossbow bolt now ignore rose restrictions on attack
|
||||
* migrating to SDL2 caused crashes in shmup, with the game_keys_scroll option, and with the shift-target option -- this should be fixed
|
||||
* 'custom' land list mode is now mentioned in the watermark (bottom left of the screen)
|
||||
|
||||
2024-03-27 23:47 Update 13.0f:
|
||||
|
||||
* new messages on Orb of Phasing, Slaying, and Weakness
|
||||
* more accurate messages on dice pushing
|
||||
* when loading save, load full mode data including custom lands
|
||||
* irregular maps no longer change on every load due to floating point precision
|
||||
* [custom lands list] Space Rock monsters now drop treasure only if in Space Rock land
|
||||
* ineligible starting land also if land is not in game
|
||||
* [custom lands list] do not freeze if no new sealand is available
|
||||
* in countHyperstones, two variants of Mirror are counted once
|
||||
* specially generated lands (horocycles, Brown Islands) now respect Unlocked and LandIngame rules
|
||||
* fixed some more crashes related to SDL2 (e.g., right-click in shmup)
|
||||
|
|
|
@ -1298,7 +1298,7 @@ LAND( 0xE08020, "Canvas", laCanvas, ZERO | LF_TECHNICAL, itNone, RESERVED, "A fa
|
|||
|
||||
LAND( 0x00C000, "Palace Quest", laPrincessQuest, ZERO, itSavedPrincess, RESERVED, princessdesc) // fake
|
||||
NATIVE(isNative(laPalace, m))
|
||||
REQ(ACCONLY(laPalace) KILL(moVizier, laPalace))
|
||||
REQ(ACCONLY(laPalace) INMODE(princess::challenge) KILL(moVizier, laPalace))
|
||||
|
||||
LAND( 0xD0D060, "Wild West", laWildWest, ZERO, itBounty, RESERVED, wildwestdesc)
|
||||
NATIVE((m == moOutlaw) ? 2 : 0)
|
||||
|
@ -1797,4 +1797,5 @@ MONSTER( '*', 0, "vertex", moRogueviz, ZERO | CF_TECHNICAL, RESERVED, moN
|
|||
#undef ACCONLY2
|
||||
#undef ACCONLY3
|
||||
#undef ACCONLYF
|
||||
#undef IFINGAME
|
||||
#undef IFINGAME
|
||||
#undef INMODE
|
||||
|
|
|
@ -660,6 +660,9 @@ int read_cheat_args() {
|
|||
PHASEFROM(2);
|
||||
shift(); vid.stereo_mode = eStereo(argi());
|
||||
}
|
||||
else if(argis("-save-cheats")) {
|
||||
save_cheats = true;
|
||||
}
|
||||
else if(argis("-cmove")) {
|
||||
PHASE(3); shift();
|
||||
for(char c: args()) cheat_move(c);
|
||||
|
|
1
help.cpp
1
help.cpp
|
@ -700,6 +700,7 @@ void add_reqs(eLand l, string& s) {
|
|||
#define COND(x,y) s += (y);
|
||||
#define ITEMS_TOTAL(list, z) \
|
||||
{ int now = 0; string t = "("; for(eItem i: list) { if(t!="(") t += " | "; t += XLATN(iinf[i].name); now += items[i]; } t += ")"; s += XLAT("Treasure required: %1 x %2.\n", its(z), t); buteol(s, now, z); }
|
||||
#define INMODE(x) ;
|
||||
#define ACCONLY(z) s += XLAT("Accessible only from %the1.\n", z);
|
||||
#define ACCONLY2(z,x) s += XLAT("Accessible only from %the1 or %the2.\n", z, x);
|
||||
#define ACCONLY3(z,y,x) s += XLAT("Accessible only from %the1, %2, or %3.\n", z, y, x);
|
||||
|
|
4
hyper.h
4
hyper.h
|
@ -13,8 +13,8 @@
|
|||
#define _HYPER_H_
|
||||
|
||||
// version numbers
|
||||
#define VER "13.0d"
|
||||
#define VERNUM_HEX 0xAA04
|
||||
#define VER "13.0f"
|
||||
#define VERNUM_HEX 0xAA06
|
||||
|
||||
#include "sysconfig.h"
|
||||
|
||||
|
|
|
@ -402,10 +402,7 @@ bool step(int delta) {
|
|||
if(notfound) { status[4] = XLAT("cells badly paired: %1", its(notfound)); runlevel = 0; break; }
|
||||
|
||||
int heptas = 0;
|
||||
for(auto p: cells_of_heptagon) {
|
||||
printf("%p: %d\n", hr::voidp(p.first), isize(p.second));
|
||||
heptas++;
|
||||
}
|
||||
for(auto p: cells_of_heptagon) heptas++;
|
||||
|
||||
if(heptas != isize(all)) {
|
||||
status[4] = XLAT("cells not covered: %1", its(isize(all) - heptas));
|
||||
|
@ -807,6 +804,8 @@ bool save_map(const string& fname) {
|
|||
return true;
|
||||
}
|
||||
|
||||
vector<ld> float_order;
|
||||
|
||||
EX void save_map_bin(hstream& f) {
|
||||
if(!base) { f.write<short>(-1); return; }
|
||||
auto& all = base->allcells();
|
||||
|
@ -817,6 +816,19 @@ EX void save_map_bin(hstream& f) {
|
|||
f.write<short> (base_geometry);
|
||||
f.write<short> (isize(all));
|
||||
f.write<short> (origcells);
|
||||
int foi = 0;
|
||||
|
||||
auto check_float_order = [&] (ld x) {
|
||||
if(foi >= isize(float_order)) {
|
||||
float_order.push_back(x);
|
||||
f.write<ld>(x);
|
||||
}
|
||||
else if(abs(float_order[foi] - x) > 1e-6) {
|
||||
println(hlog, float_order[foi], " vs ", x, " : abs difference is ", abs(float_order[foi] - x));
|
||||
float_order[foi] = x;
|
||||
}
|
||||
f.write<ld>(float_order[foi++]);
|
||||
};
|
||||
|
||||
for(auto h: all) {
|
||||
origcells = 0;
|
||||
|
@ -826,9 +838,9 @@ EX void save_map_bin(hstream& f) {
|
|||
f.write<short> (origcells);
|
||||
for(auto i: cells_of_heptagon[h->master]) if(cells[i].generation == 0) {
|
||||
auto &ci = cells[i];
|
||||
f.write<ld>(ci.p[0]);
|
||||
f.write<ld>(ci.p[1]);
|
||||
f.write<ld>(ci.p[LDIM]);
|
||||
check_float_order(ci.p[0]);
|
||||
check_float_order(ci.p[1]);
|
||||
check_float_order(ci.p[LDIM]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -877,6 +889,7 @@ EX void load_map_bin(hstream& f) {
|
|||
density = cellcount * 1. / isize(all);
|
||||
|
||||
cells.clear();
|
||||
float_order.clear();
|
||||
|
||||
for(auto h: all) {
|
||||
int q = f.get<short>();
|
||||
|
@ -889,6 +902,9 @@ EX void load_map_bin(hstream& f) {
|
|||
a = f.get<ld>();
|
||||
b = f.get<ld>();
|
||||
c = f.get<ld>();
|
||||
float_order.push_back(a);
|
||||
float_order.push_back(b);
|
||||
float_order.push_back(c);
|
||||
s.p = hpxyz(a, b, c);
|
||||
s.p = normalize(s.p);
|
||||
for(auto c0: all) s.relmatrices[c0] = calc_relative_matrix(c0, h, s.p);
|
||||
|
|
12
landlock.cpp
12
landlock.cpp
|
@ -230,6 +230,7 @@ EX bool landUnlocked(eLand l) {
|
|||
#define ACCONLY3(x,y,z)
|
||||
#define ACCONLYF(x)
|
||||
#define IFINGAME(land, ok, fallback) if(isLandIngame(land)) { ok } else { fallback }
|
||||
#define INMODE(x) if(x) return true;
|
||||
#include "content.cpp"
|
||||
|
||||
case landtypes: return false;
|
||||
|
@ -251,7 +252,10 @@ EX void countHyperstoneQuest(int& i1, int& i2) {
|
|||
i1 = 0; i2 = 0;
|
||||
generateLandList(isLandIngame);
|
||||
for(eLand l: landlist) {
|
||||
// no treasure
|
||||
if(l == laCA) continue;
|
||||
// same treasure, so count only once
|
||||
if(l == laMirrorOld && isLandIngame(laMirror)) continue;
|
||||
eItem ttype = treasureType(l);
|
||||
if(!required_for_hyperstones(ttype)) continue;
|
||||
i2++; if(items[ttype] >= R10) i1++;
|
||||
|
@ -383,7 +387,7 @@ EX eLand pickluck(eLand l1, eLand l2) {
|
|||
} */
|
||||
|
||||
EX eLand getNewSealand(eLand old) {
|
||||
while(true) {
|
||||
for(int it=0; it<100; it++) {
|
||||
eLand p = pick(laOcean, pick(laCaribbean, laLivefjord, laWarpSea, laKraken, laDocks));
|
||||
if(p == laKraken && !landUnlocked(p)) continue;
|
||||
if(p == laKraken && peace::on) continue;
|
||||
|
@ -392,6 +396,7 @@ EX eLand getNewSealand(eLand old) {
|
|||
if(!isLandIngame(p)) continue;
|
||||
return p;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
EX bool createOnSea(eLand old) {
|
||||
|
@ -741,6 +746,11 @@ EX bool isLandIngame(eLand l) {
|
|||
return land_validity(l).flags & lv::appears_in_full;
|
||||
}
|
||||
|
||||
EX bool landUnlockedIngame(eLand l) {
|
||||
if(!peace::on && !landUnlocked(l)) return false;
|
||||
return isLandIngame(l);
|
||||
}
|
||||
|
||||
namespace lv {
|
||||
|
||||
flagtype q0 = lv::display_error_message | lv::display_in_help | lv::appears_in_geom_exp;
|
||||
|
|
|
@ -780,7 +780,7 @@ EX void showChangeMode() {
|
|||
#endif
|
||||
dialog::addBoolItem(XLAT("%1 Challenge", moPrincess), (princess::challenge), 'P');
|
||||
dialog::add_action_confirmed([] {
|
||||
if(!princess::everSaved)
|
||||
if(!princess::everSaved && !autocheat)
|
||||
addMessage(XLAT("Save %the1 first to unlock this challenge!", moPrincess));
|
||||
else restart_game(rg::princess);
|
||||
});
|
||||
|
|
24
multi.cpp
24
multi.cpp
|
@ -11,13 +11,14 @@ namespace hr {
|
|||
EX namespace multi {
|
||||
|
||||
#if HDR
|
||||
static constexpr int SCANCODES = 512;
|
||||
static constexpr int MAXJOY = 8;
|
||||
static constexpr int MAXBUTTON = 64;
|
||||
static constexpr int MAXAXE = 16;
|
||||
static constexpr int MAXHAT = 4;
|
||||
|
||||
struct config {
|
||||
char keyaction[512];
|
||||
char keyaction[SCANCODES];
|
||||
char joyaction[MAXJOY][MAXBUTTON];
|
||||
char axeaction[MAXJOY][MAXAXE];
|
||||
char hataction[MAXJOY][MAXHAT][4];
|
||||
|
@ -171,7 +172,7 @@ int* dzconfigs[24];
|
|||
string listkeys(config& scfg, int id) {
|
||||
#if CAP_SDL
|
||||
string lk = "";
|
||||
for(int i=0; i<512; i++)
|
||||
for(int i=0; i<SCANCODES; i++)
|
||||
if(scfg.keyaction[i] == id)
|
||||
#if CAP_SDL2
|
||||
lk = lk + " " + SDL_GetScancodeName(SDL_Scancode(i));
|
||||
|
@ -265,7 +266,8 @@ struct key_configurer {
|
|||
if(!setwhat) dialog::handleNavigation(sym, uni);
|
||||
if(sym) {
|
||||
if(setwhat) {
|
||||
which_config->keyaction[sym] = setwhat;
|
||||
int scan = key_to_scan(sym);
|
||||
if(scan >= 0 && scan < SCANCODES) which_config->keyaction[scan] = setwhat;
|
||||
setwhat = 0;
|
||||
}
|
||||
else if(uni >= 'a' && uni < 'a' + isize(shmupcmdtable) && shmupcmdtable[uni-'a'][0])
|
||||
|
@ -584,9 +586,19 @@ void pressaction(int id) {
|
|||
actionspressed[id]++;
|
||||
}
|
||||
|
||||
EX int key_to_scan(int sym) {
|
||||
#if CAP_SDL2
|
||||
return SDL_GetScancodeFromKey(sym);
|
||||
#else
|
||||
return sym;
|
||||
#endif
|
||||
}
|
||||
|
||||
EX bool notremapped(int sym) {
|
||||
auto& scfg = scfg_default;
|
||||
int k = scfg.keyaction[sym];
|
||||
int sc = key_to_scan(sym);
|
||||
if(sc < 0 || sc >= SCANCODES) return true;
|
||||
int k = scfg.keyaction[sc];
|
||||
if(k == 0) return true;
|
||||
k /= 16;
|
||||
if(k > 3) k--; else if(k==3) k = 0;
|
||||
|
@ -595,7 +607,7 @@ EX bool notremapped(int sym) {
|
|||
|
||||
EX void sconfig_savers(config& scfg, string prefix) {
|
||||
// unfortunately we cannot use key names here because SDL is not yet initialized
|
||||
for(int i=0; i<512; i++)
|
||||
for(int i=0; i<SCANCODES; i++)
|
||||
addsaver(scfg.keyaction[i], prefix + string("key:")+its(i));
|
||||
|
||||
for(int i=0; i<MAXJOY; i++) {
|
||||
|
@ -613,7 +625,7 @@ EX void sconfig_savers(config& scfg, string prefix) {
|
|||
}
|
||||
|
||||
EX void clear_config(config& scfg) {
|
||||
for(int i=0; i<512; i++) scfg.keyaction[i] = 0;
|
||||
for(int i=0; i<SCANCODES; i++) scfg.keyaction[i] = 0;
|
||||
}
|
||||
|
||||
EX void initConfig() {
|
||||
|
|
9
orbs.cpp
9
orbs.cpp
|
@ -664,7 +664,7 @@ EX void teleportTo(cell *dest) {
|
|||
}
|
||||
|
||||
/* calls changes.rollback or changes.commit */
|
||||
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone)) {
|
||||
EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon IS(moNone), cell *phasecell IS(nullptr)) {
|
||||
if(byWhat != itStrongWind) playSound(dest, "orb-frog");
|
||||
cell *from = cwt.at;
|
||||
changes.value_keep(cwt);
|
||||
|
@ -683,7 +683,10 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons
|
|||
|
||||
if(byWhat == itOrbPhasing) {
|
||||
useupOrb(itOrbPhasing, 5);
|
||||
addMessage(XLAT("You jump!"));
|
||||
if(phasecell->monst)
|
||||
addMessage(XLAT("You phase through %the1!", phasecell->monst));
|
||||
else
|
||||
addMessage(XLAT("You phase through %the1!", phasecell->wall));
|
||||
}
|
||||
|
||||
movecost(from, dest, 1);
|
||||
|
@ -1523,7 +1526,7 @@ EX eItem targetRangedOrb(cell *c, orbAction a) {
|
|||
}
|
||||
|
||||
if(phasestate == 3) {
|
||||
if(jumpTo(a, c, itOrbPhasing)) phasestate = 4;
|
||||
if(jumpTo(a, c, itOrbPhasing, 0, moNone, jumpthru)) phasestate = 4;
|
||||
else wouldkill_there = true;
|
||||
}
|
||||
else changes.rollback();
|
||||
|
|
12
pcmove.cpp
12
pcmove.cpp
|
@ -802,6 +802,16 @@ bool pcmove::actual_move() {
|
|||
c2->monst = moNone;
|
||||
c2->wall = waRichDie;
|
||||
}
|
||||
else {
|
||||
if(vmsg(miWALL, siWALL, c2, c2->monst))
|
||||
addMessage(XLAT("You can only push this die if the highest number would be on the top!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(mip.d == NO_SPACE) {
|
||||
if(vmsg(miWALL, siWALL, c2, c2->monst))
|
||||
addMessage(XLAT("No room to push %the1.", c2->monst));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -921,8 +931,6 @@ void pcmove::tell_why_cannot_attack() {
|
|||
addMessage(XLAT("You cannot attack Raiders directly!"));
|
||||
else if(isSwitch(c2->monst))
|
||||
addMessage(XLAT("You cannot attack Jellies in their wall form!"));
|
||||
else if(c2->monst == moAnimatedDie)
|
||||
addMessage(XLAT("You can only push this die if the highest number would be on the top!"));
|
||||
else if(c2->monst == moAngryDie)
|
||||
addMessage(XLAT("This die is really angry at you!"));
|
||||
else if((attackflags & AF_WEAK) && isIvy(c2))
|
||||
|
|
27
system.cpp
27
system.cpp
|
@ -187,7 +187,7 @@ EX void initgame() {
|
|||
|
||||
if(!safety) {
|
||||
firstland = specialland;
|
||||
ineligible_starting_land = !landUnlocked(specialland);
|
||||
ineligible_starting_land = !landUnlockedIngame(specialland);
|
||||
}
|
||||
|
||||
if(firstland == laNone || firstland == laBarrier)
|
||||
|
@ -1047,17 +1047,19 @@ EX void remove_emergency_save() {
|
|||
|
||||
scores::score scorebox;
|
||||
|
||||
EX bool save_cheats;
|
||||
|
||||
EX void saveStats(bool emergency IS(false)) {
|
||||
DEBBI(DF_INIT, ("saveStats [", scorefile, "]"));
|
||||
|
||||
if(autocheat) return;
|
||||
if(autocheat && !save_cheats) return;
|
||||
if(scorefile == "") return;
|
||||
#if CAP_TOUR
|
||||
if(tour::on) return;
|
||||
if(tour::on && !save_cheats) return;
|
||||
#endif
|
||||
if(randomPatternsMode) return;
|
||||
if(randomPatternsMode && !save_cheats) return;
|
||||
if(daily::on) return;
|
||||
if(peace::on) return;
|
||||
if(peace::on && !save_cheats) return;
|
||||
if(experimental) return;
|
||||
|
||||
if(!gold() && !racing::on) return;
|
||||
|
@ -1215,8 +1217,13 @@ EX void loadsave() {
|
|||
load_modecode_line(s);
|
||||
}
|
||||
if(buf[0] == 'H' && buf[1] == 'y') {
|
||||
if(fscanf(f, "%s", buf) <= 0) break;
|
||||
if(fscanf(f, "%9999s", buf) <= 0) break;
|
||||
sc.ver = buf;
|
||||
if(sc.ver == "CHEATER!" && save_cheats) {
|
||||
fgets(buf, 12000, f);
|
||||
if(fscanf(f, "%9999s", buf) <= 0) break;
|
||||
sc.ver = buf;
|
||||
}
|
||||
if(sc.ver[1] != '.') sc.ver = '0' + sc.ver;
|
||||
if(verless(sc.ver, "4.4") || sc.ver == "CHEATER!") { ok = false; continue; }
|
||||
ok = true;
|
||||
|
@ -1314,6 +1321,7 @@ EX void loadsave() {
|
|||
|
||||
}
|
||||
fclose(f);
|
||||
// this is the index of Orb of Safety
|
||||
if(ok && sc.box[65 + 4 + itOrbSafety - itOrbLightning])
|
||||
load_last_save();
|
||||
}
|
||||
|
@ -1332,7 +1340,12 @@ EX void load_last_save() {
|
|||
shstream ss;
|
||||
ss.s = meaning[sc.box[MODECODE_BOX]];
|
||||
ss.read(ss.vernum);
|
||||
mapstream::load_geometry(ss);
|
||||
if(ss.vernum < 0xAA05)
|
||||
mapstream::load_geometry(ss);
|
||||
else {
|
||||
ss.write_char(0);
|
||||
load_mode_data_with_zero(ss);
|
||||
}
|
||||
}
|
||||
|
||||
loadBox();
|
||||
|
|
|
@ -1053,7 +1053,7 @@ EX void load_mode_data_with_zero(hstream& f) {
|
|||
case 3: {
|
||||
use_custom_land_list = true;
|
||||
int lt = f.get<int>();
|
||||
if(lt > landtypes) throw hstream_exception();
|
||||
if(lt > landtypes) throw hstream_exception("too many landtypes");
|
||||
for(int i=0; i<lt; i++) {
|
||||
custom_land_list[i] = f.get<char>();
|
||||
custom_land_treasure[i] = f.get<int>();
|
||||
|
@ -1079,7 +1079,7 @@ EX void load_mode_data_with_zero(hstream& f) {
|
|||
vid.creature_scale = f.get<ld>();
|
||||
|
||||
default:
|
||||
throw hstream_exception();
|
||||
throw hstream_exception("wrong option");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue