mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
orb help now lists the OSM information (required refactoring)
This commit is contained in:
parent
035f1ad8de
commit
206e56942a
@ -1206,7 +1206,8 @@ itemtype iinf[ittypes] = {
|
||||
{ 'o', 0x3080D0, "Orb of Morph", NODESCYET},
|
||||
};
|
||||
|
||||
enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue,
|
||||
enum eItem {
|
||||
itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue,
|
||||
itFeather, itSapphire, itHyperstone, itKey,
|
||||
itGreenStone, itOrbYendor,
|
||||
itOrbLightning, itOrbFlash, itOrbWinter, itOrbSpeed, itOrbLife, itOrbShield, itOrbDigging,
|
||||
@ -1240,7 +1241,7 @@ enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBo
|
||||
itInventory,
|
||||
itLavaLily, itDogPlains, itBlizzard, itTerra,
|
||||
itOrbSide1, itOrbSide2, itOrbSide3,
|
||||
itOrbLava, itOrbMorph
|
||||
itOrbLava, itOrbMorph,
|
||||
};
|
||||
|
||||
// --- wall types ---
|
||||
|
6
help.cpp
6
help.cpp
@ -281,6 +281,12 @@ string generateHelpForItem(eItem it) {
|
||||
"\n\nIn the Orb Strategy Mode, each 25 Necromancer's Totems "
|
||||
"you are given a random offensive Orb."
|
||||
);
|
||||
|
||||
if(inv::remaining[it] || inv::usedup[it]) help += "\n\n" + inv::osminfo(it);
|
||||
inv::whichorbinfo = it;
|
||||
inv::compute();
|
||||
if(inv::orbinfoline != "") help += "\n\n" + inv::orbinfoline;
|
||||
if(inv::extra != "") help += "\n\nExtras:" + inv::extra;
|
||||
}
|
||||
|
||||
if(itemclass(it) == IC_ORB || it == itGreenStone || it == itOrbYendor) {
|
||||
|
259
inventory.cpp
259
inventory.cpp
@ -20,7 +20,6 @@ namespace inv {
|
||||
struct lateextraorb {
|
||||
eItem treasure;
|
||||
eItem orb;
|
||||
int at;
|
||||
};
|
||||
|
||||
vector<lateextraorb> lateextraorbs = {
|
||||
@ -90,10 +89,6 @@ namespace inv {
|
||||
return int(mirrorqty0(orb) * sqrt(1.000001+items[itPower]/20.));
|
||||
}
|
||||
|
||||
struct nextinfo { int min, real, max; };
|
||||
|
||||
nextinfo next[ittypes];
|
||||
|
||||
mt19937 invr;
|
||||
|
||||
void sirand(int i) {
|
||||
@ -104,17 +99,37 @@ namespace inv {
|
||||
return invr() % i;
|
||||
}
|
||||
|
||||
eItem whichorbinfo;
|
||||
string orbinfoline, extra;
|
||||
|
||||
string extraline(eItem it, string s) {
|
||||
return " "+XLAT1(iinf[it].name) + " ("+s+")";
|
||||
}
|
||||
|
||||
void gainOrbs(eItem it, eItem o) {
|
||||
auto& nx = next[o == itHyperstone ? o : it];
|
||||
int qty = items[it];
|
||||
if(it == itHolyGrail) {
|
||||
remaining[itOrbIllusion] += qty;
|
||||
nx = {qty+1, qty+1, qty+1};
|
||||
if(it == itOrbIllusion) {
|
||||
orbinfoline += XLAT("Unlocked by: %1 in %2", it, laNone);
|
||||
orbinfoline += XLAT(" (next at %1)", its(qty+1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool nextfound = false;
|
||||
if(qty >= 10) remaining[o]++;
|
||||
else nx = {10,10,10}, nextfound = true;
|
||||
else {
|
||||
if(whichorbinfo == o) {
|
||||
if(it == itHyperstone) {
|
||||
extra += extraline(it, "10");
|
||||
}
|
||||
else {
|
||||
orbinfoline += XLAT("Unlocked by: %1 in %2", it, laNone);
|
||||
orbinfoline += XLAT(" (next at %1)", its(10));
|
||||
}
|
||||
}
|
||||
nextfound = true;
|
||||
}
|
||||
int last = 10;
|
||||
for(int k=0; k<30 || !nextfound; k++) {
|
||||
int maxstep = 15 + 5 * k;
|
||||
@ -129,8 +144,19 @@ namespace inv {
|
||||
}
|
||||
else
|
||||
xnext = last + 1 + irand(maxstep);
|
||||
if(xnext > qty && !nextfound)
|
||||
nx = { last+1, xnext, last + maxstep }, nextfound = true;
|
||||
if(xnext > qty && !nextfound) {
|
||||
if(whichorbinfo == o) {
|
||||
if(it == itHyperstone) {
|
||||
extra += extraline(it, its(last+maxstep));
|
||||
}
|
||||
orbinfoline += XLAT("Unlocked by: %1 in %2", it, laCrossroads);
|
||||
if(maxstep == 1)
|
||||
orbinfoline += XLAT(" (next at %1)", its(last+1));
|
||||
else
|
||||
orbinfoline += XLAT(" (next at %1 to %2)", its(last+1), its(last + maxstep));
|
||||
}
|
||||
nextfound = true;
|
||||
}
|
||||
if(xnext <= qty) remaining[o]++;
|
||||
last = xnext;
|
||||
}
|
||||
@ -143,8 +169,11 @@ namespace inv {
|
||||
return z;
|
||||
}
|
||||
|
||||
void gainMirrors(int qtl) {
|
||||
void gainMirrors(eItem forwhich) {
|
||||
int qtl = items[forwhich];
|
||||
while(qtl > 0) qtl >>= 1, remaining[itOrbMirror]++;
|
||||
if(whichorbinfo == itOrbMirror)
|
||||
extra += extraline(forwhich, its(nextp2(items[which])));
|
||||
}
|
||||
|
||||
vector<eItem> offensiveOrbs = {
|
||||
@ -166,12 +195,62 @@ namespace inv {
|
||||
const int qoff = size(orblist);
|
||||
for(int i=1; i<qoff; i++) swap(orblist[i], orblist[irand(1+i)]);
|
||||
for(int i=0; i<20; i++) {
|
||||
if((i+1)*each <= items[which] - reduce)
|
||||
remaining[orblist[i%qoff]]++;
|
||||
int nextat = (i+1)*each + reduce;
|
||||
if(items[which] >= nextat) {
|
||||
remaining[orblist[i%qoff]]++;
|
||||
}
|
||||
else {
|
||||
if(isIn(whichorbinfo, orblist))
|
||||
extra += extraline(which, its(nextat) + "?");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gainGuestOrbs() {
|
||||
for(int k=0; k<ORBLINES; k++) {
|
||||
auto& oi = orbinfos[k];
|
||||
if(oi.flags & orbgenflags::OSM_AT10) {
|
||||
eItem it = treasureType(oi.l);
|
||||
if(items[it] >= 10) {
|
||||
remaining[oi.orb]++;
|
||||
}
|
||||
if(whichorbinfo == oi.orb) extra += extraline(it, "10");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gainLove() {
|
||||
if(princess::reviveAt) {
|
||||
remaining[itOrbLove]++;
|
||||
int s = gold(NO_LOVE);
|
||||
int last = princess::reviveAt;
|
||||
for(int k=0;; k++) {
|
||||
int nextstep = 50 + 20 * k;
|
||||
last += nextstep;
|
||||
if(last > s) {
|
||||
if(whichorbinfo == itOrbLove) {
|
||||
orbinfoline += XLAT("Unlocked by: %1 in %2", itSavedPrincess, laPrincessQuest);
|
||||
orbinfoline += XLAT(" (next at %1)", its(last));
|
||||
}
|
||||
break;
|
||||
}
|
||||
else { last += nextstep; remaining[itOrbLove]++; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gainLate(eItem tr, eItem orb) {
|
||||
int at = 10 + irand(41);
|
||||
int itr = items[tr];
|
||||
if(itr >= at) remaining[orb]++;
|
||||
if(whichorbinfo == orb)
|
||||
extra += extraline(tr, itr >= at ? (its(at)+"!") : "10-50");
|
||||
}
|
||||
|
||||
void compute() {
|
||||
extra = "";
|
||||
orbinfoline = "";
|
||||
|
||||
for(int i=0; i<ittypes; i++) remaining[i] = -usedup[i];
|
||||
for(int i=0; i<ittypes; i++) if(usedup[i] >= TESTMIRRORED) {
|
||||
@ -182,51 +261,66 @@ namespace inv {
|
||||
|
||||
sirand(rseed);
|
||||
|
||||
vector<pair<eItem, eItem>> itempairs;
|
||||
|
||||
for(int k=0; k<ORBLINES; k++) {
|
||||
auto oi = orbinfos[k];
|
||||
eLand l = oi.l;
|
||||
eItem it = treasureType(l);
|
||||
eItem o = oi.orb;
|
||||
if(oi.gchance) itempairs.emplace_back(it, o);
|
||||
else if(items[it] >= 10) remaining[o]++;
|
||||
}
|
||||
|
||||
sort(itempairs.begin(), itempairs.end());
|
||||
|
||||
gainGuestOrbs();
|
||||
|
||||
gainOrbs(itShard, itOrbMirror);
|
||||
gainOrbs(itHyperstone, itOrbMirror);
|
||||
for(auto p: itempairs)
|
||||
gainOrbs(p.first, p.second);
|
||||
gainOrbs(itDiamond, itOrbFlash);
|
||||
gainOrbs(itGold, itOrbLife);
|
||||
gainOrbs(itSpice, itOrbShield);
|
||||
gainOrbs(itRuby, itOrbLightning);
|
||||
gainOrbs(itElixir, itOrbSpeed);
|
||||
gainOrbs(itBone, itGreenStone);
|
||||
gainOrbs(itHell, itOrbYendor);
|
||||
gainOrbs(itStatue, itOrbTeleport);
|
||||
gainOrbs(itFeather, itOrbSafety);
|
||||
gainOrbs(itSapphire, itOrbWinter);
|
||||
gainOrbs(itFernFlower, itOrbThorns);
|
||||
gainOrbs(itWine, itOrbAether);
|
||||
gainOrbs(itSilver, itOrbDigging);
|
||||
gainOrbs(itRoyalJelly, itOrbInvis);
|
||||
gainOrbs(itEmerald, itOrbPsi);
|
||||
gainOrbs(itPower, itOrbFire);
|
||||
gainOrbs(itHolyGrail, itOrbIllusion);
|
||||
gainOrbs(itGrimoire, itOrbDragon);
|
||||
gainOrbs(itPirate, itOrbTime);
|
||||
gainOrbs(itRedGem, itOrbSpace);
|
||||
gainOrbs(itBombEgg, itOrbFriend);
|
||||
gainOrbs(itCoast, itOrbEmpathy);
|
||||
gainOrbs(itWhirlpool, itOrbWater);
|
||||
gainOrbs(itPalace, itOrbDiscord);
|
||||
gainOrbs(itFjord, itOrbFish);
|
||||
gainOrbs(itSavedPrincess, itOrbLove);
|
||||
gainOrbs(itIvory, itOrbMatter);
|
||||
gainOrbs(itZebra, itOrbFrog);
|
||||
gainOrbs(itElemental, itOrbSummon);
|
||||
gainOrbs(itFulgurite, itOrbStunning);
|
||||
gainOrbs(itMutant, itOrbLuck);
|
||||
gainOrbs(itMutant2, itOrbFreedom);
|
||||
gainOrbs(itLotus, itOrbUndeath);
|
||||
gainOrbs(itWindstone, itOrbAir);
|
||||
gainOrbs(itRose, itOrbBeauty);
|
||||
gainOrbs(itCoral, itOrb37);
|
||||
gainOrbs(itBabyTortoise, itOrbShell);
|
||||
gainOrbs(itApple, itOrbEnergy);
|
||||
gainOrbs(itDragon, itOrbDomination);
|
||||
gainOrbs(itKraken, itOrbSword);
|
||||
gainOrbs(itBarrow, itOrbSword2);
|
||||
gainOrbs(itTrollEgg, itOrbStone);
|
||||
gainOrbs(itSlime, itOrbRecall);
|
||||
gainOrbs(itAmethyst, itOrbNature);
|
||||
gainOrbs(itDodeca, itOrbDash);
|
||||
gainOrbs(itGreenGrass, itOrbBull);
|
||||
gainOrbs(itBull, itOrbHorns);
|
||||
if(items[itOrbYendor]) remaining[itOrbMirror]++;
|
||||
|
||||
gainMirrors(items[itOrbYendor]);
|
||||
gainMirrors(items[itHolyGrail]);
|
||||
|
||||
if(princess::reviveAt) {
|
||||
remaining[itOrbLove]++;
|
||||
int s = gold(NO_LOVE);
|
||||
int last = princess::reviveAt;
|
||||
for(int k=0;; k++) {
|
||||
int nextstep = 50 + 20 * k;
|
||||
last += nextstep;
|
||||
if(last > s) {
|
||||
next[itSavedPrincess] = {last, last, last};
|
||||
break;
|
||||
}
|
||||
else { last += nextstep; remaining[itOrbLove]++; }
|
||||
}
|
||||
}
|
||||
|
||||
gainMirrors(itOrbYendor);
|
||||
gainMirrors(itHolyGrail);
|
||||
gainLove();
|
||||
gainRandomOrbs(offensiveOrbs, itBone, 25, 0);
|
||||
gainRandomOrbs(elementalOrbs, itElemental, 12, 0);
|
||||
gainRandomOrbs(demonicOrbs, itHell, 20, 100);
|
||||
|
||||
for(auto& it: lateextraorbs) {
|
||||
it.at = 10 + irand(41);
|
||||
if(items[it.treasure] >= it.at) remaining[it.orb]++;
|
||||
}
|
||||
for(auto& it: lateextraorbs) gainLate(it.treasure, it.orb);
|
||||
|
||||
if(items[itOrbLove] && !items[itSavedPrincess]) items[itSavedPrincess] = 1;
|
||||
|
||||
@ -285,10 +379,6 @@ namespace inv {
|
||||
"several quests and lands "
|
||||
"give you extremely powerful Orbs of the Mirror.\n";
|
||||
|
||||
string extraline(eItem it, string s) {
|
||||
return " "+XLAT1(iinf[it].name) + " ("+s+")";
|
||||
}
|
||||
|
||||
void evokeBeautyAt(cell *c) {
|
||||
forCellEx(c2, c)
|
||||
if(c2->monst && !isFriendly(c2->monst) && !isIvy(c2->monst)) {
|
||||
@ -321,6 +411,14 @@ namespace inv {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string osminfo(eItem orb) {
|
||||
string s = XLAT("Number of uses left: %1", its(remaining[orb]));
|
||||
int us = usedup[orb];
|
||||
if(us >= TESTMIRRORED) s += XLAT(" (mirrored)"), us = us - MIRRORED + mirrorqty0(orb);
|
||||
if(us) s += XLAT(" (used %1 times)", its(us));
|
||||
return s;
|
||||
}
|
||||
|
||||
void show() {
|
||||
|
||||
@ -401,60 +499,29 @@ namespace inv {
|
||||
else {
|
||||
int icol = iinf[which].color;
|
||||
displaystr(vid.xres/2, vid.fsize*2, 2, vid.fsize*2, XLAT1(iinf[which].name), icol, 8);
|
||||
auto oi = getOrbInfo(which);
|
||||
|
||||
if(mirroring)
|
||||
displaystr(vid.xres/2, vid.fsize*4, 2, vid.fsize, usedup[which] >= TESTMIRRORED ? XLAT("already mirrored") : XLAT("Uses to gain: %1", its(mirrorqty(which))), icol, 8);
|
||||
else {
|
||||
eItem t = treasureType(oi.l);
|
||||
string s = XLAT("Unlocked by: %1 in %2", t, oi.l);
|
||||
if(next[t].min == next[t].max)
|
||||
s += XLAT(" (next at %1)", its(next[t].min));
|
||||
else
|
||||
s += XLAT(" (next at %1 to %2)", its(next[t].min), its(next[t].max));
|
||||
|
||||
displaystr(vid.xres/2, vid.fsize*4, 2, vid.fsize, s, icol, 8);
|
||||
whichorbinfo = which;
|
||||
compute();
|
||||
|
||||
|
||||
string extras = "";
|
||||
for(int k=0; k<ORBLINES; k++) {
|
||||
auto oi = orbinfos[k];
|
||||
if(oi.gchance || oi.orb != which) continue;
|
||||
eItem it = treasureType(oi.l);
|
||||
extras += extraline(it, "10");
|
||||
}
|
||||
|
||||
if(which == itOrbMirror) {
|
||||
extras += extraline(itOrbYendor, its(nextp2(items[itOrbYendor])));
|
||||
extras += extraline(itHolyGrail, its(nextp2(items[itHolyGrail])));
|
||||
auto& nx = next[itHyperstone];
|
||||
extras += extraline(itHyperstone, its(nx.min));
|
||||
}
|
||||
if(isIn(which, offensiveOrbs)) extras += extraline(itBone, its(items[itBone]/25*25+25) + "?");
|
||||
if(isIn(which, elementalOrbs)) extras += extraline(itElemental, its(items[itBone]/20*20+20) + "?");
|
||||
if(isIn(which, demonicOrbs)) extras += extraline(itHell, its(max(125, items[itHell]/25*25+25)) + "?");
|
||||
for(auto& a: lateextraorbs) if(a.orb == which)
|
||||
extras += extraline(a.treasure, items[a.treasure] >= a.at ? (its(a.at)+"!") : "10-50");
|
||||
|
||||
if(extras != "")
|
||||
displaystr(vid.xres/2, vid.fsize*5, 2, vid.fsize, XLAT("Extras:")+extras, icol, 8);
|
||||
displaystr(vid.xres/2, vid.fsize*4, 2, vid.fsize, orbinfoline, icol, 8);
|
||||
|
||||
if(extra != "")
|
||||
displaystr(vid.xres/2, vid.fsize*5, 2, vid.fsize, XLAT("Extras:")+extra, icol, 8);
|
||||
}
|
||||
|
||||
if(remaining[which] != 1 || usedup[which]) {
|
||||
string s = XLAT("Number of uses left: %1", its(remaining[which]));
|
||||
int us = usedup[which];
|
||||
if(us >= TESTMIRRORED) s += XLAT(" (mirrored)"), us = us - MIRRORED + mirrorqty0(which);
|
||||
if(us) s += XLAT(" (used %1 times)", its(us));
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*6, 2, vid.fsize, s, icol, 8);
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*6, 2, vid.fsize, osminfo(which), icol, 8);
|
||||
}
|
||||
|
||||
#if ISMOBILE==0
|
||||
string hot = XLAT1("Hotkey: "); hot += getcstat;
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*5, 2, vid.fsize, hot, icol, 8);
|
||||
#endif
|
||||
|
||||
eOrbLandRelation olr = getOLR(oi.orb, getPrizeLand());
|
||||
eItem tr = treasureType(oi.l);
|
||||
|
||||
eOrbLandRelation olr = getOLR(which, getPrizeLand());
|
||||
|
||||
int col = 0;
|
||||
if(olr == olrDangerous) col = 0xC00000;
|
||||
@ -462,7 +529,7 @@ namespace inv {
|
||||
if(olr == olrForbidden) col = 0x804000;
|
||||
|
||||
if(col)
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*4, 2, vid.fsize, XLAT(olrDescriptions[olr], cwt.c->land, tr, treasureType(cwt.c->land)), col, 8);
|
||||
displaystr(vid.xres/2, vid.yres - vid.fsize*4, 2, vid.fsize, XLAT(olrDescriptions[olr], cwt.c->land, itNone, treasureType(cwt.c->land)), col, 8);
|
||||
|
||||
}
|
||||
}
|
||||
|
22
language.cpp
22
language.cpp
@ -20,6 +20,28 @@ const char *dnameof(eLand l) { return linf[l].name; }
|
||||
const char *dnameof(eWall w) { return winf[w].name; }
|
||||
const char *dnameof(eItem i) { return iinf[i].name; }
|
||||
|
||||
/*
|
||||
string dnameofEnum(eItem i) {
|
||||
FILE *f = fopen("classes.cpp", "rt");
|
||||
while(!feof(f)) {
|
||||
char buf[256];
|
||||
fgets(buf, 256, f);
|
||||
if(strstr(buf, "eItem")) {
|
||||
string ret;
|
||||
int qty = i;
|
||||
while(qty > -1) {
|
||||
char c = fgetc(f);
|
||||
if(c == ' ' || c == '\n' || c == '\r') continue;
|
||||
else if(c == ',') qty--;
|
||||
else if(!qty) ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
*/
|
||||
|
||||
void rep(string& pattern, string what, string to) {
|
||||
while(true) {
|
||||
size_t at = pattern.find(what);
|
||||
|
@ -50,7 +50,7 @@ void showOverview() {
|
||||
s += "@";
|
||||
s += dnameof(treasureType(l));
|
||||
s += "@";
|
||||
s += dnameof(orbType(l));
|
||||
s += dnameof(nativeOrbType(l));
|
||||
if(mapeditor::hasInfix(s))
|
||||
filteredLands[nlid++] = l;
|
||||
}
|
||||
@ -104,7 +104,7 @@ void showOverview() {
|
||||
getcstat = 2000+it;
|
||||
if(displayfrZ(xr*24+c8*5, i0, 1, vf-4, XLAT1(iinf[it].name), col, 0))
|
||||
getcstat = 2000+it;
|
||||
eItem io = orbType(l);
|
||||
eItem io = nativeOrbType(l);
|
||||
if(io == itShard) {
|
||||
if(items[it] >= 10) col = winf[waMirror].color; else col = BLACKISH;
|
||||
if(chaosmode && noChaos(l)) col = REDDISH;
|
||||
|
214
orbgen.cpp
214
orbgen.cpp
@ -1,86 +1,121 @@
|
||||
#define ORBLINES 56
|
||||
|
||||
// orbgen flags
|
||||
|
||||
namespace orbgenflags {
|
||||
// generates in the given land from 10 treasures, in the classic mode
|
||||
static const int LOCAL10 = 1;
|
||||
// generates in the Crossroads from 10 treasures, in the classic mode
|
||||
static const int CROSS10 = 2;
|
||||
// generates in other places from 25 treasures, in the classic mode
|
||||
static const int GLOBAL25 = 4;
|
||||
// in OSM you get it once at 10 treasures
|
||||
static const int OSM_AT10 = 8;
|
||||
|
||||
|
||||
// 'native' functions return this
|
||||
static const int NATIVE = 64;
|
||||
// 'local' orb will be also placed in OSM (at 25 treasures); needs LOCAL10
|
||||
static const int OSM_LOCAL25 = 128;
|
||||
// 'crossroads' orb will be also placed in OSM (at 50 treasures)
|
||||
static const int OSM_CROSS50 = 256;
|
||||
// 'crossroads' orb will be also placed in OSM (at 25 treasures)
|
||||
static const int OSM_CROSS25 = 512;
|
||||
// 'global' orb will be also placed in OSM (at 100 treasures)
|
||||
static const int OSM_GLOBAL100 = 1024;
|
||||
// do not create in the Crossroads in the tactics mode
|
||||
static const int NO_TACTIC = (1<<11);
|
||||
|
||||
// typical combinations
|
||||
static const int S_NATIVE = LOCAL10 | CROSS10 | GLOBAL25 | NATIVE;
|
||||
static const int S_GUEST = LOCAL10 | OSM_AT10;
|
||||
static const int S_YENDOR = S_NATIVE | OSM_LOCAL25 | OSM_CROSS50 | OSM_GLOBAL100 | NO_TACTIC;
|
||||
static const int S_NAT_NT = S_NATIVE | NO_TACTIC;
|
||||
static const int S_NA_O25 = S_NATIVE | OSM_CROSS25;
|
||||
}
|
||||
|
||||
struct orbinfo {
|
||||
int flags;
|
||||
eLand l;
|
||||
int lchance;
|
||||
int gchance;
|
||||
eItem orb;
|
||||
bool is_native() const { using namespace orbgenflags; return flags & NATIVE; }
|
||||
};
|
||||
|
||||
const orbinfo orbinfos[ORBLINES] = {
|
||||
{laGraveyard, 200, 200,itGreenStone}, // must be first so that it does not reduce
|
||||
// chance of other orbs
|
||||
{laJungle, 1200, 1500,itOrbLightning},
|
||||
{laIce, 2000, 1500,itOrbFlash},
|
||||
{laCaves, 1800, 2000,itOrbLife},
|
||||
{laAlchemist, 800, 800,itOrbSpeed},
|
||||
{laDesert, 2500, 1500,itOrbShield},
|
||||
{laHell, 2000, 1000,itOrbYendor},
|
||||
{laRlyeh, 1500, 1500,itOrbTeleport},
|
||||
{laMotion, 2000, 700, itOrbSafety},
|
||||
{laIce, 1500, 0, itOrbWinter},
|
||||
{laDragon, 2500, 0, itOrbWinter},
|
||||
{laDryForest, 2500, 0, itOrbWinter},
|
||||
{laCocytus, 1500, 1500, itOrbWinter},
|
||||
{laCaves, 1200, 0, itOrbDigging},
|
||||
{laDryForest, 500, 4500, itOrbThorns},
|
||||
{laDeadCaves, 1800, 0, itGreenStone},
|
||||
{laDeadCaves, 1800, 1500, itOrbDigging},
|
||||
{laEmerald, 1500, 3500, itOrbPsi},
|
||||
{laWineyard, 900, 1200, itOrbAether},
|
||||
{laHive, 800, 1200, itOrbInvis},
|
||||
{laPower, 0, 3000, itOrbFire},
|
||||
{laMinefield, 0, 3500, itOrbFriend},
|
||||
{laTemple, 0, 3000, itOrbDragon},
|
||||
{laCaribbean, 0, 3500, itOrbTime},
|
||||
{laRedRock, 0, 2500, itOrbSpace},
|
||||
{laCamelot, 1000, 1500, itOrbIllusion},
|
||||
{laOcean, 0, 3000, itOrbEmpathy},
|
||||
{laOcean, 0, 0, itOrbAir},
|
||||
{laPalace, 0, 4000, itOrbDiscord},
|
||||
{laPalace, 0, 0, itOrbFrog},
|
||||
{laZebra, 500, 2100, itOrbFrog},
|
||||
{laLivefjord, 0, 1800, itOrbFish},
|
||||
{laPrincessQuest, 0, 200, itOrbLove},
|
||||
{laIvoryTower, 500, 4000, itOrbMatter},
|
||||
{laElementalWall, 1500, 4000, itOrbSummon},
|
||||
{laStorms, 1000, 2500, itOrbStunning},
|
||||
{laOvergrown, 1000, 800, itOrbLuck},
|
||||
{laWhirlwind, 1250, 3000, itOrbAir},
|
||||
{laHaunted, 1000, 5000, itOrbUndeath},
|
||||
{laClearing, 5000, 5000, itOrbFreedom},
|
||||
{laRose, 2000, 8000, itOrbBeauty},
|
||||
{laWarpCoast, 2000, 8000, itOrb37},
|
||||
{laDragon, 500, 5000, itOrbDomination},
|
||||
{laTortoise, 2500, 1500, itOrbShell},
|
||||
{laEndorian, 150, 2500, itOrbEnergy},
|
||||
{laEndorian, 450, 0, itOrbTeleport},
|
||||
{laKraken, 500, 2500, itOrbSword},
|
||||
{laBurial, 500, 2500, itOrbSword2},
|
||||
{laTrollheim, 750, 1800, itOrbStone},
|
||||
{laMountain, 400, 3500, itOrbNature},
|
||||
{laDungeon, 120, 2500, itOrbRecall},
|
||||
{laReptile, 500, 2100, itOrbDash},
|
||||
{laBull, 720, 3000, itOrbHorns},
|
||||
{laPrairie, 0, 3500, itOrbBull},
|
||||
{laWhirlpool, 0, 0, itOrbSafety},
|
||||
{laWhirlpool, 0, 2000, itOrbWater}, // must be last because it generates a boat
|
||||
{orbgenflags::S_NATIVE, laGraveyard, 200, 200,itGreenStone}, // must be first so that it does not reduce
|
||||
{orbgenflags::S_NATIVE, laJungle, 1200, 1500,itOrbLightning},
|
||||
{orbgenflags::S_NATIVE, laIce, 2000, 1500,itOrbFlash},
|
||||
{orbgenflags::S_NATIVE, laCaves, 1800, 2000,itOrbLife},
|
||||
{orbgenflags::S_NATIVE, laAlchemist, 800, 800,itOrbSpeed},
|
||||
{orbgenflags::S_NATIVE, laDesert, 2500, 1500,itOrbShield},
|
||||
{orbgenflags::S_YENDOR, laHell, 2000, 1000,itOrbYendor},
|
||||
{orbgenflags::S_NATIVE, laRlyeh, 1500, 1500,itOrbTeleport},
|
||||
{orbgenflags::S_NA_O25, laMotion, 2000, 700, itOrbSafety},
|
||||
{orbgenflags::S_NATIVE, laIce, 1500, 0, itOrbWinter},
|
||||
{orbgenflags::S_GUEST, laDragon, 2500, 0, itOrbWinter},
|
||||
{orbgenflags::S_GUEST, laDryForest, 2500, 0, itOrbWinter},
|
||||
{orbgenflags::S_NATIVE, laCocytus, 1500, 1500, itOrbWinter},
|
||||
{orbgenflags::S_GUEST, laCaves, 1200, 0, itOrbDigging},
|
||||
{orbgenflags::S_NATIVE, laDryForest, 500, 4500, itOrbThorns},
|
||||
{orbgenflags::S_GUEST, laDeadCaves, 1800, 0, itGreenStone},
|
||||
{orbgenflags::S_NAT_NT, laDeadCaves, 1800, 1500, itOrbDigging},
|
||||
{orbgenflags::S_NATIVE, laEmerald, 1500, 3500, itOrbPsi},
|
||||
{orbgenflags::S_NATIVE, laWineyard, 900, 1200, itOrbAether},
|
||||
{orbgenflags::S_NATIVE, laHive, 800, 1200, itOrbInvis},
|
||||
{orbgenflags::S_NATIVE, laPower, 0, 3000, itOrbFire},
|
||||
{orbgenflags::S_NATIVE, laMinefield, 0, 3500, itOrbFriend},
|
||||
{orbgenflags::S_NATIVE, laTemple, 0, 3000, itOrbDragon},
|
||||
{orbgenflags::S_NATIVE, laCaribbean, 0, 3500, itOrbTime},
|
||||
{orbgenflags::S_NATIVE, laRedRock, 0, 2500, itOrbSpace},
|
||||
{orbgenflags::S_NATIVE, laCamelot, 1000, 1500, itOrbIllusion},
|
||||
{orbgenflags::S_NATIVE, laOcean, 0, 3000, itOrbEmpathy},
|
||||
{orbgenflags::S_GUEST, laOcean, 0, 0, itOrbAir},
|
||||
{orbgenflags::S_NATIVE, laPalace, 0, 4000, itOrbDiscord},
|
||||
{orbgenflags::S_GUEST, laPalace, 0, 0, itOrbFrog},
|
||||
{orbgenflags::S_NATIVE, laZebra, 500, 2100, itOrbFrog},
|
||||
{orbgenflags::S_NAT_NT, laLivefjord, 0, 1800, itOrbFish},
|
||||
{orbgenflags::S_NAT_NT, laPrincessQuest, 0, 200, itOrbLove},
|
||||
{orbgenflags::S_NATIVE, laIvoryTower, 500, 4000, itOrbMatter},
|
||||
{orbgenflags::S_NAT_NT , laElementalWall, 1500, 4000, itOrbSummon},
|
||||
{orbgenflags::S_NATIVE, laStorms, 1000, 2500, itOrbStunning},
|
||||
{orbgenflags::S_NAT_NT, laOvergrown, 1000, 800, itOrbLuck},
|
||||
{orbgenflags::S_NATIVE, laWhirlwind, 1250, 3000, itOrbAir},
|
||||
{orbgenflags::S_NATIVE, laHaunted, 1000, 5000, itOrbUndeath},
|
||||
{orbgenflags::S_NATIVE, laClearing, 5000, 5000, itOrbFreedom},
|
||||
{orbgenflags::S_NATIVE, laRose, 2000, 8000, itOrbBeauty},
|
||||
{orbgenflags::S_NATIVE, laWarpCoast, 2000, 8000, itOrb37},
|
||||
{orbgenflags::S_NATIVE, laDragon, 500, 5000, itOrbDomination},
|
||||
{orbgenflags::S_NATIVE, laTortoise, 2500, 1500, itOrbShell},
|
||||
{orbgenflags::S_NATIVE, laEndorian, 150, 2500, itOrbEnergy},
|
||||
{orbgenflags::S_GUEST, laEndorian, 450, 0, itOrbTeleport},
|
||||
{orbgenflags::S_NATIVE, laKraken, 500, 2500, itOrbSword},
|
||||
{orbgenflags::S_NATIVE, laBurial, 500, 2500, itOrbSword2},
|
||||
{orbgenflags::S_NATIVE, laTrollheim, 750, 1800, itOrbStone},
|
||||
{orbgenflags::S_NATIVE, laMountain, 400, 3500, itOrbNature},
|
||||
{orbgenflags::S_NATIVE, laDungeon, 120, 2500, itOrbRecall},
|
||||
{orbgenflags::S_NATIVE, laReptile, 500, 2100, itOrbDash},
|
||||
{orbgenflags::S_NATIVE, laBull, 720, 3000, itOrbHorns},
|
||||
{orbgenflags::S_NATIVE, laPrairie, 0, 3500, itOrbBull},
|
||||
{orbgenflags::S_GUEST, laWhirlpool, 0, 0, itOrbSafety},
|
||||
{orbgenflags::S_NATIVE, laWhirlpool, 0, 2000, itOrbWater},
|
||||
};
|
||||
|
||||
eItem orbType(eLand l) {
|
||||
eItem nativeOrbType(eLand l) {
|
||||
if(isElemental(l)) l = laElementalWall;
|
||||
if(inv::on && (l == laMirror || l == laMirrorOld || isCrossroads(l)))
|
||||
return itOrbMirror;
|
||||
if(l == laMirror || l == laMirrorOld) return itShard;
|
||||
for(int i=0; i<ORBLINES; i++)
|
||||
if(orbinfos[i].l == l && orbinfos[i].gchance)
|
||||
if(orbinfos[i].l == l && orbinfos[i].is_native())
|
||||
return orbinfos[i].orb;
|
||||
return itNone;
|
||||
}
|
||||
|
||||
const orbinfo& getOrbInfo(eItem orb) {
|
||||
const orbinfo& getNativityOrbInfo(eItem orb) {
|
||||
for(int i=0; i<ORBLINES; i++)
|
||||
if(orbinfos[i].orb == orb && orbinfos[i].gchance)
|
||||
if(orbinfos[i].orb == orb && orbinfos[i].is_native())
|
||||
return orbinfos[i];
|
||||
static orbinfo oi;
|
||||
oi.l = laMirror;
|
||||
@ -161,7 +196,7 @@ eOrbLandRelation getOLR(eItem it, eLand l) {
|
||||
|
||||
if(it == itOrbIllusion && l == laCamelot) return olrNative1;
|
||||
if(it == itOrbLove) return olrNoPrizeOrb;
|
||||
if(orbType(l) == it) return olrNative;
|
||||
if(nativeOrbType(l) == it) return olrNative;
|
||||
if(it == itOrbWinter && (l == laIce || l == laDryForest || l == laDragon))
|
||||
return olrGuest;
|
||||
if(it == itOrbLuck && l == laIvoryTower)
|
||||
@ -346,9 +381,11 @@ void placePrizeOrb(cell *c) {
|
||||
|
||||
for(int i=0; i<ORBLINES; i++) {
|
||||
const orbinfo& oi(orbinfos[i]);
|
||||
if(!(oi.flags & orbgenflags::GLOBAL25)) continue;
|
||||
|
||||
int mintreas = 25;
|
||||
if(inv::on) {
|
||||
if(oi.orb == itOrbYendor && items[itHell] >= 100) ;
|
||||
if(oi.flags & orbgenflags::OSM_GLOBAL100) mintreas = 100;
|
||||
else continue;
|
||||
}
|
||||
|
||||
@ -357,7 +394,7 @@ void placePrizeOrb(cell *c) {
|
||||
int treas = items[treasureType(oi.l)];
|
||||
if(olr == olrPrize3) treas *= 10;
|
||||
if(olr == olrPrize25 || olr == olrPrize3 || olr == olrGuest || olr == olrMonster || olr == olrAlways) {
|
||||
if(treas < 25) continue;
|
||||
if(treas < mintreas) continue;
|
||||
}
|
||||
else continue;
|
||||
|
||||
@ -386,11 +423,8 @@ void placeLocalOrbs(cell *c) {
|
||||
|
||||
for(int i=0; i<ORBLINES; i++) {
|
||||
const orbinfo& oi(orbinfos[i]);
|
||||
if(!(oi.flags & orbgenflags::LOCAL10)) continue;
|
||||
if(oi.l != l) continue;
|
||||
if(inv::on) {
|
||||
if(oi.orb != itOrbYendor) continue;
|
||||
if(items[itHell] < 25) continue;
|
||||
}
|
||||
if(yendor::on && (oi.orb == itOrbSafety || oi.orb == itOrbYendor))
|
||||
continue;
|
||||
if(!oi.lchance) continue;
|
||||
@ -398,7 +432,15 @@ void placeLocalOrbs(cell *c) {
|
||||
if(ch == 1 && chaosmode && hrand(2) == 0 && items[treasureType(oi.l)] * landMultiplier(oi.l) >= (11+hrand(15)))
|
||||
ch = 0;
|
||||
if(tactic::trailer && ch < 5) ch = 0;
|
||||
if(ch == 0 && items[treasureType(oi.l)] * landMultiplier(oi.l) >= (chaosmode ? 1+hrand(10) : 10)) {
|
||||
int tc = items[treasureType(oi.l)] * landMultiplier(oi.l);
|
||||
int tcmin = (chaosmode ? 1+hrand(10) : 10);
|
||||
if(inv::on) {
|
||||
if(!(oi.flags & orbgenflags::OSM_LOCAL25))
|
||||
tc = 0;
|
||||
else
|
||||
tcmin = 25;
|
||||
}
|
||||
if(ch == 0 && tc >= tcmin) {
|
||||
// printf("local orb\n");
|
||||
c->item = oi.orb;
|
||||
if(oi.orb == itOrbWater && c->land != laOcean) c->wall = waStrandedBoat;
|
||||
@ -415,21 +457,27 @@ void placeCrossroadOrbs(cell *c) {
|
||||
if(peace::on) return;
|
||||
for(int i=0; i<ORBLINES; i++) {
|
||||
const orbinfo& oi(orbinfos[i]);
|
||||
if(!(oi.flags & orbgenflags::CROSS10)) continue;
|
||||
if(!oi.gchance) continue;
|
||||
|
||||
int treas = items[treasureType(oi.l)] * landMultiplier(oi.l);
|
||||
int mintreas = 10;
|
||||
|
||||
if(inv::on) {
|
||||
if(oi.orb == itOrbYendor && items[itHell] >= 50) ;
|
||||
else if(oi.orb == itOrbSafety && items[itFeather] >= 25) ;
|
||||
if(oi.flags & orbgenflags::OSM_CROSS25)
|
||||
mintreas = 25;
|
||||
else if(oi.flags & orbgenflags::OSM_CROSS50)
|
||||
mintreas = 50;
|
||||
else continue;
|
||||
}
|
||||
int treas = items[treasureType(oi.l)] * landMultiplier(oi.l);
|
||||
if(tactic::on && isCrossroads(tactic::lasttactic)) {
|
||||
if(oi.orb == itOrbYendor || oi.orb == itOrbSummon || oi.orb == itOrbFish || oi.orb == itOrbDigging || oi.orb == itOrbLove || oi.orb == itOrbLuck)
|
||||
|
||||
if(tactic::on) {
|
||||
if(isCrossroads(tactic::lasttactic) && (oi.flags & orbgenflags::NO_TACTIC))
|
||||
continue;
|
||||
else mintreas = 0;
|
||||
}
|
||||
else {
|
||||
if(treas < 10) continue;
|
||||
}
|
||||
if(treas < mintreas) continue;
|
||||
|
||||
if(oi.orb == itOrbSafety && c->land == laCrossroads5) continue;
|
||||
int mul = c->land == laCrossroads5 ? 10 : 1;
|
||||
int gch = oi.gchance;
|
||||
@ -445,14 +493,20 @@ void placeOceanOrbs(cell *c) {
|
||||
if(peace::on) return;
|
||||
for(int i=0; i<ORBLINES; i++) {
|
||||
const orbinfo& oi(orbinfos[i]);
|
||||
if(!(oi.flags & orbgenflags::CROSS10)) continue;
|
||||
|
||||
int treas = items[treasureType(oi.l)] * landMultiplier(oi.l);
|
||||
int mintreas = 10;
|
||||
|
||||
if(inv::on) {
|
||||
if(oi.orb == itOrbYendor && items[itHell] >= 50) ;
|
||||
else if(oi.orb == itOrbSafety && items[itFeather] >= 25) ;
|
||||
if(oi.flags & orbgenflags::OSM_CROSS25)
|
||||
mintreas = 25;
|
||||
else if(oi.flags & orbgenflags::OSM_CROSS50)
|
||||
mintreas = 50;
|
||||
else continue;
|
||||
}
|
||||
|
||||
if(items[treasureType(oi.l)] * landMultiplier(oi.l) < 10) continue;
|
||||
if(treas < mintreas) continue;
|
||||
if(!oi.gchance) continue;
|
||||
if(oi.orb == itOrbLife) continue; // useless
|
||||
if(hrand(oi.gchance) >= 20) continue;
|
||||
|
Loading…
Reference in New Issue
Block a user