Commit a210a243 authored by Markus Koschany's avatar Markus Koschany

New upstream version 10.4j

parent 82625bf4
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Hyperbolic Rogue -- special graphical effects, such as the Blizzard
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
namespace hr {
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
double cellgfxdist(cell *c, int i) {
if(gp::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i)));
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
}
transmatrix cellrelmatrix(cell *c, int i) {
if(gp::on) return shmup::calc_relative_matrix(c->mov[i], c, i);
double d = cellgfxdist(c, i);
return ddspin(c, i) * xpush(d) * iddspin(c->mov[i], c->spin(i), euclid ? 0 : S42);
}
hyperpoint randomPointIn(int t) {
while(true) {
hyperpoint h = spin(2*M_PI*(randd()-.5)/t) * tC0(xpush(asinh(randd())));
double d =
nonbitrunc ? tessf : t == 6 ? hexhexdist : crossf;
if(hdist0(h) < hdist0(xpush(-d) * h))
return spin(2*M_PI/t * (rand() % t)) * h;
}
}
struct snowball {
transmatrix T;
transmatrix global;
snowball *prev;
snowball *next;
double phase;
snowball(int t) { T = rgpushxto0(randomPointIn(t)); phase = randd(); }
};
struct blizzardcell {
cell *c;
int frame;
int tmp;
transmatrix *gm;
char wmap;
int inward, outward, ward;
int qty[MAX_EDGE];
vector<snowball*> inorder, outorder;
int inid, outid;
~blizzardcell() { for(auto i: inorder) delete i; }
};
map<cell*, blizzardcell> blizzardcells;
void set_blizzard_frame(cell *c, int frameid) {
blizzardcells[c].frame = frameid;
}
vector<blizzardcell*> bcells;
int blizzard_N;
blizzardcell* getbcell(cell *c) {
int i = c->listindex;
if(i<0 || i >= blizzard_N) return NULL;
if(bcells[i]->c != c) return NULL;
return bcells[i];
}
void drawBlizzards() {
poly_outline = OUTLINE_NONE;
auto it = blizzardcells.begin();
bcells.clear();
while(it != blizzardcells.end())
if(it->second.frame != frameid || !gmatrix.count(it->first))
it = blizzardcells.erase(it);
else {
it->second.c = it->first;
bcells.push_back(&it->second);
it++;
}
blizzard_N = isize(bcells);
for(int i=0; i<blizzard_N; i++) {
auto& bc = *bcells[i];
bc.tmp = bc.c->listindex,
bc.c->listindex = i;
bc.gm = &gmatrix[bc.c];
bc.wmap = windmap::at(bc.c);
}
for(int i=0; i<blizzard_N; i++) {
auto& bc = *bcells[i];
cell *c = bc.c;
bc.inward = bc.outward = 0;
for(int i=0; i<c->type; i++) {
int& qty = bc.qty[i];
qty = 0;
cell *c2 = c->mov[i];
if(!c2) continue;
auto bc2 = getbcell(c2);
if(!bc2) continue;
int z = (bc2->wmap - bc.wmap) & 255;
if(z >= windmap::NOWINDBELOW && z < windmap::NOWINDFROM)
bc.outward += qty = z / 8;
z = (-z) & 255;
if(z >= windmap::NOWINDBELOW && z < windmap::NOWINDFROM)
bc.inward += z / 8, qty = -z/8;
}
bc.ward = max(bc.inward, bc.outward);
while(isize(bc.inorder) < bc.ward) {
auto sb = new snowball(c->type);
bc.inorder.push_back(sb);
bc.outorder.push_back(sb);
}
for(auto& sb: bc.inorder) sb->prev = sb->next = NULL;
bc.inid = 0;
}
double at = (ticks % 250) / 250.0;
for(int i=0; i<blizzard_N; i++) {
auto& bc = *bcells[i];
for(auto sb: bc.inorder)
sb->global = (*bc.gm) * sb->T;
}
for(int i=0; i<blizzard_N; i++) {
auto& bc = *bcells[i];
cell *c = bc.c;
bc.outid = 0;
for(int d=0; d<c->type; d++) for(int k=0; k<bc.qty[d]; k++) {
auto& bc2 = *getbcell(c->mov[d]);
auto& sball = *bc.outorder[bc.outid++];
auto& sball2 = *bc2.inorder[bc2.inid++];
sball.next = &sball2;
sball2.prev = &sball;
hyperpoint t = inverse(sball.global) * tC0(sball2.global);
double at0 = at + sball.phase;
if(at0>1) at0 -= 1;
transmatrix tpartial = sball.global * rspintox(t) * xpush(hdist0(t) * at0);
if(wmascii || wmblack)
queuechr(tpartial, .2, '.', 0xFFFFFF);
else
queuepoly(tpartial, shSnowball, 0xFFFFFF80);
}
}
for(int ii=0; ii<blizzard_N; ii++) {
auto& bc = *bcells[ii];
/* if(isNeighbor(bc.c, mouseover)) {
if(againstWind(mouseover, bc.c))
queuepoly(*bc.gm, shHeptaMarker, 0x00C00040);
if(againstWind(bc.c, mouseover))
queuepoly(*bc.gm, shHeptaMarker, 0xC0000040);
} */
forCellIdEx(c2, i, bc.c) if(bc.c == mouseover || c2 == mouseover) {
int col = 0x00C00080;
if(c2 == mouseover)
col ^= 0xC0C00000;
if(isPlayerOn(c2))
col ^= 0x00000040;
if(isPlayerOn(bc.c))
col ^= 0x00000040;
if(againstWind(bc.c, c2))
queuepoly(*bc.gm * ddspin(bc.c, i) * xpush(cellgfxdist(bc.c, i)/2), shWindArrow, col);
}
int B = isize(bc.outorder);
if(B<2) continue;
int i = rand() % B;
int j = rand() % (B-1);
if(i==j) j++;
if(1) {
auto& sb1 = *bc.outorder[i];
auto& sb2 = *bc.outorder[j];
double swapcost = 0;
if(sb1.next) swapcost -= hdist(tC0(sb1.global), tC0(sb1.next->global));
if(sb2.next) swapcost -= hdist(tC0(sb2.global), tC0(sb2.next->global));
if(sb1.next) swapcost += hdist(tC0(sb2.global), tC0(sb1.next->global));
if(sb2.next) swapcost += hdist(tC0(sb1.global), tC0(sb2.next->global));
if(swapcost < 0) {
swap(bc.outorder[i], bc.outorder[j]);
swap(sb1.next, sb2.next);
if(sb1.next) sb1.next->prev = &sb1;
if(sb2.next) sb2.next->prev = &sb2;
}
}
if(1) {
auto& sb1 = *bc.inorder[i];
auto& sb2 = *bc.inorder[j];
double swapcost = 0;
if(sb1.prev) swapcost -= hdist(tC0(sb1.global), tC0(sb1.prev->global));
if(sb2.prev) swapcost -= hdist(tC0(sb2.global), tC0(sb2.prev->global));
if(sb1.prev) swapcost += hdist(tC0(sb2.global), tC0(sb1.prev->global));
if(sb2.prev) swapcost += hdist(tC0(sb1.global), tC0(sb2.prev->global));
if(swapcost < 0) {
swap(bc.inorder[i], bc.inorder[j]);
swap(sb1.prev, sb2.prev);
if(sb1.prev) sb1.prev->next = &sb1;
if(sb2.prev) sb2.prev->next = &sb2;
}
}
auto& sbp = *bc.inorder[i];
if(sbp.next && sbp.prev) {
double p1 = sbp.next->phase;
double p2 = sbp.prev->phase;
double d = p2-p1;
if(d<=.5) d+=1;
if(d>=.5) d-=1;
sbp.phase = p1 + d/2;
if(sbp.phase >= 1) sbp.phase -= 1;
if(sbp.phase < 0) sbp.phase += 1;
}
}
for(auto bc: bcells)
bc->c->listindex = bc->tmp;
}
vector<cell*> arrowtraps;
void drawArrowTraps() {
for(cell *c: arrowtraps) {
auto r = traplimits(c);
try {
transmatrix& t0 = gmatrix.at(r[0]);
transmatrix& t1 = gmatrix.at(r[4]);
queueline(tC0(t0), tC0(t1), 0xFF0000FF, 4, PPR_ITEM);
if((c->wparam & 7) == 3 && !shmup::on) {
// queueline(t0 * randomPointIn(r[0]->type), t1 * randomPointIn(r[1]->type), 0xFFFFFFFF, 4, PPR_ITEM);
int tt = ticks % 401;
if(tt < 0) tt += 401;
for(int u=0; u<2; u++) {
transmatrix& tu = u ? t0 : t1;
transmatrix& tv = u ? t1 : t0;
hyperpoint trel = inverse(tu) * tC0(tv);
transmatrix tpartial = tu * rspintox(trel) * xpush(hdist0(trel) * tt / 401.0);
queuepoly(tpartial * ypush(.05), shTrapArrow, 0xFFFFFFFF);
}
}
}
catch(out_of_range&) {}
}
}
auto ccm_blizzard = addHook(clearmemory, 0, [] () {
arrowtraps.clear();
blizzardcells.clear();
bcells.clear();
}) +
addHook(hooks_removecells, 0, [] () {
eliminate_if(arrowtraps, is_cell_removed);
});
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
namespace hr {
static const int motypes = 162;
struct monstertype {
char glyph;
int color;
const char *name;
const char *help;
};
enum eMonster {
moNone,
moYeti, moWolf, moWolfMoved,
moRanger,
moTroll, moGoblin,
moWorm, moWormtail, moWormwait, moHedge,
moDesertman,
moIvyRoot, moIvyHead, moIvyBranch, moIvyWait, moIvyNext, moIvyDead,
moMonkey,
moSlime,
moMimic, moREMOVED, moGolem, moGolemMoved,
moEagle, moSeep,
moZombie, moGhost, moNecromancer, moShadow,
moTentacle, moTentacletail, moTentaclewait, moTentacleEscaping,
moCultist, moPyroCultist,
moGreater, moGreaterM, moLesser, moLesserM,
moShark, moRunDog, moGreaterShark, moFireFairy,
moCrystalSage, moLancer, moFlailer, moMiner,
moVineBeast, moVineSpirit, moDarkTroll, moEarthElemental,
moBug0, moBug1, moBug2,
moWitch, moWitchSpeed, moWitchFlash, moWitchFire, moWitchWinter, moWitchGhost,
moEvilGolem, moKnight, moCultistLeader, moSlimeNextTurn, moKnightMoved,
moIllusion,
moPirate, moCShark, moParrot,
moHexSnake, moHexSnakeTail, moRedTroll, moBomberbird, moAlbatross,
moTameBomberbird, moTameBomberbirdMoved,
moPalace, moFatGuard, moSkeleton, moVizier,
moViking, moFjordTroll, moWaterElemental,
moMouse, moMouseMoved,
moPrincess, moPrincessMoved,
moPrincessArmed, moPrincessArmedMoved,
moFamiliar, moGargoyle, moFireElemental, moAirElemental,
moOrangeDog, moTentacleGhost,
moMetalBeast, moMetalBeast2, moOutlaw, moMutant,
moStormTroll, moForestTroll,
moRedFox, moWindCrow, moFriendlyGhost, moRatling, moFalsePrincess, moRoseLady,
moRoseBeauty, moRatlingAvenger,
moTortoise, moDragonHead, moDragonTail,
moGadfly, moResearcher, moSparrowhawk,
moKrakenH, moKrakenT, moDraugr, moFriendlyIvy,
moVampire, moBat, moReptile,
moHerdBull, moRagingBull, moSleepBull,
moButterfly, moNarciss, moMirrorSpirit,
moHunterDog, moTerraWarrior, moJiangshi, moVoidBeast, moLavaWolf, moHunterGuard,
moIceGolem, moSandBird, moSalamander, moHunterChanging,
moNorthPole, moSouthPole,
moPair, moHexDemon, moAltDemon, moMonk, moCrusher,
moSwitch1, moSwitch2,
// shmup specials
moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball, moCrushball,
// temporary
moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning, moArrowTrap,
moRogueviz
};
struct genderswitch_t {
int gender;
eMonster m;
const char *name;
const char *desc;
};
#define NUM_GS 6
static const int ittypes = 130;
struct itemtype {
char glyph;
int color;
const char *name;
const char *help;
};
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,
itOrbTeleport, itOrbSafety,
itOrbThorns, itFernFlower,
itWine, itOrbAether, itSilver, itOrbPsi,
itRoyalJelly, itEmerald, itOrbInvis, itPower, itOrbFire,
itHolyGrail, itGrimoire,
itOrbDragon, itOrbIllusion,
itPirate, itCompass,
itRedGem, itOrbTime, itOrbSpace,
itBombEgg, itCoast, itWhirlpool,
itOrbFriend, itOrbWater, itOrbAir,
itPalace, itOrbFrog,
itFjord, itOrbFish,
itOrbDiscord,
itSavedPrincess, itOrbLove,
itIvory, itZebra,
itFireShard, itAirShard, itEarthShard, itWaterShard,
itElemental, itOrbSummon, itOrbMatter,
itBounty, itRevolver, itFulgurite, itMutant,
itOrbStunning, itOrbLuck,
itMutant2, itOrbFreedom, itLotus, itOrbUndeath,
itWindstone, itOrbEmpathy, itStrongWind, itBuggy, itBuggy2,
itRose, itCoral, itOrbBeauty, itOrb37, itOrbEnergy,
itBabyTortoise, itOrbShell, itApple, itDragon, itOrbDomination,
itOrbSword, itKraken, itOrbSword2, itBarrow,
itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat,
itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns,
itOrbBull, itBull, itOrbMirror,
itInventory,
itLavaLily, itHunting, itBlizzard, itTerra,
itOrbSide1, itOrbSide2, itOrbSide3,
itOrbLava, itOrbMorph, itGlowCrystal, itSnake,
itDock, itRuins, itMagnet, itSwitch,
itOrbPhasing, itOrbMagnetism, itOrbSlaying
};
static const int walltypes = 109;
struct walltype {
char glyph;
int color;
const char *name;
const char *help;
};
enum eWall { waNone, waIcewall, waBarrier, waFloorA, waFloorB, waCavewall, waCavefloor, waDeadTroll, waDune,
waMirror, waCloud, waThumperOff, waFire, waAncientGrave, waFreshGrave, waColumn, waSulphurC, waSulphur,
waLake, waFrozenLake, waChasm, waChasmD, waBigTree, waSmallTree,
waVinePlant, waVineHalfA, waVineHalfB, waPartialFire,
waDeadwall, waDeadfloor, waDeadfloor2, waWaxWall, waGlass, waCamelot, waRoundTable,
waCamelotMoat,
waBigStatue,
waSea, waBoat, waCIsland, waCIsland2, waCTree,
waRed1, waRed2, waRed3,
waMineUnknown, waMineMine, waMineOpen,
waStrandedBoat,
waPalace, waClosedGate, waOpenGate, waClosePlate, waOpenPlate, waTrapdoor,
waGiantRug,
waPlatform, waGargoyle, waGargoyleFloor, waRubble, waLadder, waStone,
waBonfireOff, waThumperOn, waEternalFire,
waGargoyleBridge,
waTempWall, waTempFloor, waTempBridge,
waCharged, waGrounded, waSandstone, waSaloon, waMetal,
waDeadTroll2, waFan,
waTemporary, waEarthD, waElementalTmp, waElementalD,
waSlime1, waSlime2, waRose, waWarpGate,
waTrunk, waSolidBranch, waWeakBranch, waCanopy,
waBarrowWall, waBarrowDig,
waPetrified, waTower,
waBigBush, waSmallBush,
waReptile, waReptileBridge,
waInvisibleFloor,
waMirrorWall,
waPetrifiedBridge,
waTempBridgeBlocked,
waTerraWarrior, waBubble,
waArrowTrap, waMercury, waMagma,
waDock, waBurningDock, waRuinWall, waBrownian
};
static const int landtypes = 85;
struct landtype {
int color;
const char *name;
const char *help;
};
enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle, laAlchemist, laMirror, laGraveyard,
laRlyeh, laHell, laCocytus, laMotion, laDryForest, laEmerald, laWineyard, laDeadCaves,
laHive, laPower, laCamelot, laTemple,
laCrossroads2, laCaribbean, laRedRock, laMinefield, laOcean, laWhirlpool,
laPalace, laLivefjord,
laIvoryTower, laZebra, laEFire, laEAir, laEEarth, laEWater, laCrossroads3,
laOceanWall, laElementalWall,
laCanvas, laPrincessQuest,
laWildWest, laStorms, laOvergrown, laClearing,
laHaunted, laHauntedWall, laHauntedBorder,
laWhirlwind, laRose, laWarpCoast, laWarpSea, laCrossroads4,
laEndorian, laTortoise, laDragon,
laKraken, laBurial, laTrollheim,
laHalloween, laDungeon, laMountain, laReptile,
laPrairie, laBull, laCrossroads5, laCA,
laMirrorWall, laMirrored, laMirrorWall2, laMirrored2,
laMirrorOld,
laVolcano, laBlizzard, laHunting, laTerracotta, laMercuryRiver,
laDual, laSnakeNest, laDocks, laRuins, laMagnetic,
laSwitch, laMemory, laBrownian
};
enum eGeometry {
gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
gKleinQuartic, gBolza, gBolza2, gMinimal,
gGUARD};
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };
struct geometryinfo {
const char* name;
const char* shortname;
int sides;
int vertex;
int quotientstyle;
eGeometryClass cclass;
int xcode;
std::array<int,2> distlimit; // bitrunc, non-bitrunc
};
static const int qSMALL = 1;
static const int qFIELD = 2;
static const int qNONORIENTABLE = 4;
static const int qTORUS = 8;
static const int qDOCKS = 16;
static const int qZEBRA = 32;
// note: dnext assumes that x&7 equals 7
static const int SEE_ALL = 15;
static const int FORBIDDEN = -1;
extern eGeometry geometry;
extern geometryinfo ginf[gGUARD];
extern monstertype minf[motypes];
extern itemtype iinf[ittypes];
extern const landtype linf[landtypes];
enum cpatterntype {
cpFootball, cpThree, cpChess, cpSingle, cpLarge, cpZebra, cpUnknown
};
struct landtacinfo { eLand l; int tries, multiplier; };
}
This diff is collapsed.
// Usage:
// * compile hyper.cpp with CU == 0
// * compile init.cpp with CU == 1
// * link them.
// Only the parts defined in #if IN_CU(1) will be included in the second compiling.
#ifndef CU
#define IN_CU(x) 1
#else
#define IN_CU(x) (CU == x)
#endif
#include "sysconfig.h"
#include "classes.h"
#include "hyper.h"
#if CAP_ROGUEVIZ
#include "rogueviz.h"
#endif
#define CU_INIT IN_CU(0)
#define CU_HYPER IN_CU(0)
#if IN_CU(0)
#include "classes.cpp"
#endif
#if IN_CU(0)
#include "shaders.cpp"
#include "util.cpp"
#include "hyperpoint.cpp"
#include "patterns.cpp"
#include "fieldpattern.cpp"
#include "heptagon.cpp"
#include "language.cpp"
#include "cell.cpp"
#include "goldberg.cpp"
#include "pattern2.cpp"
#include "flags.cpp"
#include "yendor.cpp"
#include "complex.cpp"
#include "savemem.cpp"
#include "game.cpp"
#include "orbgen.cpp"
#include "monstergen.cpp"
#include "landlock.cpp"
#include "landgen.cpp"
#include "orbs.cpp"
#if CAP_INV
#include "inventory.cpp"
#else
namespace hr { namespace inv { bool on, activating; } }
#endif
#include "system.cpp"
#include "debug.cpp"
#include "geometry.cpp"
#include "polygons.cpp"
#include "floorshapes.cpp"
#include "mapeditor.cpp"
#if CAP_MODEL
#include "netgen.cpp"
#endif
#if CAP_TABFONT || CAP_CREATEFONT
#include "nofont.cpp"
#endif
#include "basegraph.cpp"
#include "renderbuffer.cpp"
#include "help.cpp"
#include "config.cpp"
#include "scores.cpp"
#include "dialogs.cpp"
#include "menus.cpp"
#include "geom-exp.cpp"
#include "quit.cpp"
#include "shmup.cpp"
#if CAP_ROGUEVIZ
#include "rogueviz.cpp"
#endif
#include "conformal.cpp"
#include "rug.cpp"
#include "control.cpp"
#include "hud.cpp"
#include "hypgraph.cpp"
#include "textures.cpp"
#include "graph.cpp"
#include "blizzard.cpp"
#include "sound.cpp"
#include "achievement.cpp"
#include "barriers.cpp"
#include "surface.cpp"
#if CAP_TOUR
#include "tour.cpp"
#endif
#include "commandline.cpp"
#include "bigstuff.cpp"
#if CAP_DAILY
#include "private/daily.cpp"
#else
namespace hr { namespace daily { bool on; } }
#endif
#endif
#if IN_CU(1)
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Hyperbolic Rogue -- debugging routines
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
namespace hr {
int steplimit = 0;
int cstep;
vector<cell*> buggycells;
cell *pathTowards(cell *pf, cell *pt) {
while(celldist(pt) > celldist(pf)) {
if(isNeighbor(pf, pt)) return pt;
cell *pn = NULL;
forCellEx(pn2, pt) if(celldist(pn2) < celldist(pt)) pn = pn2;
pt = pn;
}
if(isNeighbor(pf, pt)) return pt;
forCellEx(pn2, pt) if(celldist(pn2) < celldist(pt)) return pn2;
return NULL;
}
bool buggyGeneration = false;
bool errorReported = false;
void describeCell(cell *c) {
if(!c) { printf("NULL\n"); return; }
printf("describe %p: ", c);
printf("%-15s", linf[c->land].name);
printf("%-15s", winf[c->wall].name);
printf("%-15s", iinf[c->item].name);
printf("%-15s", minf[c->monst].name);
printf("LP%08x", c->landparam);
printf("D%3d", c->mpdist);
printf("MON%3d", c->mondir);
printf("\n");
}
static int orbid = 0;
void debugScreen();
......@@ -36,12 +77,6 @@ eItem randomTreasure2(int cv) {
return best;
}
bool isTechnicalLand(eLand l) {
return l == laNone || l == laOceanWall || l == laBarrier || l == laCanvas ||
l == laHauntedWall || l == laHauntedBorder || l == laCA ||
l == laMirrorWall || l == laMirrored || l