exporting necessary stuff all over (in progress)

This commit is contained in:
Zeno Rogue 2019-09-05 12:00:55 +02:00
parent caf838ed22
commit 82f24b4b6c
34 changed files with 451 additions and 385 deletions

View File

@ -557,8 +557,7 @@ EX void setGLProjection(color_t col IS(backcolor)) {
glClear(GL_DEPTH_BUFFER_BIT);
}
inline int next_p2 (int a )
{
EX int next_p2 (int a ) {
int rval=1;
// rval<<=1 Is A Prettier Way Of Writing rval*=2;
while(rval<a) rval<<=1;
@ -721,21 +720,6 @@ int gl_width(int size, const char *s) {
return x;
}
namespace glhr {
void texture_vertices(GLfloat *f, int qty, int stride = 2) {
WITHSHADER(
glVertexAttribPointer(aTexture, stride, GL_FLOAT, GL_FALSE, stride * sizeof(GLfloat), f);,
glTexCoordPointer(stride, GL_FLOAT, 0, f);
)
}
void oldvertices(GLfloat *f, int qty) {
WITHSHADER(
glVertexAttribPointer(aPosition, SHDIM, GL_FLOAT, GL_FALSE, SHDIM * sizeof(GLfloat), f);,
glVertexPointer(SHDIM, GL_FLOAT, 0, f);
)
}
}
vector<glhr::textured_vertex> tver;
glhr::textured_vertex charvertex(int x1, int y1, ld tx, ld ty) {
@ -1263,7 +1247,7 @@ ld textscale() {
return vid.fsize / (current_display->radius * cgi.crossf) * (1+vid.alpha) * 2;
}
bool setfsize = true;
EX bool setfsize = true;
EX bool vsync_off;

View File

@ -605,7 +605,9 @@ EX int randpatternCode(cell *c, int rval) {
return 0;
}
#if HDR
#define RANDITER 31
#endif
char rpm_memoize[3][256][RANDITER+1];

View File

@ -61,7 +61,7 @@ const char *trollhelp =
"A big monster from the Living Caves. A dead Troll will be reunited "
"with the rocks, causing some walls to grow around its body.";
const char *trollhelp2 =
EX const char *trollhelp2 =
" Additionally, all items around the killed Troll will be destroyed.";
const char *trollhelpX =
@ -293,7 +293,7 @@ const char *GENDERSWITCH = NODESC;
// --- monsters ---
const char *rosedesc =
EX const char *rosedesc =
"Each eight turns, each rosebush at distance at most 5 from you will "
"release a wave of alluring scent. Creatures on the frontwave "
"will move towards where the scent came from. Even if it causes them "
@ -301,7 +301,7 @@ const char *rosedesc =
"Ivies, Ghosts, Rock Snakes, Rose Ladies and Lords, and monsters restricted to a specific "
"terrain are immune to scents.";
const char *warpdesc =
EX const char *warpdesc =
"This part of the world is warped, restricting the movement somewhat. "
"\"Diagonal\" movement and attacking between triangular cells is not allowed. "
"Flash, Storms, and Freedom spells ignore this, and Ghosts can move, attack, and "
@ -460,7 +460,7 @@ const landtype linf[landtypes] = {
#include "content.cpp"
};
vector<landtacinfo> land_tac = {
EX vector<landtacinfo> land_tac = {
{laIce, 10, 1}, {laDesert, 10, 1},
{laHunting, 5, 2},
{laMotion, 10, 1}, {laCaves, 10, 1}, {laAlchemist, 10, 1},
@ -497,7 +497,7 @@ vector<landtacinfo> land_tac = {
{laWestWall, 10, 1},
};
vector<eLand> randlands = {
EX vector<eLand> randlands = {
laIce, laDesert, laCaves, laAlchemist, laGraveyard, laPower, laLivefjord, laZebra,
laRlyeh, laDryForest, laEmerald, laWineyard, laDeadCaves, laRedRock,
laOvergrown, laWildWest, laWarpCoast, laRuins, laBull, laDragon, laReptile, laDocks
@ -516,18 +516,18 @@ static const flagtype qsSMALLBF = qsSMALLB | qsFIELD;
static const flagtype qsSMALLBE = qsSMALLB | qELLIPTIC;
static const flagtype qsBP = qBINARY | qPENROSE;
geometryinfo1 giEuclid2 = { gcEuclid, 2, 2, 3, {1,1, 0,0 } };
geometryinfo1 giHyperb2 = { gcHyperbolic, 2, 2, 3, {1,1,-1,0 } };
geometryinfo1 giSphere2 = { gcSphere, 2, 2, 3, {1,1,+1,0 } };
EX geometryinfo1 giEuclid2 = { gcEuclid, 2, 2, 3, {1,1, 0,0 } };
EX geometryinfo1 giHyperb2 = { gcHyperbolic, 2, 2, 3, {1,1,-1,0 } };
EX geometryinfo1 giSphere2 = { gcSphere, 2, 2, 3, {1,1,+1,0 } };
geometryinfo1 giEuclid3 = { gcEuclid, 3, 3, 4, {1,1, 1,0 } };
geometryinfo1 giHyperb3 = { gcHyperbolic, 3, 3, 4, {1,1, 1,-1} };
geometryinfo1 giSphere3 = { gcSphere, 3, 3, 4, {1,1, 1,+1} };
EX geometryinfo1 giEuclid3 = { gcEuclid, 3, 3, 4, {1,1, 1,0 } };
EX geometryinfo1 giHyperb3 = { gcHyperbolic, 3, 3, 4, {1,1, 1,-1} };
EX geometryinfo1 giSphere3 = { gcSphere, 3, 3, 4, {1,1, 1,+1} };
geometryinfo1 giSol = { gcSol, 3, 3, 4, {1,1, 1,0 } };
geometryinfo1 giNil = { gcNil, 3, 3, 4, {1,1, 1,0 } };
geometryinfo1 giProduct = { /* will be filled in product::configure() */ };
geometryinfo1 giSL2 = { gcSL2, 3, 3, 4, {1,1,-1,-1} };
EX geometryinfo1 giSol = { gcSol, 3, 3, 4, {1,1, 1,0 } };
EX geometryinfo1 giNil = { gcNil, 3, 3, 4, {1,1, 1,0 } };
EX geometryinfo1 giProduct = { /* will be filled in product::configure() */ };
EX geometryinfo1 giSL2 = { gcSL2, 3, 3, 4, {1,1,-1,-1} };
/** list of available geometries */
vector<geometryinfo> ginf = {

View File

@ -12,7 +12,7 @@ namespace hr {
EX namespace whirlwind {
int fzebra3(cell *c) {
EX int fzebra3(cell *c) {
if(archimedean) return 0;
if(euclid) {
if(fulltorus) return 0;
@ -31,7 +31,7 @@ EX namespace whirlwind {
return zebra3(c);
}
void switchTreasure(cell *c) {
EX void switchTreasure(cell *c) {
c->item = itNone;
if(safety) return;
if(hrand(5000) < PT(100 + 2 * (kills[moAirElemental] + kills[moWindCrow]), 200) && notDippingFor(itWindstone)
@ -41,7 +41,7 @@ EX namespace whirlwind {
placeLocalOrbs(c);
}
int cat(cell *c) {
EX int cat(cell *c) {
if(c->land != laWhirlwind) return 0;
if(c->wall != waNone && c->wall != waChasm &&
c->wall != waSea && !isAlchAny(c) &&
@ -53,11 +53,12 @@ EX namespace whirlwind {
}
cell *where;
int dfrom[2], dto[2], qdirs;
int dfrom[2], dto[2];
EX int qdirs;
int gdist(int d, int e) { return dirdiff(d-e, where->type); }
void calcdirs(cell *c) {
EX void calcdirs(cell *c) {
where = c;
int d = cat(c);
qdirs = 0;
@ -87,7 +88,7 @@ EX namespace whirlwind {
return min(gdist(d, tab[0]), gdist(d, tab[1]));
}
int winddir(int d) {
EX int winddir(int d) {
if(d == -1) return 0;
int mdf = mindist(d, dfrom);
int mdt = mindist(d, dto);
@ -146,7 +147,7 @@ EX namespace whirlwind {
pickupMovedItems(whirlline[i]);
}
void move() {
EX void move() {
manual_celllister cl;
for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i];
@ -160,7 +161,7 @@ EX namespace whirlwind {
}
}
cell *jumpFromWhereTo(cell *c, bool player) {
EX cell *jumpFromWhereTo(cell *c, bool player) {
for(int i=0; i<2; i++) {
calcdirs(c);
if(qdirs != 1) return NULL;
@ -174,7 +175,7 @@ EX namespace whirlwind {
return c;
}
cell *jumpDestination(cell *c) {
EX cell *jumpDestination(cell *c) {
for(int i=0; i<2; i++) {
calcdirs(c);
if(qdirs != 1) return NULL;
@ -188,8 +189,8 @@ EX }
EX namespace elec {
bool havecharge, haveelec, havethunder;
bool afterOrb; // extra charge from the Orb of Lightning
EX bool havecharge, haveelec, havethunder;
EX bool afterOrb; // extra charge from the Orb of Lightning
enum eCharge {
ecCharged, ecGrounded, ecIsolator, ecConductor
@ -371,7 +372,7 @@ EX namespace elec {
}
}
void init() {
EX void init() {
chargecells.clear();
if(!haveelec && !afterOrb) return;
if(1) {
@ -410,7 +411,7 @@ EX namespace elec {
}
}
void cleanup() {
EX void cleanup() {
for(int i=2; i<isize(charges); i++)
charges[i].c->listindex = charges[i].otmp;
charges.resize(0);
@ -434,18 +435,20 @@ EX namespace elec {
draw(dcal[i], ecCharged);
}
bool affected(cell *c) {
EX bool affected(cell *c) {
if(c->listindex >= 0 && c->listindex < isize(charges) && charges[c->listindex].c == c)
return charges[c->listindex].fire;
return false;
}
#if HDR
struct builder {
builder() { init(); }
~builder() { cleanup(); }
};
#endif
void act() {
EX void act() {
int k = tkills();
for(int i=0; i<numplayers(); i++)
if(multi::playerActive(i) && playerpos(i)->land == laStorms && !afterOrb)
@ -458,7 +461,7 @@ EX namespace elec {
// 0 = no close escape, 1 = close escape, 2 = message already shown
EX int lightningfast;
void checklightningfast() {
EX void checklightningfast() {
if(lightningfast == 1) {
addMessage(XLAT("Wow! That was close."));
lightningfast = 2;
@ -505,11 +508,12 @@ struct info {
EX bool forceMouse = false;
EX bool gotoPrincess = false;
EX bool nodungeon = false;
bool squeaked = false;
EX bool squeaked = false;
int saveHP = 0, saveArmedHP = 0;
EX int saveHP = 0;
EX int saveArmedHP = 0;
int reviveAt;
EX int reviveAt;
vector<info*> infos;
@ -530,7 +534,7 @@ struct info {
return i->id;
}
void newFakeInfo(cell *c) {
EX void newFakeInfo(cell *c) {
info *i = new info;
i->prison = NULL;
i->princess = c;
@ -542,7 +546,7 @@ struct info {
assign(i);
}
info *getPrisonInfo(cell *c) {
EX info *getPrisonInfo(cell *c) {
if(euclid || quotient || sphere) return NULL;
if(c->land != laPalace) return NULL;
if(!c->master->alt) return NULL;
@ -552,7 +556,7 @@ struct info {
return infos[ev];
}
info *getPrincessInfo(cell *c) {
EX info *getPrincessInfo(cell *c) {
for(int i=0; i<isize(infos); i++) if(infos[i]->princess == c) {
while(i) {
infos[i]->id = i-1; assign(infos[i]);
@ -565,7 +569,7 @@ struct info {
return NULL;
}
int dist(cell *c) {
EX int dist(cell *c) {
if(c->land != laPalace && c->land != laDungeon) return OUT_OF_PALACE;
else if(quotient || sphere || fulltorus) return OUT_OF_PRISON;
else if(euclid) return celldistAlt(c);
@ -597,7 +601,7 @@ struct info {
return true;
}
void bringBack() {
EX void bringBack() {
if(bringBackAt(cwt.peek())) return;
for(int i=1; i<isize(dcal); i++)
if(bringBackAt(dcal[i])) return;
@ -632,14 +636,14 @@ struct info {
}
}
void save(cell *princess) {
EX void save(cell *princess) {
if(euclid) return;
princess::info *i = princess::getPrincessInfo(princess);
if(!i || i->bestdist <= 3) princess->monst = moNone;
else if(i) setdist(i, OUT_OF_PRISON);
}
void move(cell *ct, cell *cf) {
EX void move(cell *ct, cell *cf) {
if(euclid) return;
princess::info *i = princess::getPrincessInfo(cf);
if(!i) {
@ -655,7 +659,7 @@ struct info {
}
}
void mouseSqueak(cell *c) {
EX void mouseSqueak(cell *c) {
eMonster m = c->monst;
info *i = getPrisonInfo(c);
int d = dist(c);
@ -679,7 +683,7 @@ struct info {
addMessage(XLAT("%The1 squeaks excitedly!", m));
}
void line(cell *c) {
EX void line(cell *c) {
int d = (euclid || c->master->alt) ? celldistAlt(c) : 200;
eMonster m = c->monst;
@ -749,7 +753,7 @@ struct info {
msgid++;
}
void playernear(cell *c) {
EX void playernear(cell *c) {
info *i = getPrisonInfo(c);
int d = dist(c);
// if(i) printf("d=%d bn=%d\n", d, i->bestnear);
@ -778,9 +782,9 @@ EX namespace clearing {
EX std::map<heptagon*, clearingdata> bpdata;
cell *current_root;
EX cell *current_root;
void new_root() {
EX void new_root() {
if(!current_root || current_root->monst != moMutant) {
auto& ac = currentmap->allcells();
int iter = 0;
@ -955,7 +959,7 @@ EX }
EX namespace whirlpool {
bool escaped = false; // escaped the Whirlpool?
EX bool escaped = false; // escaped the Whirlpool?
// next == +1 -> next
// next == -1 -> prev
@ -1074,7 +1078,7 @@ EX namespace whirlpool {
whirlMove(whirlline[z-1], NULL);
}
void move() {
EX void move() {
manual_celllister cl;
for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i];
@ -1098,7 +1102,7 @@ EX namespace mirror {
static const int ATTACK = 8;
#endif
bool build(cell *c) {
EX bool build(cell *c) {
if(penrose || sol) return false;
#if CAP_GP
if(GOLDBERG) {
@ -1130,8 +1134,10 @@ EX namespace mirror {
return false;
}
vector<pair<int, cellwalker>> mirrors;
static const int LIGHTNING = -1; // passed instead of cpid
EX vector<pair<int, cellwalker>> mirrors;
#if HDR
constexpr int LIGHTNING = -1; // passed instead of cpid
#endif
bool noMirrorOn(cell *c) {
return c->monst || (!shmup::on && isPlayerOn(c)) || (geometry != gFieldQuotient && geometry != gTorus && c->cpdist > gamerange());
@ -1167,12 +1173,12 @@ EX namespace mirror {
m.second.at->monst = moMimic;
}
void destroyAll() {
EX void destroyAll() {
unlist();
mirrors.clear();
}
void createMirror(cellwalker cw, int cpid) {
EX void createMirror(cellwalker cw, int cpid) {
if(!shmup::on && inmirror(cw))
cw = reflect(cw);
if(cpid == LIGHTNING)
@ -1223,7 +1229,7 @@ EX namespace mirror {
}
#endif
void createMirrors(cellwalker cw, int cpid) {
EX void createMirrors(cellwalker cw, int cpid) {
if(penrose || sol) return;
@ -1261,7 +1267,7 @@ EX namespace mirror {
}
}
void createMirages(cellwalker cw, int cpid) {
EX void createMirages(cellwalker cw, int cpid) {
#if CAP_ARCM
if(archimedean) {
create_archimedean(cw, cpid, false);
@ -1335,7 +1341,7 @@ EX namespace mirror {
}
}
bool isKilledByMirror(cell *c) {
EX bool isKilledByMirror(cell *c) {
for(auto& m: mirrors) {
cell *c1 = (m.second + wstep).at;
if(inmirror(c1)) c1 = reflect(cellwalker(c1, 0, false)).at;
@ -1410,7 +1416,7 @@ EX namespace mirror {
list();
}
void breakAll() {
EX void breakAll() {
destroyKilled();
unlist();
if(numplayers() == 1)
@ -1576,12 +1582,12 @@ EX namespace mirror {
EX namespace hive {
int hivehard() {
EX int hivehard() {
return items[itRoyalJelly] + hardness_empty();
// 0, 5, 40, 135
}
eMonster randomHyperbug() {
EX eMonster randomHyperbug() {
int h = hivehard();
if(hrand(200) < h)
return moBug2;
@ -1720,7 +1726,7 @@ EX namespace hive {
isIvy(c->monst) || isMutantIvy(c->monst);
}
void movebugs() {
EX void movebugs() {
buginfo.clear();
for(int k=0; k<BUGCOLORS; k++) bugqueue[k].clear();
for(int k=0; k<BUGCOLORS; k++) bugqueue4[k].clear();
@ -1933,28 +1939,30 @@ EX namespace hive {
EX }
#if HDR
inline float& HEAT(cell *c) { return c->LHU.heat; }
#endif
namespace heat {
EX namespace heat {
void affect(cell *c, double delta) {
EX void affect(cell *c, double delta) {
if(isIcyLand(c)) HEAT(c) += delta;
}
double absheat(cell *c) {
EX double absheat(cell *c) {
if(c->land == laCocytus) return HEAT(c) -.6;
if(c->land == laIce || c->land == laBlizzard) return HEAT(c) -.4;
return 0;
}
double celsius(cell *c) { return absheat(c) * 60; }
EX double celsius(cell *c) { return absheat(c) * 60; }
// adjust to the improved heat transfer algorithm in 9.4
const float FIX94 = 1.5;
vector<cell*> offscreen_heat, offscreen_fire; // offscreen cells to take care off
EX vector<cell*> offscreen_heat, offscreen_fire; // offscreen cells to take care off
void processheat(double rate = 1) {
EX void processheat(double rate IS(1)) {
if(markOrb(itOrbSpeed)) rate /= 2;
if(racing::on) return;
int oldmelt = kills[0];
@ -2078,7 +2086,9 @@ namespace heat {
offscreen_heat.push_back(c);
}
#if HDR
#define MELTCOLOR 0xA04040
#endif
for(int i=0; i<dcs; i++) {
cell *c = allcells[i];
@ -2110,7 +2120,7 @@ namespace heat {
vector<pair<cell*, int> > newfires;
void processfires() {
EX void processfires() {
newfires.clear();
vector<cell*> offscreen2;
@ -2223,13 +2233,13 @@ namespace heat {
offscreen_fire = move(offscreen2);
}
}
EX }
bool gardener = false;
bool lifebrought = false; // was Life brought to the Dead Caves?
void livecaves() {
EX void livecaves() {
vector<cell*>& allcells = currentmap->allcells();
int dcs = isize(allcells);
@ -2398,10 +2408,11 @@ void livecaves() {
/* evolver */
EX namespace tortoise {
map<cell*, int> emap;
map<cell*, int> babymap;
int last;
EX map<cell*, int> emap;
EX map<cell*, int> babymap;
EX int last;
#if HDR
enum tflag {
tfShell, tfScute0, tfScute1, tfScute2, tfScute3,
tfEdge1, tfEdge, tfEdge3,
@ -2411,16 +2422,17 @@ EX namespace tortoise {
tfShellDark, tfSkinDark,
tfCOUNT
};
#endif
const int numbits = (int) tfCOUNT;
const int mask = (1<<numbits)-1;
EX const int numbits = (int) tfCOUNT;
EX const int mask = (1<<numbits)-1;
int getb(cell *where) {
EX int getb(cell *where) {
if(emap.count(where)) return emap[where];
return getBits(where);
}
int countBits(int c) {
EX int countBits(int c) {
int bi = 0;
for(int i=0; i<numbits; i++) if((c >> i)&1) bi++;
return bi;
@ -2430,7 +2442,7 @@ EX namespace tortoise {
EX int getRandomBits() { return hrand(1 << numbits); }
bool seek() { return items[itBabyTortoise] % 5; }
EX bool seek() { return items[itBabyTortoise] % 5; }
EX int seekbits;
double seekval[numbits];
double currval[numbits];
@ -2470,18 +2482,18 @@ EX namespace tortoise {
return res;
}
int diff(int bits) { return countBits(bits ^ tortoise::seekbits); }
EX int diff(int bits) { return countBits(bits ^ tortoise::seekbits); }
int progress(int bits) { return numbits - diff(bits); }
string measure(int bits) {
EX string measure(int bits) {
return "(" + its(progress(bits)) + "/" + its(tortoise::numbits) + ")";
}
EX }
namespace dragon {
EX namespace dragon {
int whichturn; // which turn has the target been set on
cell *target; // actually for all Orb of Control
EX int whichturn; // which turn has the target been set on
EX cell *target; // actually for all Orb of Control
void pullback(cell *c) {
int maxlen = 1000;
@ -2499,7 +2511,7 @@ namespace dragon {
bool dragbugs = false;
cell *findhead(cell *c) {
EX cell *findhead(cell *c) {
cell *cor = c;
int maxlen=1000;
findhead:
@ -2545,7 +2557,7 @@ namespace dragon {
return 0;
}
void kill(cell *c, eMonster who) {
EX void kill(cell *c, eMonster who) {
int delay = false;
kills[moDragonHead]++;
int penalty = 0;
@ -2576,7 +2588,7 @@ namespace dragon {
}
}
int totalhp(cell *c) {
EX int totalhp(cell *c) {
int total = 0;
int maxlen = 1000;
while(maxlen-->0) {
@ -2627,7 +2639,7 @@ namespace dragon {
}
}
bool move(cell *dt, cell *df) {
EX bool move(cell *dt, cell *df) {
if(df->monst == moDragonHead) {
dt->mondir = neighborId(dt,df);
// printf("pull back\n");
@ -2658,7 +2670,7 @@ namespace dragon {
return false;
}
}
EX }
EX namespace sword {
@ -2679,7 +2691,7 @@ EX namespace sword {
void possible_divisor(int s) { sword_angles *= s / gcd(sword_angles, s); }
void determine_sword_angles() {
EX void determine_sword_angles() {
sword_angles = 2;
if(SWORDDIM == 3) sword_angles = 1;
else if(IRREGULAR) sword_angles = 840;
@ -2721,9 +2733,9 @@ EX namespace sword {
}
eItem orbof(bool rev) { return rev ? itOrbSword2 : itOrbSword; }
int orbcount(bool rev) { return items[orbof(rev)]; }
EX int orbcount(bool rev) { return items[orbof(rev)]; }
cell *pos(int id, bool rev) {
EX cell *pos(int id, bool rev) {
if(!orbcount(rev)) return NULL;
return pos(playerpos(id), dir[id], rev);
}
@ -2736,7 +2748,7 @@ EX namespace sword {
return false;
}
bool isnear(cell *where) {
EX bool isnear(cell *where) {
if(at(where, false)) return true;
forCellEx(w2, where) if(at(w2, false)) return true;
return false;
@ -2771,7 +2783,7 @@ EX namespace sword {
return cspin(0, 1, 0.1) * cspin(0, 2, 0.1) * cspin(1, 2, 0.1) * Id;
}
sworddir initial(cell *c) {
EX sworddir initial(cell *c) {
sworddir res;
res.angle = (sword::sword_angles / cwt.at->type + 1) / 2;
if(SWORDDIM == 3) res.T = initial_matrix();
@ -2783,7 +2795,7 @@ EX namespace sword {
if(SWORDDIM == 3) dir[i].T = initial_matrix();
}
void reset() {
EX void reset() {
items[itOrbSword] = items[itOrbSword2] = 0;
shuffle(multi::cpid);
}
@ -2793,15 +2805,15 @@ EX namespace sword {
}
EX }
namespace kraken {
EX namespace kraken {
cell *head(cell *c) {
EX cell *head(cell *c) {
if(c->monst == moKrakenH) return c;
if(c->monst == moKrakenT) return c->move(c->mondir);
return NULL;
}
void kill(cell *c, eMonster who) {
EX void kill(cell *c, eMonster who) {
drawParticles(c, minf[moKrakenH].color, 16);
c->monst = moNone;
if(checkOrb(who, itOrbUndeath)) c->monst = moFriendlyGhost;
@ -2821,7 +2833,7 @@ namespace kraken {
}
}
int totalhp(cell *c) {
EX int totalhp(cell *c) {
int total = 0;
for(int i=0; i<c->type; i++)
if(c->move(i)->monst == moKrakenT)
@ -2837,7 +2849,7 @@ namespace kraken {
forCellEx(c2, c) c2->stuntime = 1;
}
void attacks() {
EX void attacks() {
pathdata pd(2);
bool offboat[MAXPLAYER];
for(int i=0; i<MAXPLAYER; i++) offboat[i] = false;
@ -2875,7 +2887,7 @@ namespace kraken {
}
// c is the tentacle which will be the head after the move
void trymove(cell *c) {
EX void trymove(cell *c) {
if(kraken_pseudohept(c)) return;
cell *c2 = c->move(c->mondir);
if(!isWatery(c)) return;
@ -2934,14 +2946,14 @@ namespace kraken {
return;
}
}
EX }
bool barrierhept(cell *c) {
return c->bardir != NOBARRIERS && c->bardir != NODIR;
}
#if CAP_FIELD
namespace prairie {
EX namespace prairie {
using namespace fieldpattern;
@ -2950,7 +2962,7 @@ namespace prairie {
return 0;
}
void spread(cell *c, cell *from) {
EX void spread(cell *c, cell *from) {
int rd;
c->LHU.fi.flowerdist = 8;
@ -3034,12 +3046,12 @@ namespace prairie {
#define RLOW (sphere?(PURE?7:6):PURE?4:2)
#define RHIGH (sphere?(PURE?8:9):PURE?11:13)
bool no_worms(cell *c) {
EX bool no_worms(cell *c) {
int rv = c->LHU.fi.rval;
return rv > RLOW+1 && rv < RHIGH-1;
}
bool isriver(cell *c) {
EX bool isriver(cell *c) {
return c->land == laPrairie && c->LHU.fi.rval <= RHIGH && c->LHU.fi.rval >= RLOW;
}
@ -3047,7 +3059,7 @@ namespace prairie {
return c->LHU.fi.rval <= 8 && c->LHU.fi.rval >= 7;
}
bool nearriver(cell *c) {
EX bool nearriver(cell *c) {
return c->LHU.fi.rval == RHIGH+1 || c->LHU.fi.rval == RLOW-1;
}
@ -3093,9 +3105,9 @@ namespace prairie {
}
}
vector<cell*> beaststogen;
EX vector<cell*> beaststogen;
void generateBeast(cell *c) {
EX void generateBeast(cell *c) {
int beastdistance = min(beastdist(c, 1), beastdist(c, -1));
if(hrand(1000) >= 15 * beastdistance + 2 * items[itGreenGrass]) return;
c->monst = moHerdBull;
@ -3153,7 +3165,7 @@ namespace prairie {
}
}
void move() {
EX void move() {
if(chaosmode) return;
manual_celllister cl;
for(int i=0; i<isize(dcal); i++) {
@ -3177,7 +3189,7 @@ namespace prairie {
return true;
}
void generateTreasure(cell *c) {
EX void generateTreasure(cell *c) {
// if(nearriver(c) && op
if(enter && nearriver(c) && opposite(c) && thisriver(c)) {
int hr = hrand(100);
@ -3193,7 +3205,7 @@ namespace prairie {
}
}
void treasures() {
EX void treasures() {
if(enter && !isriver(cwt.at)) enter = NULL;
else if(!enter && isriver(cwt.at)) enter = cwt.at;
if(isize(tchoices)) {
@ -3212,7 +3224,7 @@ namespace prairie {
tchoices.clear();
}
}
}
EX }
#else
namespace prairie {
bool no_worms(cell *c) { return false; }
@ -3222,11 +3234,11 @@ namespace prairie {
}
#endif
namespace ca {
ld prob = .2;
EX namespace ca {
EX ld prob = .2;
string carule[8][2];
void init() {
EX void init() {
// hexagonal variant of Game of Life, as suggested by Wikipedia
for(int i=0; i<8; i++)
carule[i][0] = "00100000",
@ -3262,7 +3274,7 @@ namespace ca {
auto ah = addHook(hooks_args, 0, readArg);
#endif
void simulate() {
EX void simulate() {
if(cwt.at->land != laCA) return;
vector<cell*>& allcells = currentmap->allcells();
int dcs = isize(allcells);
@ -3282,7 +3294,7 @@ namespace ca {
c->wall = willlive[i] ? waFloorA : waNone;
}
}
}
EX }
auto ccm = addHook(clearmemory, 0, [] () {
heat::offscreen_heat.clear();
@ -3480,13 +3492,13 @@ EX namespace windmap {
return windmap::windcodes[windmap::getId(c)];
}
}
EX }
#endif
// Halloween namespace
EX namespace halloween {
cell *dragoncells[4];
EX cell *dragoncells[4];
vector<cell*> srch;
cell *farempty(bool lastresort = false) {
@ -3730,7 +3742,7 @@ EX }
// ... also includes the Ivory Tower
namespace dungeon {
EX namespace dungeon {
void towerError(cell *c) {
// only care in the standard geometry -- weird ones are intentionally left buggy
@ -4039,7 +4051,7 @@ namespace dungeon {
bool is02(int i) { return i == 0 || i == 2; }
void all(cell *c, int d) {
EX void all(cell *c, int d) {
if(d == 8 && (c->land == laIvoryTower || c->land == laDungeon) && !euclid) {
if(hrand(1000) < 75 && (WDIM == 3 || (c->landparam & 1))) {
@ -4061,6 +4073,6 @@ namespace dungeon {
if(d == (BARLEV == 8 ? 7 : 8) && c->land == laDungeon) build(c);
if(d == 7 && c->land == laDungeon) buildPlates(c);
}
}
EX }
}

View File

@ -79,7 +79,7 @@ EX namespace brownian {
}
}
void dissolve_brownian(cell *c, int x) {
EX void dissolve_brownian(cell *c, int x) {
if(c->land == laBrownian) {
if(among(c->wall, waNone, waStrandedBoat, waMineOpen, waFire)) {
if(c->landparam >= 4 * level) c->landparam = 4 * level - 1;
@ -91,7 +91,7 @@ EX namespace brownian {
}
}
void dissolve(cell *c, int x) {
EX void dissolve(cell *c, int x) {
destroyTrapsAround(c);
if(c->land == laBrownian)
dissolve_brownian(c, x);
@ -146,7 +146,7 @@ EX namespace brownian {
if(!c2->monst && c2->wall != waBoat) c2->monst = moAcidBird;
}
void apply_futures(cell *c) {
EX void apply_futures(cell *c) {
if(futures.count(c)) {
auto m = move(futures[c]);
futures.erase(c);
@ -175,7 +175,7 @@ EX namespace brownian {
}
}
colortable colors = { 0x603000, 0x804000, 0xA05000, 0xC09050, 0xE0D0A0 };
EX colortable colors = { 0x603000, 0x804000, 0xA05000, 0xC09050, 0xE0D0A0 };
color_t get_color(int y) {
return
@ -185,7 +185,7 @@ EX namespace brownian {
colors[4];
}
color_t& get_color_edit(int y) {
EX color_t& get_color_edit(int y) {
return
y < level/2 ? colors[0] :
y < level ? colors[1] :
@ -201,11 +201,11 @@ EX namespace brownian {
}) + addHook(clearmemory, 0, [] () { futures.clear(); })
+ addHook(hooks_gamedata, 0, [] (gamedata* gd) { gd->store(futures); });
}
EX }
namespace westwall {
EX namespace westwall {
void switchTreasure(cell *c) {
EX void switchTreasure(cell *c) {
c->item = itNone;
if(safety) return;
if(hrand(5000) < PT(100 + 2 * (kills[moAirElemental] + kills[moWindCrow]), 200) && c->landparam >= 5 + items[itWest])
@ -255,7 +255,7 @@ namespace westwall {
pickupMovedItems(whirlline[i]);
}
void move() {
EX void move() {
manual_celllister cl;
if(gravity_state == gsLevitation) return;
for(cell *c: dcal) moveAt(c, cl);
@ -272,8 +272,9 @@ namespace westwall {
}
}
}
}
EX }
#if HDR
struct variant_feature {
color_t color_change;
int rate_change;
@ -281,9 +282,12 @@ struct variant_feature {
void (*build)(cell*);
};
extern array<variant_feature, 21> variant_features;
#endif
#define VF [] (cell *c)
const array<variant_feature, 21> variant_features {{
array<variant_feature, 21> variant_features {{
variant_feature{(color_t)(-0x202020), 5, moNecromancer, VF {
if(c->wall == waNone && hrand(1500) < 20) c->wall = waFreshGrave;
if(hrand(20000) < 10 + items[itVarTreasure])

View File

@ -116,13 +116,11 @@ EX color_t poly_outline;
EX vector<unique_ptr<drawqueueitem>> ptds;
#if CAP_GL
color_t text_color;
int text_shift;
GLuint text_texture;
int texts_merged;
int shapes_merged;
vector<glhr::textured_vertex> text_vertices;
EX color_t text_color;
EX int text_shift;
EX GLuint text_texture;
EX int texts_merged;
EX int shapes_merged;
#if MINIMIZE_GL_CALLS
color_t triangle_color, line_color;
@ -191,18 +189,20 @@ SDL_Surface *aux;
#endif
#if CAP_POLY
#if HDR
#define POLYMAX 60000
#endif
EX vector<glvertex> glcoords;
#endif
int spherespecial, spherephase;
EX int spherespecial, spherephase;
#if CAP_POLY
int polyi;
int polyx[POLYMAX], polyxr[POLYMAX], polyy[POLYMAX];
EX int polyx[POLYMAX], polyxr[POLYMAX], polyy[POLYMAX];
int poly_flags;
@ -426,7 +426,7 @@ void polylineColor(SDL_Surface *s, int *x, int *y, int polyi, color_t col) {
lineColor(s, x[i-1], y[i-1], x[i], y[i], col);
}
void filledPolygonColorI(SDL_Surface *s, int* px, int *py, int polyi, color_t col) {
EX void filledPolygonColorI(SDL_Surface *s, int* px, int *py, int polyi, color_t col) {
std::vector<Sint16> spx(px, px + polyi);
std::vector<Sint16> spy(py, py + polyi);
filledPolygonColor(s, spx.data(), spy.data(), polyi, col);
@ -1486,7 +1486,7 @@ ld xintval(const hyperpoint& h) {
return -intval(h, C0);
}
ld backbrightness = .25;
EX ld backbrightness = .25;
purehookset hook_drawqueue;

View File

@ -115,7 +115,7 @@ void bignum::addmul(const bignum& b, int factor) {
while(isize(digits) && digits.back() == 0) digits.pop_back();
}
bignum hrand(bignum b) {
EX bignum hrand(bignum b) {
bignum res;
int d = isize(b.digits);
while(true) {
@ -126,7 +126,7 @@ bignum hrand(bignum b) {
}
}
void operator ++(bignum &b, int) {
EX void operator ++(bignum &b, int) {
int i = 0;
while(true) {
if(isize(b.digits) == i) { b.digits.push_back(1); break; }
@ -141,7 +141,7 @@ void operator ++(bignum &b, int) {
}
}
void operator --(bignum &b, int) {
EX void operator --(bignum &b, int) {
int i = 0;
while(true) {
if(isize(b.digits) == i) { b.digits.push_back(bignum::BASE-1); break; }
@ -444,7 +444,7 @@ void expansion_analyzer::reset() {
descendants.clear();
}
int type_in(expansion_analyzer& ea, cell *c, const cellfunction& f) {
EX int type_in(expansion_analyzer& ea, cell *c, const cellfunction& f) {
if(!ea.N) ea.preliminary_grouping(), ea.reduce_grouping();
vector<int> res;
res.push_back(subtype(c) * 4 + 2);
@ -483,7 +483,7 @@ int type_in_quick(expansion_analyzer& ea, cell *c, const cellfunction& f) {
return -1;
}
bool sizes_known() {
EX bool sizes_known() {
if(GDIM == 3) return false;
if(bounded) return false;
// Castle Anthrax is infinite
@ -494,7 +494,7 @@ bool sizes_known() {
return true;
}
bool trees_known() {
EX bool trees_known() {
return sizes_known() && !(BITRUNCATED && a4 && S7 <= 5);
}
@ -525,7 +525,7 @@ bool mod_allowed() {
return cheater || autocheat || archimedean || tour::on;
}
int curr_dist(cell *c) {
EX int curr_dist(cell *c) {
switch(distance_from) {
case dfPlayer:
return c->cpdist < INFD ? c->cpdist : celldistance(cwt.at, c);
@ -575,7 +575,7 @@ EX int parent_id(cell *c, int which, const cellfunction& cf) {
// set which=1,bonus=1 to get right neighbor on level
void generate_around(cell *c) {
EX void generate_around(cell *c) {
forCellCM(c2, c) if(c2->mpdist > BARLEV) setdist(c2, BARLEV, c);
}
@ -623,12 +623,13 @@ EX namespace ts {
EX }
bool viewdists = false, use_color_codes = true, use_analyzer = true, show_distance_lists = true;
EX bool viewdists = false;
bool use_color_codes = true, use_analyzer = true, show_distance_lists = true;
int first_distance = 0, scrolltime = 0;
bool scrolling_distances = false;
map<int, color_t> expcolors;
EX map<int, color_t> expcolors;
color_t distribute_color(int id) {
if(expcolors.count(id)) return expcolors[id];

View File

@ -13,7 +13,7 @@ namespace hr {
#include <SDL/SDL.h>
#include "init.cpp"
#include "hyper.cpp"
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_gfxPrimitives.h>

View File

@ -766,7 +766,7 @@ void info() {
EX fpattern current_quotient_field = fpattern(0);
EX fpattern fp_invalid = fpattern(0);
bool quotient_field_changed;
EX bool quotient_field_changed;
EX struct fpattern& getcurrfp() {
if(geometry == gFieldQuotient && quotient_field_changed)
@ -852,7 +852,7 @@ EX void enableFieldChange() {
fieldpattern::current_quotient_field.init(gxcur.primes[gxcur.current_prime_id].p);
}
}
EX }
#define currfp fieldpattern::getcurrfp()

View File

@ -9,12 +9,13 @@
#include "hyper.h"
namespace hr {
#if HDR
const flagtype& classflag(eItem it) { return iinf[it].flags; }
const flagtype& classflag(eWall w) { return winf[w].flags; }
const flagtype& classflag(eMonster m) { return minf[m].flags; }
const flagtype& classflag(eLand l) { return linf[l].flags; }
#define ANYFLAGCHECK(name, cond, field, enum) bool name(enum w) { flagtype flag = classflag(w); return cond; } bool name(cell *c) { return name(c->field); }
#define ANYFLAGCHECK(name, cond, field, enum) inline bool name(enum w) { flagtype flag = classflag(w); return cond; } inline bool name(cell *c) { return name(c->field); }
#define MONFLAGCHECK(name, cond) ANYFLAGCHECK(name, cond, monst, eMonster)
#define WALLFLAGCHECK(name, cond) ANYFLAGCHECK(name, cond, wall, eWall)
@ -116,26 +117,27 @@ ITEMFLAGCHECK(isProtectionOrb, flag & IF_PROTECTION)
ITEMFLAGCHECK(isEmpathyOrb, flag & IF_EMPATHY)
ITEMFLAGCHECK(isRangedOrb, flag & IF_RANGED)
ITEMFLAGCHECK(isRevivalOrb, flag & IF_REVIVAL)
#endif
eMonster movegroup(eMonster m);
// watery
bool boatStrandable(cell *c) {
EX bool boatStrandable(cell *c) {
return c->wall == waNone && (c->land == laLivefjord || c->land == laOcean);
}
// monster/wall types
bool isFireOrMagma(cell *w) {
EX bool isFireOrMagma(cell *w) {
return isFire(w) || w->wall == waMagma;
}
int mirrorcolor(bool mirrored) {
EX int mirrorcolor(bool mirrored) {
return winf[mirrored ? waMirror : waCloud].color;
}
bool isMounted(cell *c) {
EX bool isMounted(cell *c) {
if(c && c->monst && c->monst != moTentacleGhost && isMountable(c->monst)) {
for(int i=0; i<numplayers(); i++) {
if(playerpos(i)->monst && sameMonster(c, playerpos(i)))
@ -147,31 +149,31 @@ bool isMounted(cell *c) {
return false;
}
int itemclass(eItem it) { return iinf[it].itemclass; }
EX int itemclass(eItem it) { return iinf[it].itemclass; }
bool isFriendly(eMonster m) { return isFriendlyType(m); }
EX bool isFriendly(eMonster m) { return isFriendlyType(m); }
bool isFriendly(cell *c) {
EX bool isFriendly(cell *c) {
return isMounted(c) || isFriendly(c->monst);
}
bool isFriendlyOrBug(cell *c) { // or killable discord!
EX bool isFriendlyOrBug(cell *c) { // or killable discord!
// do not attack the stunned Princess
if(isPrincess(c->monst) && c->stuntime) return false;
return isFriendly(c) || isBug(c) || (c->monst && markOrb(itOrbDiscord) && !c->stuntime);
}
bool cellUnstable(cell *c) {
EX bool cellUnstable(cell *c) {
return (c->land == laMotion && c->wall == waNone) || c->wall == waTrapdoor;
}
bool cellUnstableOrChasm(cell *c) {
EX bool cellUnstableOrChasm(cell *c) {
return
(c->land == laMotion && c->wall == waNone) ||
c->wall == waChasm || c->wall == waTrapdoor;
}
eMonster elementalOf(eLand l) {
EX eMonster elementalOf(eLand l) {
if(l == laEFire) return moFireElemental;
if(l == laEWater) return moWaterElemental;
if(l == laEAir) return moAirElemental;
@ -179,11 +181,11 @@ eMonster elementalOf(eLand l) {
return moNone;
}
eItem localshardof(eLand l) {
EX eItem localshardof(eLand l) {
return eItem(itFireShard + (l - laEFire));
}
int snakelevel(cell *c) {
EX int snakelevel(cell *c) {
#if CAP_COMPLEX2
if(c->land == laBrownian && among(c->wall, waNone, waMineMine, waFire)) return min(c->landparam / brownian::level, 3);
#endif
@ -192,23 +194,23 @@ int snakelevel(cell *c) {
// from-to
eSlimegroup slimegroup(cell *c) {
EX eSlimegroup slimegroup(cell *c) {
return winf[c->wall].sg;
}
bool isFlying(eMonster m) {
EX bool isFlying(eMonster m) {
return isFlyingType(m) || checkOrb(m, itOrbAether);
}
bool survivesChasm(eMonster m) {
EX bool survivesChasm(eMonster m) {
return isFlying(m);
}
bool ignoresPlates(eMonster m) {
EX bool ignoresPlates(eMonster m) {
return ignoresPlatesType(m) || isFlying(m);
}
bool isInactiveEnemy(cell *w, eMonster forwho) {
EX bool isInactiveEnemy(cell *w, eMonster forwho) {
if(forwho != moPlayer) {
if(w->monst == moGreaterM || w->monst == moLesserM) return true;
if(w->monst == moGreater || w->monst == moLesser) return false;
@ -220,7 +222,7 @@ bool isInactiveEnemy(cell *w, eMonster forwho) {
}
// forpc = true (for PC), false (for golems)
bool isActiveEnemy(cell *w, eMonster forwho) {
EX bool isActiveEnemy(cell *w, eMonster forwho) {
if(((forwho == moPlayer) ? realstuntime(w) : realstuntime(w) > 1))
return false;
if(w->monst == passive_switch) return false;
@ -230,16 +232,16 @@ bool isActiveEnemy(cell *w, eMonster forwho) {
return true;
}
bool isArmedEnemy(cell *w, eMonster forwho) {
EX bool isArmedEnemy(cell *w, eMonster forwho) {
return w->monst != moCrystalSage && w->monst != moCrusher && isActiveEnemy(w, forwho);
}
bool eternalFire(cell *c) {
EX bool eternalFire(cell *c) {
return c->land == laDryForest || (c->land == laPower && !smallbounded) || c->land == laMinefield ||
c->land == laEFire || c->land == laElementalWall;
}
bool haveRangedOrb() {
EX bool haveRangedOrb() {
return
items[itOrbPsi] || items[itOrbDragon] || items[itOrbTeleport] ||
items[itOrbIllusion] || items[itOrbSpace] || items[itOrbAir] ||
@ -249,15 +251,15 @@ bool haveRangedOrb() {
items[itOrbMorph] || items[itOrbPhasing];
}
bool isFriendlyGhost(eMonster m) {
EX bool isFriendlyGhost(eMonster m) {
return m == moFriendlyGhost || (markEmpathy(itOrbAether) && isFriendly(m));
}
bool isGhostAether(eMonster m) {
EX bool isGhostAether(eMonster m) {
return isGhost(m) || checkOrb(m, itOrbAether);
}
bool survivesWater(eMonster m) {
EX bool survivesWater(eMonster m) {
return
m == moShark || m == moGreaterShark || m == moCShark ||
isGhostAether(m) || m == moWitchGhost || m == moShadow ||
@ -269,18 +271,18 @@ bool survivesWater(eMonster m) {
}
// survives Mercury or Sulphur or Lava
bool survivesPoison(eMonster m, eWall p) {
EX bool survivesPoison(eMonster m, eWall p) {
return
isGhostAether(m) || m == moWitchGhost || m == moShadow ||
isBird(m) || m == moAirElemental || isDragon(m) || isWorm(m);
}
// flying even if stunned
bool isPermanentFlying(eMonster m) {
EX bool isPermanentFlying(eMonster m) {
return m == moAirElemental || isGhostAether(m);
}
bool survivesFire(eMonster m) {
EX bool survivesFire(eMonster m) {
return
isGhostAether(m) || m == moWitchWinter || m == moWitchGhost ||
m == moBomberbird || m == moTameBomberbird || m == moTameBomberbirdMoved ||
@ -288,15 +290,15 @@ bool survivesFire(eMonster m) {
isDragon(m) || m == moShadow;
}
bool survivesWall(eMonster m) {
EX bool survivesWall(eMonster m) {
return isGhostAether(m);
}
bool survivesThorns(eMonster m) {
EX bool survivesThorns(eMonster m) {
return isGhostAether(m) || m == moSkeleton || m == moDraugr;
}
bool survivesFall(eMonster m) {
EX bool survivesFall(eMonster m) {
return isBird(m) || m == moAirElemental || m == moSkeleton || isDragon(m) || m == moShadow || isGhostAether(m);
}
@ -312,11 +314,11 @@ EX bool checkOrb2(eMonster m1, eItem orb) {
return false;
}
bool ignoresSmell(eMonster m) {
EX bool ignoresSmell(eMonster m) {
return ignoresSmellType(m) || checkOrb(m, itOrbBeauty) || checkOrb(m, itOrbAether) || checkOrb(m, itOrbShield);
}
bool highwall(cell *c) {
EX bool highwall(cell *c) {
if(c->wall == waGlass) return false;
if(wmescher && wmspatial && c->wall == waBarrier && c->land == laOceanWall)
return false;
@ -327,7 +329,7 @@ bool highwall(cell *c) {
return winf[c->wall].glyph == '#' || c->wall == waClosedGate;
}
int chasmgraph(cell *c) {
EX int chasmgraph(cell *c) {
if(c->wall == waChasm || c->wall == waInvisibleFloor) return 2;
if(isChasmy(c)) return 1;
if(isWateryOrBoat(c)) return 1;
@ -336,11 +338,11 @@ int chasmgraph(cell *c) {
return 0;
}
bool conegraph(cell *c) {
EX bool conegraph(cell *c) {
return wmescher && wmspatial && (conegraphtype(c) || (c->wall == waBarrier && c->land == laOceanWall));
}
bool hornStuns(cell *c) {
EX bool hornStuns(cell *c) {
eMonster m = c->monst;
return
m == moRagingBull || m == moSleepBull || m == moHerdBull ||

View File

@ -841,7 +841,7 @@ void draw_floorshape(cell *c, const transmatrix& V, const floorshape &fsh, color
draw_shapevec(c, V, fsh.b, col, prio);
}
void draw_qfi(cell *c, const transmatrix& V, color_t col, PPR prio = PPR::DEFAULT, vector<hpcshape> floorshape::* tab = &floorshape::b) {
EX void draw_qfi(cell *c, const transmatrix& V, color_t col, PPR prio IS(PPR::DEFAULT), vector<hpcshape> floorshape::* tab IS(&floorshape::b)) {
if(qfi.shape)
queuepolyat(V * qfi.spin, *qfi.shape, col, prio);
else if(qfi.usershape >= 0) {

View File

@ -19,8 +19,8 @@ extern eForcemovetype forcedmovetype;
EX int lastsafety;
EX int mutantphase;
EX int turncount;
int rosewave, rosephase;
int avengers, mirrorspirits, wandering_jiangshi, jiangshi_on_screen;
EX int rosewave, rosephase;
EX int avengers, mirrorspirits, wandering_jiangshi, jiangshi_on_screen;
EX int gamerange_bonus = 0;
EX int gamerange() { return getDistLimit() + gamerange_bonus; }
@ -29,16 +29,15 @@ cell *lastmove;
eLastmovetype lastmovetype, nextmovetype;
eForcemovetype forcedmovetype;
bool hauntedWarning;
bool survivalist;
EX bool hauntedWarning;
EX bool survivalist;
bool hardcore = false;
int hardcoreAt;
EX bool hardcore = false;
EX int hardcoreAt;
set<int> snaketypes;
flagtype havewhat, hadwhat;
#if HDR
#define HF_BUG Flag(0)
#define HF_EARTH Flag(1)
#define HF_BIRD Flag(2)
@ -71,22 +70,24 @@ flagtype havewhat, hadwhat;
#define HF_ALT Flag(29)
#define HF_MONK Flag(30)
#define HF_WESTWALL Flag(31)
#endif
EX flagtype havewhat, hadwhat;
bool seenSevenMines = false;
EX bool seenSevenMines = false;
EX bool pureHardcore() { return hardcore && hardcoreAt < PUREHARDCORE_LEVEL; }
EX bool canmove = true;
int sagephase = 0;
EX int sagephase = 0;
/** number of Grails collected, to show you as a knight */
int knighted = 0;
EX int knighted = 0;
bool usedSafety = false;
eLand safetyland;
int safetyseed;
EX bool usedSafety = false;
EX eLand safetyland;
EX int safetyseed;
int showid = 0;
@ -95,15 +96,15 @@ EX bool invismove = false;
/** last move was invisible due to Orb of Fish (thus Fish still see you)*/
EX bool invisfish = false;
int noiseuntil; // noise until the given turn
EX int noiseuntil; // noise until the given turn
void createNoise(int t) {
EX void createNoise(int t) {
noiseuntil = max(noiseuntil, turncount+t);
invismove = false;
if(shmup::on) shmup::visibleFor(100 * t);
}
int currentLocalTreasure;
EX int currentLocalTreasure;
bool landvisited[landtypes];
@ -116,7 +117,7 @@ EX array<int, motypes> kills;
EX int explore[10], exploreland[10][landtypes], landcount[landtypes];
EX map<modecode_t, array<int, ittypes> > hiitems;
bool orbused[ittypes], lastorbused[ittypes];
EX bool orbused[ittypes], lastorbused[ittypes];
/** should we center the screen on the PC? */
EX bool playermoved = true;
/** if false, make the PC look in direction cwt.spin (after attack); otherwise, make them look the other direction (after move) */
@ -125,18 +126,18 @@ EX bool flipplayer = true;
EX int cheater = 0;
/** this value is used when using Orb of Safety in the Camelot in Pure Tactics Mode */
int anthraxBonus = 0;
EX int anthraxBonus = 0;
/** the list of all nearby cells, according to cpdist */
EX vector<cell*> dcal;
/** the list of all nearby cells, according to current pathdist */
vector<cell*> pathq;
EX vector<cell*> pathq;
/** offscreen cells to take care off */
vector<cell*> offscreen;
EX vector<cell*> offscreen;
/** list of monsters to move (pathq restriced to monsters) */
vector<cell*> pathqm;
EX vector<cell*> pathqm;
/** list of cells that the monsters are targetting (PCs, allies, Thumpers, etc.) */
vector<cell*> targets;
@ -152,13 +153,13 @@ vector<pair<cell*, eMonster>> tempmonsters;
* the opposite cell will be added to the queue first,
* which helps the AI.
**/
vector<int> reachedfrom;
EX vector<int> reachedfrom;
/** monsters to move, ordered by the number of possible good moves */
vector<cell*> movesofgood[MAX_EDGE+1];
/** The position of the first cell in dcal in distance 7. New wandering monsters can be generated in dcal[first7..]. */
int first7;
EX int first7;
/** Cellwalker describing the single player. Also used temporarily in shmup and multiplayer modes. */
EX cellwalker cwt;
@ -792,7 +793,7 @@ EX bool passable(cell *w, cell *from, flagtype flags) {
return true;
}
vector<pair<cell*, int> > airmap;
EX vector<pair<cell*, int> > airmap;
EX int airdist(cell *c) {
if(!(havewhat & HF_AIR)) return 3;
@ -1376,7 +1377,7 @@ EX eMonster active_switch() {
return eMonster(passive_switch ^ moSwitch1 ^ moSwitch2);
}
vector<cell*> crush_now, crush_next;
EX vector<cell*> crush_now, crush_next;
EX bool monstersnear(stalemate1& sm) {
@ -1476,7 +1477,7 @@ namespace multi { bool aftermove; }
EX bool monstersnear2();
int lastkills;
EX int lastkills;
EX bool multimove() {
if(multi::cpid == 0) lastkills = tkills();
@ -2835,11 +2836,11 @@ bool bugsfighting;
bool keepLightning = false;
int statuecount;
EX int statuecount;
int tidalphase;
int tidalsize, tide[200];
EX int tidalsize, tide[200];
EX void calcTidalPhase() {
if(!tidalsize) {
@ -2879,9 +2880,11 @@ EX int tidespeed() {
bool recalcTide;
#if HDR
#define SEADIST LHU.bytes[0]
#define LANDDIST LHU.bytes[1]
#define CHAOSPARAM LHU.bytes[2]
#endif
#if CAP_FIELD
EX int lavatide(cell *c, int t) {
@ -2963,7 +2966,7 @@ EX void buildAirmap() {
* 2 - wave phase 1
* 3 - wave phase 2
*/
map<cell*, int> rosemap;
EX map<cell*, int> rosemap;
EX int rosedist(cell *c) {
if(!(havewhat&HF_ROSE)) return 0;
@ -3144,7 +3147,7 @@ struct pathdata {
#endif
// pathdist end
vector<pair<cell*, int> > butterflies;
EX vector<pair<cell*, int> > butterflies;
EX void addButterfly(cell *c) {
for(int i=0; i<isize(butterflies); i++)
@ -4398,7 +4401,7 @@ EX void beastAttack(cell *c, bool player) {
}
}
bool quantum;
EX bool quantum;
EX cell *moveNormal(cell *c, flagtype mf) {
eMonster m = c->monst;
@ -5680,7 +5683,9 @@ EX int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
return val;
}
#define STRONGWIND 99
#if HDR
constexpr int STRONGWIND = 99;
#endif
EX void movegolems(flagtype flags) {
if(items[itOrbEmpathy] && items[itOrbSlaying])
@ -6255,8 +6260,8 @@ EX void markAmbush(cell *c, manual_celllister& cl) {
markAmbush(c2, cl);
}
int ambush_distance;
bool ambushed;
EX int ambush_distance;
EX bool ambushed;
EX void checkAmbushState() {
if(havewhat & HF_HUNTER) {
@ -6937,7 +6942,7 @@ EX void collectMessage(cell *c2, eItem which) {
}
}
int ambushval;
EX int ambushval;
EX int ambushSize(cell *c, eItem what) {
bool restricted = false;
@ -7581,7 +7586,7 @@ EX void knightFlavorMessage(cell *c2) {
int mine_adjacency_rule = 0;
map<cell*, vector<cell*>> adj_memo;
EX map<cell*, vector<cell*>> adj_memo;
EX bool geometry_has_alt_mine_rule() {
if(WDIM == 2) return VALENCE > 3;
@ -7722,8 +7727,10 @@ namespace orbbull {
}
}
#if HDR
// predictable or not
static constexpr bool randterra = false;
#endif
EX void terracotta(cell *c) {
if(c->wall == waTerraWarrior && !c->monst && !racing::on) {
@ -7955,7 +7962,7 @@ EX bool monsterPushable(cell *c2) {
return (c2->monst != moFatGuard && !(isMetalBeast(c2->monst) && c2->stuntime < 2) && c2->monst != moTortoise && c2->monst != moTerraWarrior && c2->monst != moVizier);
}
bool got_survivalist;
EX bool got_survivalist;
EX bool should_switchplace(cell *c1, cell *c2) {
if(isPrincess(c2->monst) || among(c2->monst, moGolem, moIllusion, moMouse, moFriendlyGhost))

View File

@ -408,7 +408,7 @@ hpcshape
static const ld hcrossf7 = 0.620672, hexf7 = 0.378077, tessf7 = 1.090550, hexhexdist7 = 0.566256;
#endif
bool scale_used() { return (shmup::on && geometry == gNormal && BITRUNCATED) ? (cheater || autocheat) : true; }
EX bool scale_used() { return (shmup::on && geometry == gNormal && BITRUNCATED) ? (cheater || autocheat) : true; }
void geometry_information::prepare_basics() {
@ -601,7 +601,7 @@ void geometry_information::prepare_basics() {
currfp.analyze();
}
transmatrix xspinpush(ld dir, ld dist) {
EX transmatrix xspinpush(ld dir, ld dist) {
if(euclid)
return eupush(cos(dir) * dist, -sin(dir) * dist);
else
@ -610,7 +610,7 @@ transmatrix xspinpush(ld dir, ld dist) {
EX purehookset hooks_swapdim;
namespace geom3 {
EX namespace geom3 {
// Here we convert between the following parameters:
@ -638,11 +638,11 @@ namespace geom3 {
return lev_to_projection(0) / proj;
}
ld factor_to_projection(ld fac) {
EX ld factor_to_projection(ld fac) {
return lev_to_projection(0) / fac;
}
ld lev_to_factor(ld lev) {
EX ld lev_to_factor(ld lev) {
if(prod) return -lev;
if(WDIM == 3) return lev;
if(GDIM == 3) return vid.depth - lev;
@ -654,7 +654,7 @@ namespace geom3 {
return vid.depth - projection_to_abslev(factor_to_projection(fac));
}
void do_auto_eye() {
EX void do_auto_eye() {
if(!vid.auto_eye) return;
auto& cs = getcs();
if(cs.charid < 4)
@ -671,9 +671,9 @@ namespace geom3 {
return cosh(vid.depth - lev);
}
string invalid;
EX string invalid;
ld actual_wall_height() {
EX ld actual_wall_height() {
if(hybri) return cgi.plevel;
#if CAP_GP
if(GOLDBERG && vid.gp_autoscale_heights)
@ -681,7 +681,7 @@ namespace geom3 {
#endif
return vid.wall_height;
}
}
EX }
void geometry_information::prepare_compute3() {
using namespace geom3;
@ -897,7 +897,7 @@ EX map<string, geometry_information> cgis;
#define cgi (*cgip)
#endif
int last_texture_step;
EX int last_texture_step;
int ntimestamp;

View File

@ -71,7 +71,7 @@ EX namespace gp {
#if CAP_GP
EX loc param = loc(1, 0);
hyperpoint next;
EX hyperpoint next;
struct goldberg_mapping_t {
cellwalker cw;
@ -80,9 +80,9 @@ EX namespace gp {
loc start;
};
int fixg6(int x) { return (x + MODFIXER) % SG6; }
EX int fixg6(int x) { return (x + MODFIXER) % SG6; }
int get_code(const local_info& li) {
EX int get_code(const local_info& li) {
return
((li.relative.first & 15) << 0) +
((li.relative.second & 15) << 4) +
@ -475,7 +475,7 @@ EX namespace gp {
DEBB(DF_GP, ("DONE"))
}
hyperpoint loctoh_ort(loc at) {
EX hyperpoint loctoh_ort(loc at) {
return point3(at.first, at.second, 1);
}
@ -559,7 +559,7 @@ EX namespace gp {
}
}
hyperpoint get_corner_position(const local_info& li, int cid, ld cf = 3) {
EX hyperpoint get_corner_position(const local_info& li, int cid, ld cf IS(3)) {
int i = li.last_dir;
if(i == -1)
return atz(dir_matrix(cid), cgi.gpdata->corners, li.relative, 0, cf);
@ -569,7 +569,7 @@ EX namespace gp {
}
}
hyperpoint get_corner_position(cell *c, int cid, ld cf = 3) {
EX hyperpoint get_corner_position(cell *c, int cid, ld cf IS(3)) {
return get_corner_position(get_local_info(c), cid, cf);
}
@ -620,7 +620,7 @@ EX namespace gp {
return v;
}
loc human_representation(loc v) {
EX loc human_representation(loc v) {
int& x = v.first, &y = v.second;
if(S3 == 3) while(x < 0 || y < 0 || (x == 0 && y > 0))
v = v * loc(0, 1);

View File

@ -65,7 +65,7 @@ hstate transition(hstate s, int dir) {
#define COMPUTE -1000000
// create a new heptagon
heptagon *buildHeptagon1(heptagon *h, heptagon *parent, int d, hstate s, int pard = 0) {
EX heptagon *buildHeptagon1(heptagon *h, heptagon *parent, int d, hstate s, int pard IS(0)) {
h->alt = NULL;
h->s = s;
h->c.connect(pard, parent, d, false);

View File

@ -313,19 +313,21 @@ EX ld edge_of_triangle_with_angles(ld alpha, ld beta, ld gamma) {
return acos_auto((cos(alpha) + cos(beta) * cos(gamma)) / (sin(beta) * sin(gamma)));
}
hyperpoint hpxy(ld x, ld y) {
EX hyperpoint hpxy(ld x, ld y) {
return hpxyz(x,y, sl2 ? sqrt(1+x*x+y*y) : translatable ? 1 : sphere ? sqrt(1-x*x-y*y) : sqrt(1+x*x+y*y));
}
hyperpoint hpxy3(ld x, ld y, ld z) {
EX hyperpoint hpxy3(ld x, ld y, ld z) {
return hpxyz3(x,y,z, sl2 ? sqrt(1+x*x+y*y-z*z) :translatable ? 1 : sphere ? sqrt(1-x*x-y*y-z*z) : sqrt(1+x*x+y*y+z*z));
}
#if HDR
// a point (I hope this number needs no comments ;) )
constexpr hyperpoint Cx12 = hyperpoint(1,0,1.41421356237,0);
constexpr hyperpoint Cx13 = hyperpoint(1,0,0,1.41421356237);
#define Cx1 (GDIM==2?Cx12:Cx13)
#endif
EX bool zero_d(int d, hyperpoint h) {
for(int i=0; i<d; i++) if(h[i]) return false;
@ -985,9 +987,9 @@ EX hyperpoint hpxd(ld d, ld x, ld y, ld z) {
EX ld signum(ld x) { return x<0?-1:x>0?1:0; }
bool asign(ld y1, ld y2) { return signum(y1) != signum(y2); }
EX bool asign(ld y1, ld y2) { return signum(y1) != signum(y2); }
ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2); }
EX ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2); }
EX transmatrix parallel_transport(const transmatrix Position, const transmatrix& ori, const hyperpoint direction) {
if(nonisotropic) return nisot::parallel_transport(Position, direction);
@ -1143,11 +1145,11 @@ EX ld geo_dist(const hyperpoint h1, const hyperpoint h2, iePrecision p) {
return hypot_d(3, inverse_exp(inverse(nisot::translate(h1)) * h2, p, false));
}
hyperpoint lp_iapply(const hyperpoint h) {
EX hyperpoint lp_iapply(const hyperpoint h) {
return nisot::local_perspective_used() ? inverse(nisot::local_perspective) * h : h;
}
hyperpoint lp_apply(const hyperpoint h) {
EX hyperpoint lp_apply(const hyperpoint h) {
return nisot::local_perspective_used() ? nisot::local_perspective * h : h;
}

View File

@ -13,9 +13,9 @@ EX namespace inv {
EX bool on;
EX array<int, ittypes> usedup;
EX array<int, ittypes> remaining;
array<int, ittypes> extra_orbs;
EX array<int, ittypes> extra_orbs;
int rseed;
EX int rseed;
EX bool usedForbidden;
@ -112,8 +112,8 @@ EX namespace inv {
return invr() % i;
}
eItem whichorbinfo;
string orbinfoline, extra;
EX eItem whichorbinfo;
EX string orbinfoline, extra;
string extraline(eItem it, string s) {
return " "+XLAT1(iinf[it].name) + " ("+s+")";
@ -404,7 +404,7 @@ EX namespace inv {
bool mirroring;
const char* helptext =
EX const char* helptext =
"You are playing in the Orb Strategy Mode. Collecting treasure "
"gives you access to magical Orb powers. In this mode, "
"unlocking requirements are generally higher, and "
@ -444,7 +444,7 @@ EX namespace inv {
}
}
string osminfo(eItem orb) {
EX 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);
@ -655,7 +655,7 @@ EX namespace inv {
}
#if CAP_SAVE
void applyBox(eItem it) {
EX void applyBox(eItem it) {
applyBoxNum(usedup[it]);
}
#endif

View File

@ -21,6 +21,7 @@ EX int rearrange_less = 10;
EX int cellcount;
#if HDR
struct cellinfo {
cell *owner;
map<cell*, transmatrix> relmatrices;
@ -35,10 +36,11 @@ struct cellinfo {
int patterndir;
int generation;
};
#endif
map<cell*, int> cellindex;
EX map<cell*, int> cellindex;
vector<cellinfo> cells;
EX vector<cellinfo> cells;
ld inner(hyperpoint h1, hyperpoint h2) {
return
@ -520,7 +522,7 @@ bool step(int delta) {
return false;
}
void compute_geometry() {
EX void compute_geometry() {
if(IRREGULAR) {
ld scale = sqrt(isize(cells_of_heptagon) * 1. / isize(cells));
cgi.crossf *= scale;
@ -553,13 +555,15 @@ bool draw_cell_schematics(cell *c, transmatrix V) {
return false;
}
#if HDR
struct heptinfo {
heptspin base;
vector<cell*> subcells;
vector<int> celldists[2];
};
#endif
map<heptagon*, heptinfo> periodmap;
EX map<heptagon*, heptinfo> periodmap;
EX void link_to_base(heptagon *h, heptspin base) {
// printf("linking %p to %p/%d\n", h, base.at, base.spin);
@ -1006,7 +1010,7 @@ EX void visual_creator() {
gridmaking = true;
}
void auto_creator() {
EX void auto_creator() {
variation = eVariation::pure;
int cc = cellcount;
bitruncations_requested = bitruncations_performed;

View File

@ -26,7 +26,7 @@ EX int genrange_bonus = 0;
EX bool chaosUnlocked = false;
EX bool chaosAchieved = false;
void doOvergenerate() {
EX void doOvergenerate() {
for(int i=0; i<numplayers(); i++)
setdist(playerpos(i), 7 - getDistLimit() - genrange_bonus, NULL);
}

View File

@ -84,7 +84,7 @@ EX bool landUnlockedRPM(eLand n) {
return false;
}
int variant_unlock_value() {
EX int variant_unlock_value() {
return inv::on ? 75 : 30;
}
@ -205,7 +205,7 @@ bool lchance(eLand l) {
return hrand(100) >= 40 * kills[elementalOf(l)] / (elementalKills()+1);
}
eLand pickLandRPM(eLand old) {
EX eLand pickLandRPM(eLand old) {
while(true) {
eLand n = randlands[hrand(isize(randlands))];
if(incompatible(n, old)) continue;

View File

@ -320,14 +320,17 @@ int main() {
if(isize(elt) >= 2) { javastring += elt; vchars.push_back(elt); }
}
printf("\n");
printf("#if HDR\n");
printf("#define NUMEXTRA %d\n", isize(vchars));
printf("#define NATCHARS {");
for(auto&& elt : vchars) printf("\"%s\",", elt.c_str());
printf("};\n");
printf("const char* natchars[NUMEXTRA] = NATCHARS;");
printf("extern char* natchars[NUMEXTRA];\n");
printf("#endif\n");
printf("char* natchars[NUMEXTRA] = NATCHARS;\n");
printf("//javastring = \"%s\";\n", javastring.c_str());
printf("\nint transcompleteness[NUMLAN] = {");
printf("\nEX int transcompleteness[NUMLAN] = {");
for(int i=0; i<NUMLAN; i++) printf("%d, ", completeness[i]);
printf("};\n");

View File

@ -245,7 +245,7 @@ int getSeepcount() {
return seepcount;
}
bool canReachPlayer(cell *cf, eMonster m) {
EX bool canReachPlayer(cell *cf, eMonster m) {
manual_celllister cl;
cl.add(cf);
for(int i=0; i<isize(cl.lst) && i < 10000; i++) {

View File

@ -9,7 +9,9 @@
namespace hr {
EX namespace nisot {
#if HDR
typedef array<float, 3> ptlow;
#endif
EX transmatrix local_perspective;
#if HDR
@ -36,11 +38,11 @@ EX namespace nisot {
EX namespace solv {
int PRECX, PRECY, PRECZ;
EX int PRECX, PRECY, PRECZ;
vector<nisot::ptlow> inverse_exp_table;
EX vector<nisot::ptlow> inverse_exp_table;
bool table_loaded;
EX bool table_loaded;
EX string solfname = "solv-geodesics.dat";
@ -281,7 +283,8 @@ EX namespace solv {
EX ld solrange_xy = 15;
EX ld solrange_z = 4;
EX ld glitch_xy = 2, glitch_z = 0.6;
EX ld glitch_xy = 2;
EX ld glitch_z = 0.6;
EX bool in_table_range(hyperpoint h) {
if(abs(h[0]) > glitch_xy && abs(h[1]) > glitch_xy && abs(h[2]) < glitch_z) return false;
@ -598,9 +601,9 @@ EX namespace hybrid {
ginf[g].flags |= qHYBRID;
}
hrmap *pmap;
EX hrmap *pmap;
geometry_information *pcgip;
eGeometry actual_geometry;
EX eGeometry actual_geometry;
template<class T> auto in_actual(const T& t) -> decltype(t()) {
dynamicval<eGeometry> g(geometry, actual_geometry);
@ -658,7 +661,7 @@ EX namespace hybrid {
EX pair<cell*, int> get_where(cell *c) { return hmap()->where[c]; }
void find_cell_connection(cell *c, int d) {
EX void find_cell_connection(cell *c, int d) {
auto m = hmap();
if(d >= c->type - 2) {
int s = cgi.single_step;

View File

@ -32,6 +32,7 @@ enum eOrbLandRelation {
};
#endif
#if HDR
namespace orbgenflags {
// generates in the given land from 10 treasures, in the classic mode
static const int LOCAL10 = 1;
@ -74,8 +75,9 @@ struct orbinfo {
eItem orb;
bool is_native() const { using namespace orbgenflags; return flags & NATIVE; }
};
#endif
const vector<orbinfo> orbinfos = {
EX vector<orbinfo> orbinfos = {
{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},
@ -178,7 +180,7 @@ const orbinfo& getNativityOrbInfo(eItem orb) {
return oi;
}
string olrDescriptions[] = {
EX string olrDescriptions[] = {
"forbidden to find in %the1",
"too dangerous to use in %the1",
"useless in %the1",

View File

@ -142,7 +142,7 @@ int fiftyval(cell *c) {
}
}
int cdist50(cell *c) {
EX int cdist50(cell *c) {
if(sphere || S7>7 || S6>6) return 0;
if(euclid) {
if(c->land == laWildWest)
@ -455,7 +455,7 @@ pair<int, int> subval(cell *c, int _subpathid = subpathid, int _subpathorder = s
EX }
#endif
int getHemisphere(heptagon *h, int which) {
EX int getHemisphere(heptagon *h, int which) {
int id = h->fiftyval;
if(S7 == 5) {
int hemitable[3][12] = {
@ -484,7 +484,7 @@ int getHemisphere(heptagon *h, int which) {
else return 0;
}
int getHemisphere(cell *c, int which) {
EX int getHemisphere(cell *c, int which) {
if(euwrap) return 0;
if(WDIM == 3) {
hyperpoint p = tC0(calc_relative_matrix(c, currentmap->gamestart(), C0));
@ -1403,7 +1403,7 @@ EX bool pseudohept(cell *c) {
// while Krakens movement is usually restricted to non-pseudohept cells,
// there is one special case when this does not work (because non-pseudohept cells have varying degrees)
bool kraken_pseudohept(cell *c) {
EX bool kraken_pseudohept(cell *c) {
if(0);
#if CAP_GP
else if(!euclid && S3 == 4 && GOLDBERG && (gp::param.first % 2 || gp::param.second % 2 || S7 % 2))
@ -1427,7 +1427,7 @@ bool kraken_pseudohept(cell *c) {
return pseudohept(c);
}
bool warptype(cell *c) {
EX bool warptype(cell *c) {
if(geosupport_chessboard())
return chessvalue(c);
else if(NONSTDVAR)
@ -1436,7 +1436,7 @@ bool warptype(cell *c) {
return pattern_threecolor(c) == 0;
}
map<char, colortable> colortables = {
EX map<char, colortable> colortables = {
{'A', {
0xF04040, 0x40F040, 0x4040F0,
0xD0D000, 0xD000D0, 0x00D0D0,
@ -1492,7 +1492,7 @@ EX namespace patterns {
return gmod(p.first - p.second * 2, 7);
}
string color_formula = "to01(rgb(x,y,z))";
EX string color_formula = "to01(rgb(x,y,z))";
cld compute_map_function(cell *c, int p, const string& formula) {
exp_parser ep;
@ -1782,7 +1782,7 @@ EX namespace patterns {
}
void showPrePattern() { showPrePatternP(true); }
void showPrePatternNoninstant() { showPrePatternP(false); }
EX void showPrePatternNoninstant() { showPrePatternP(false); }
#if CAP_TEXTURE

View File

@ -11,7 +11,7 @@ namespace hr {
// === EMERALD PATTERN ===
// rules for the emeraldvalues of heptagons.
int emerald_heptagon(int parent, int dir) {
EX int emerald_heptagon(int parent, int dir) {
if(a46) return parent ^ (dir & 1) ^ 2 ^ (((parent^dir) & 1) << 2);
@ -374,7 +374,7 @@ int emerald_heptagon(int parent, int dir) {
// calculate the emeraldvalue of a hexagonal cell,
// based on the emeraldvalues of the neighbor heptacells.
int emerald_hexagon(int a, int b, int c) {
EX int emerald_hexagon(int a, int b, int c) {
// pick the lexicographically smallest representation of the cycle
if(b <= a || c<a) { int t=a; a=b; b=c; c=t; }
if(b <= a || c<a) { int t=a; a=b; b=c; c=t; }
@ -1017,12 +1017,12 @@ RULE50(0x1df, 0x0c6, 0x1ae, 0x0ff, 0x0df, 0x1b7, 0x0f7, 0x1a6)
#undef RULE50
int firstfiftyval(int d) {
EX int firstfiftyval(int d) {
if(S7 == 8 && d > 3) d--;
return fiftytable[0][d];
}
int nextfiftyval(int par, int gpar, int d) {
EX int nextfiftyval(int par, int gpar, int d) {
if(S7 == 8 && d > 3) d--;
for(int i=0; i<7; i++) if(fiftytable[par][i] == gpar)
return fiftytable[par][(i+d)%7];
@ -1059,7 +1059,7 @@ int zebratable[12][7] = {
{74, 112, 95, 132, 143, 123, 135}
};
int zebratable6[28][3] = {
EX int zebratable6[28][3] = {
{4,10,6}, {5,11,7}, {4,6,12}, {5,7,13},
{8,14,10}, {9,15,11}, {4,8,10}, {5,9,11},
{6,14,12}, {7,15,13}, {8,12,14}, {9,13,15},
@ -1070,7 +1070,7 @@ int zebratable6[28][3] = {
};
// rules for the emeraldvalues of heptagons.
int zebra_heptagon(int parent, int dir) {
EX int zebra_heptagon(int parent, int dir) {
if(S3 == 4) {
int mm = (parent % 10 + S7 - dir) % S7;
int mv = parent / 10;
@ -1122,7 +1122,7 @@ int zebra_heptagon(int parent, int dir) {
return zebratable[parent/10-4][(70+dir-(parent%10))%7];
}
int fifty_38(int f, int d) {
EX int fifty_38(int f, int d) {
// This creates the 'p' pattern for the a38 geometry.
// Hexagons have codes 4 and 8, while octagons have 0, 1, 2.
// Heptagons also have a 'dock flag' which is flipped

View File

@ -10,10 +10,12 @@
namespace hr {
#if HDR
static constexpr ld NEWSHAPE = (-13.5);
#endif
static constexpr ld WOLF = (-15.5);
extern long double polydata[];
EX long double polydata[];
void geometry_information::hpcpush(hyperpoint h) {
if(sphere) h = mid(h,h);
@ -292,7 +294,9 @@ template<class... T> ld grot(bool geometry, ld factor, T... t) {
else return grot(t...);
}
#if HDR
#define SHADMUL (S3==4 ? 1.05 : 1.3)
#endif
void geometry_information::make_sidewalls() {
for(int i=0; i<=3; i++)

View File

@ -14,8 +14,8 @@ static const int PSEUDOKEY_MEMORY = 16397;
EX bool memory_saving_mode = true;
bool show_memory_warning = true;
bool ignored_memory_warning;
EX bool show_memory_warning = true;
EX bool ignored_memory_warning;
static const int LIM = 150;
@ -93,7 +93,7 @@ bool unsafeLand(cell *c) {
among(c->land, laCaribbean, laOcean, laGraveyard, laPrincessQuest);
}
void save_memory() {
EX void save_memory() {
if(quotient || !hyperbolic || NONSTDVAR) return;
if(!memory_saving_mode) return;
if(unsafeLand(cwt.at)) return;
@ -184,14 +184,14 @@ EX void set_if_removed(cell*& c, cell *val) {
typedef array<char, 1048576> reserve_block;
int reserve_count = 0;
int reserve_limit = 128;
EX int reserve_limit = 128;
const int max_reserve = 4096;
array<reserve_block*, max_reserve> reserve;
std::new_handler default_handler;
purehookset hooks_clear_cache;
EX purehookset hooks_clear_cache;
void reserve_handler() {
if(reserve_count) {
@ -202,7 +202,7 @@ void reserve_handler() {
if(!reserve_count) std::set_new_handler(default_handler);
}
void apply_memory_reserve() {
EX void apply_memory_reserve() {
#if CAP_MEMORY_RESERVE
if(reserve_count > 0) std::set_new_handler(default_handler);
if(reserve_limit > max_reserve) reserve_limit = max_reserve;
@ -230,7 +230,7 @@ void memory_for_lib() {
if(reserve_count) { reserve_count--; delete reserve[reserve_count]; }
}
void show_memory_menu() {
EX void show_memory_menu() {
gamescreen(0);
dialog::init(XLAT("memory"));

View File

@ -247,7 +247,7 @@ EX bool make_svg = false;
EX bool transparent = true;
EX ld gamma = 1;
EX int shotformat = -1;
string caption;
EX string caption;
EX ld fade = 1;
void set_shotx() {
@ -520,7 +520,8 @@ transmatrix rotation_center_View;
color_t circle_display_color = 0x00FF00FF;
EX ld circle_radius = acosh(2.), circle_spins = 1;
EX ld circle_radius = acosh(2.);
EX ld circle_spins = 1;
void moved() {
optimizeview();

View File

@ -17,7 +17,7 @@ namespace hr {
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
void glError(const char* GLcall, const char* file, const int line) {
EX void glError(const char* GLcall, const char* file, const int line) {
GLenum errCode = glGetError();
if(errCode!=GL_NO_ERROR) {
fprintf(stderr, "OPENGL ERROR #%i: in file %s on line %i :: %s\n",errCode,file, line, GLcall);
@ -107,9 +107,9 @@ enum class shader_projection { standard, band, halfplane, standardH3, standardR3
#endif
#if CAP_SHADER
bool noshaders = false;
EX bool noshaders = false;
#else
bool noshaders = true;
EX bool noshaders = true;
#endif
bool glew = false;
@ -117,14 +117,18 @@ bool glew = false;
bool current_depthtest, current_depthwrite;
ld fogbase;
#if HDR
typedef const void *constvoidptr;
#endif
constvoidptr current_vertices, buffered_vertices;
EX constvoidptr current_vertices, buffered_vertices;
ld current_linewidth;
GLuint buf_current, buf_buffered;
#if HDR
enum eMode { gmColored, gmTextured, gmVarColored, gmLightFog, gmMAX};
#endif
static const flagtype GF_TEXTURE = 1;
static const flagtype GF_VARCOLOR = 2;
@ -137,7 +141,7 @@ eMode mode;
EX shader_projection current_shader_projection, new_shader_projection;
void switch_mode(eMode m, shader_projection sp);
EX void switch_mode(eMode m, shader_projection sp);
void display(const glmatrix& m) {
for(int i=0; i<4; i++) {
@ -159,9 +163,9 @@ glmatrix operator * (glmatrix m1, glmatrix m2) {
return res;
}
glmatrix id = {{{1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {0,0,0,1}}};
EX glmatrix id = {{{1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {0,0,0,1}}};
glmatrix scale(ld x, ld y, ld z) {
EX glmatrix scale(ld x, ld y, ld z) {
glmatrix tmp;
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
@ -180,7 +184,7 @@ EX glmatrix tmtogl(const transmatrix& T) {
return tmp;
}
glmatrix tmtogl_transpose(const transmatrix& T) {
EX glmatrix tmtogl_transpose(const transmatrix& T) {
glmatrix tmp;
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
@ -188,16 +192,16 @@ glmatrix tmtogl_transpose(const transmatrix& T) {
return tmp;
}
glmatrix ortho(ld x, ld y, ld z) {
EX glmatrix ortho(ld x, ld y, ld z) {
return scale(1/x, 1/y, 1/z);
}
glmatrix& as_glmatrix(GLfloat o[16]) {
EX glmatrix& as_glmatrix(GLfloat o[16]) {
glmatrix& tmp = (glmatrix&) (o[0]);
return tmp;
}
glmatrix frustum(ld x, ld y, ld vnear = 1e-3, ld vfar = 1e9) {
EX glmatrix frustum(ld x, ld y, ld vnear IS(1e-3), ld vfar IS(1e9)) {
GLfloat frustum[16] = {
GLfloat(1 / x), 0, 0, 0,
0, GLfloat(1 / y), 0, 0,
@ -223,7 +227,7 @@ EX glmatrix translate(ld x, ld y, ld z) {
glmatrix projection;
void new_projection() {
EX void new_projection() {
WITHSHADER({
projection = id;
}, {
@ -235,7 +239,7 @@ void new_projection() {
})
}
void projection_multiply(const glmatrix& m) {
EX void projection_multiply(const glmatrix& m) {
WITHSHADER({
projection = m * projection;
}, {
@ -244,7 +248,7 @@ void projection_multiply(const glmatrix& m) {
})
}
void init();
EX void init();
int compileShader(int type, const string& s) {
GLint status;
@ -279,13 +283,21 @@ int compileShader(int type, const string& s) {
// https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php
struct GLprogram *current = NULL;
#if HDR
struct GLprogram;
#endif
EX struct GLprogram *current = NULL;
#if HDR
static const int aPosition = 0;
static const int aColor = 3;
static const int aTexture = 8;
#endif
const int INVERSE_EXP_BINDING = 2;
#if HDR
constexpr int INVERSE_EXP_BINDING = 2;
#endif
struct GLprogram {
GLuint _program;
@ -455,7 +467,7 @@ EX void set_modelview(const glmatrix& modelview) {
// glUniformMatrix3fv(current->uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, nm[0]);
}
void id_modelview() {
EX void id_modelview() {
#if CAP_NOSHADER
if(noshaders) {
glMatrixMode(GL_MODELVIEW);
@ -604,7 +616,7 @@ void switch_mode(eMode m, shader_projection sp) {
else glDisable(GL_DEPTH_TEST); */
}
void fog_max(ld fogmax, color_t fogcolor) {
EX void fog_max(ld fogmax, color_t fogcolor) {
WITHSHADER({
glUniform1f(current->uFog, 1 / fogmax);
@ -616,7 +628,7 @@ void fog_max(ld fogmax, color_t fogcolor) {
})
}
void set_fogbase(ld _fogbase) {
EX void set_fogbase(ld _fogbase) {
WITHSHADER({
if(fogbase != _fogbase) {
fogbase = _fogbase;
@ -625,7 +637,7 @@ void set_fogbase(ld _fogbase) {
}, {})
}
void set_ualpha(ld alpha) {
EX void set_ualpha(ld alpha) {
WITHSHADER({
glUniform1f(current->uAlpha, alpha);
}, {})
@ -861,7 +873,7 @@ template<class T> void bindbuffer(T& v) {
#endif
void vertices(const vector<glvertex>& v, int vshift = 0) {
EX void vertices(const vector<glvertex>& v, int vshift IS(0)) {
#if CAP_VERTEXBUFFER
if(&v[0] == buffered_vertices) {
if(&v[0] == current_vertices) return;
@ -882,7 +894,7 @@ void vertices(const vector<glvertex>& v, int vshift = 0) {
#endif
}
void vertices_texture(const vector<glvertex>& v, const vector<glvertex>& t, int vshift = 0, int tshift = 0) {
EX void vertices_texture(const vector<glvertex>& v, const vector<glvertex>& t, int vshift IS(0), int tshift IS(0)) {
#if CAP_VERTEXBUFFER
int q = min(isize(v)-vshift, isize(t)-tshift);
vector<textured_vertex> tv(q);
@ -958,7 +970,7 @@ EX void prepare(vector<ct_vertex>& v) {
#endif
}
void store_in_buffer(vector<glvertex>& v) {
EX void store_in_buffer(vector<glvertex>& v) {
#if CAP_VERTEXBUFFER
if(!buf_buffered) {
printf("no buffer yet\n");
@ -1004,7 +1016,24 @@ EX void switch_to_text(const vector<glvertex>& v, const vector<glvertex>& t) {
vertices_texture(v, t, 0, 0);
}
}
EX }
EX vector<glhr::textured_vertex> text_vertices;
EX void texture_vertices(GLfloat *f, int qty, int stride IS(2)) {
WITHSHADER(
glVertexAttribPointer(aTexture, stride, GL_FLOAT, GL_FALSE, stride * sizeof(GLfloat), f);,
glTexCoordPointer(stride, GL_FLOAT, 0, f);
)
}
EX void oldvertices(GLfloat *f, int qty) {
WITHSHADER(
glVertexAttribPointer(aPosition, SHDIM, GL_FLOAT, GL_FALSE, SHDIM * sizeof(GLfloat), f);,
glVertexPointer(SHDIM, GL_FLOAT, 0, f);
)
}
}
#define glMatrixMode DISABLED

View File

@ -48,7 +48,7 @@ EX int asteroids_generated, asteroid_orbs_generated;
EX time_t timerstart, savetime;
EX bool timerstopped;
int savecount;
EX int savecount;
EX bool showoff = false;
EX bool doCross = false;

View File

@ -12,7 +12,7 @@ namespace hr {
EX int usershape_changes;
array<map<int, usershape*>, mapeditor::USERSHAPEGROUPS> usershapes;
EX array<map<int, usershape*>, mapeditor::USERSHAPEGROUPS> usershapes;
EX void initShape(int sg, int id) {
if(!usershapes[sg][id]) {
@ -32,7 +32,7 @@ EX void initShape(int sg, int id) {
}
}
basic_textureinfo user_triangles_texture;
EX basic_textureinfo user_triangles_texture;
void geometry_information::pushShape(usershapelayer& ds) {

View File

@ -74,8 +74,8 @@ void profile_frame() {
for(int t=0; t<16; t++) proftable[t][pframeid] = 0;
}
void profile_start(int t) { proftable[t][pframeid] -= getms(); }
void profile_stop(int t) { proftable[t][pframeid] += getms(); }
EX void profile_start(int t) { proftable[t][pframeid] -= getms(); }
EX void profile_stop(int t) { proftable[t][pframeid] += getms(); }
void profile_info() {
for(int t=0; t<16; t++) {
@ -88,16 +88,18 @@ void profile_info() {
proftable[t][48], proftable[t][63]);
}
}
#endif
#else
#if !CAP_PROFILING
#if HDR
#define profile_frame()
#define profile_start(t)
#define profile_stop(t)
#define profile_info()
#endif
#endif
purehookset hooks_tests;
EX purehookset hooks_tests;
EX string simplify(const string& s) {
string res;

View File

@ -10,13 +10,13 @@ namespace hr {
namespace peace { extern bool on; }
int hiitemsMax(eItem it) {
EX int hiitemsMax(eItem it) {
int mx = 0;
for(auto& a: hiitems) if(a.second[it] > mx) mx = a.second[it];
return mx;
}
modecode_t modecode();
EX modecode_t modecode();
typedef vector<pair<int, string> > subscoreboard;
@ -40,13 +40,13 @@ EX namespace yendor {
EX bool on = false;
EX bool generating = false;
bool path = false;
bool everwon = false;
bool won = false;
EX bool path = false;
EX bool everwon = false;
EX bool won = false;
bool easy = false;
int challenge; // id of the challenge
int lastchallenge;
EX int challenge; // id of the challenge
EX int lastchallenge;
#if HDR
#define YF_DEAD 1
@ -73,11 +73,11 @@ EX namespace yendor {
eLand l;
int flags;
};
#define YENDORLEVELS 33
#endif
#define YENDORLEVELS 33
map<modecode_t, array<int, YENDORLEVELS>> bestscore;
EX map<modecode_t, array<int, YENDORLEVELS>> bestscore;
EX eLand nexttostart;
@ -138,7 +138,7 @@ EX namespace yendor {
achievement_score(LB_YENDOR_CHALLENGE, tscore);
}
yendorlevel& clev() { return levels[challenge]; }
EX yendorlevel& clev() { return levels[challenge]; }
eLand changeland(int i, eLand l) {
if(l == laIvoryTower) return laNone;
@ -150,6 +150,7 @@ EX namespace yendor {
string name;
eLand first, second, last;
#if HDR
struct yendorinfo {
cell *path[YDIST];
cell *actualKey;
@ -162,13 +163,14 @@ EX namespace yendor {
cell *actual_key() { return actualKey ? actualKey : key(); }
cell* orb() { return path[0]; }
};
#endif
vector<yendorinfo> yi;
EX vector<yendorinfo> yi;
#define NOYENDOR 999999
int yii = NOYENDOR;
int hardness() {
EX int hardness() {
if(peace::on) return 15; // just to generate monsters
if(!yendor::generating && !yendor::path && !yendor::on) return 0;
int thf = 0;
@ -182,15 +184,17 @@ EX namespace yendor {
return items[itOrbYendor] * 5 + (thf * 5) / (YDIST-25);
}
#if HDR
enum eState { ysUntouched, ysLocked, ysUnlocked };
#endif
eState state(cell *yendor) {
EX eState state(cell *yendor) {
for(int i=0; i<isize(yi); i++) if(yi[i].path[0] == yendor)
return yi[i].found ? ysUnlocked : ysLocked;
return ysUntouched;
}
bool check(cell *yendor) {
EX bool check(cell *yendor) {
int byi = isize(yi);
for(int i=0; i<isize(yi); i++) if(yi[i].path[0] == yendor) byi = i;
if(byi < isize(yi) && yi[byi].found) return false;
@ -490,7 +494,7 @@ EX namespace yendor {
return false;
}
void onpath() {
EX void onpath() {
path = false;
if(yii < isize(yi)) {
for(int i=0; i<YDIST; i++) if(yi[yii].path[i]->cpdist <= 7) {
@ -500,7 +504,7 @@ EX namespace yendor {
}
}
void init(int phase) {
EX void init(int phase) {
if(!on) return;
if(phase == 1) {
@ -726,7 +730,7 @@ EX namespace yendor {
};
}
void collected(cell* c2) {
EX void collected(cell* c2) {
int pg = gold();
playSound(c2, "tada");
items[itOrbShield] += 31;
@ -785,7 +789,7 @@ EX namespace tactic {
EX bool trailer = false;
EX bool on = false;
int id;
EX int id;
map<modecode_t, array<int, landtypes>> recordsum;
map<modecode_t, array<array<int, MAXTAC>, landtypes> > lsc;
@ -821,7 +825,7 @@ EX namespace tactic {
return hiitemsMax(treasureType(l)) * landMultiplier(l) >= 20;
}
void record(eLand land, int score, int xc = modecode()) {
EX void record(eLand land, int score, int xc IS(modecode())) {
if(land >=0 && land < landtypes) {
for(int i=MAXTAC-1; i; i--) lsc[xc][land][i] = lsc[xc][land][i-1];
tactic::lsc[xc][land][0] = score;
@ -1166,9 +1170,9 @@ modecode_t modecode() {
EX namespace peace {
EX bool on = false;
bool hint = false;
EX bool hint = false;
bool otherpuzzles;
EX bool otherpuzzles;
eLand simonlevels[] = {
laCrossroads, laCrossroads2, laDesert, laCaves, laAlchemist, laRlyeh, laEmerald,
@ -1228,7 +1232,7 @@ EX namespace peace {
"a large hyperbolic circle), and Palace (follow the mouse). "
"Other places listed are for exploration.";
namespace simon {
EX namespace simon {
vector<cell*> path;
int tobuild;
@ -1273,7 +1277,7 @@ EX namespace peace {
}
}
void extend() {
EX void extend() {
int i = 0;
while(i<isize(path) && path[i]->item != itDodeca) i++;
if(tobuild == i+9)
@ -1282,7 +1286,7 @@ EX namespace peace {
build();
}
void init() {
EX void init() {
tobuild = 0;
if(!on) return;
if(otherpuzzles) { items[itGreenStone] = 500; return; }
@ -1296,12 +1300,12 @@ EX namespace peace {
extend();
}
void restore() {
EX void restore() {
for(int i=1; i<isize(path); i++)
if(path[i]->item == itNone && items[itDodeca])
path[i]->item = itDodeca, items[itDodeca]--;
}
}
EX }
void showMenu() {
listLevels();