mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 06:27:17 +00:00
first version of the Land of Dice
This commit is contained in:
parent
744f03c7d6
commit
feaef63f22
@ -146,7 +146,7 @@ void celldrawer::setcolors() {
|
||||
case laDesert: case laKraken: case laDocks:
|
||||
case laMotion: case laGraveyard: case laWineyard: case laLivefjord:
|
||||
case laRlyeh: case laHell: case laCrossroads: case laJungle:
|
||||
case laAlchemist: case laFrog: case laCursed:
|
||||
case laAlchemist: case laFrog: case laCursed: case laDice:
|
||||
fcol = floorcolors[c->land]; break;
|
||||
|
||||
case laCA:
|
||||
@ -1601,6 +1601,10 @@ void celldrawer::draw_features() {
|
||||
poly_outline = OUTLINE_DEFAULT;
|
||||
}
|
||||
|
||||
else if(c->wall == waDie) {
|
||||
dice::draw_die(c, V);
|
||||
}
|
||||
|
||||
else if(c->wall == waExplosiveBarrel) {
|
||||
if(GDIM == 3 && qfi.fshape) {
|
||||
draw_shapevec(c, V, qfi.fshape->cone[1], 0xD00000FF, PPR::REDWALL);
|
||||
|
180
complex2.cpp
180
complex2.cpp
@ -899,6 +899,186 @@ EX void ambush(cell *c, int dogs) {
|
||||
if(result)
|
||||
addMessage(XLAT("You are ambushed!"));
|
||||
}
|
||||
|
||||
EX }
|
||||
|
||||
EX namespace dice {
|
||||
|
||||
/* vector<vector<int>> sides = {
|
||||
{1, 3, 5}, {0, 4, 2}, {3, 1, 7}, {2, 6, 0}, {5, 7, 1}, {4, 0, 6}, {7, 5, 3}, {6, 2, 4}
|
||||
}; */
|
||||
|
||||
vector<vector<int>> sides = {
|
||||
{13-1, 7-1, 19-1}, {20-1, 12-1, 18-1}, {19-1, 17-1, 16-1}, {14-1, 18-1, 11-1}, {13-1, 18-1, 15-1},
|
||||
{14-1, 9-1, 16-1}, { 1-1, 15-1, 17-1}, {20-1, 16-1, 10-1}, {19-1, 6-1, 11-1}, { 8-1, 17-1, 12-1},
|
||||
{13-1, 9-1, 4-1}, { 2-1, 10-1, 15-1}, { 1-1, 11-1, 5-1}, {20-1, 4-1, 6-1}, { 7-1, 5-1, 12-1},
|
||||
{ 8-1, 6-1, 3-1}, { 7-1, 10-1, 3-1}, { 2-1, 5-1, 4-1}, { 1-1, 3-1, 9-1}, { 8-1, 2-1, 14-1}
|
||||
};
|
||||
|
||||
vector<vector<int>> spins;
|
||||
int order;
|
||||
|
||||
int faces() { return isize(sides); }
|
||||
|
||||
EX void generate_on(cell *c) {
|
||||
c->wparam = hrand(faces()) + faces() * (1 + hrand(3) * 2);
|
||||
}
|
||||
|
||||
bool prepared;
|
||||
|
||||
void prepare() {
|
||||
if(prepared) return;
|
||||
prepared = true;
|
||||
spins = sides;
|
||||
order = faces() == 8 ? 4 : 5;
|
||||
for(int i=0; i<faces(); i++)
|
||||
for(int j=0; j<isize(sides[i]); j++) {
|
||||
int i1 = sides[i][j];
|
||||
spins[i][j] = -1;
|
||||
for(int k=0; k<isize(sides[i1]); k++)
|
||||
if(sides[i1][k] == i)
|
||||
spins[i][j] = k;
|
||||
if(spins[i][j] == -1)
|
||||
println(hlog, "asymmetric");
|
||||
}
|
||||
}
|
||||
|
||||
EX void roll(movei mi) {
|
||||
prepare();
|
||||
auto &cto = mi.t;
|
||||
auto &th = mi.s;
|
||||
|
||||
int rdir = mi.dir_force();
|
||||
int t = th->type;
|
||||
|
||||
int val = th->wparam % faces();
|
||||
int dir = th->wparam / faces();
|
||||
|
||||
int si = isize(sides[val]);
|
||||
|
||||
if(t % si) { println(hlog, "error: bad roll\n"); return; }
|
||||
|
||||
int sideid = (rdir - dir) * si / t;
|
||||
if(sideid < 0) sideid += si;
|
||||
|
||||
int val1 = sides[val][sideid];
|
||||
|
||||
int si1 = isize(sides[val1]);
|
||||
|
||||
println(hlog, tie(val, si, rdir), " to ", tie(val1, si1));
|
||||
|
||||
int sideid1 = spins[val][sideid];
|
||||
|
||||
int t1 = cto->type;
|
||||
if(t1 % si1) { println(hlog, "error: bad roll target\n"); return; }
|
||||
|
||||
int rdir1 = mi.rev_dir_force();
|
||||
|
||||
int dir1 = rdir1 - sideid1 * t1 / si1;
|
||||
|
||||
dir1 = gmod(dir1, t1);
|
||||
|
||||
th->wall = waNone;
|
||||
cto->wall = waDie;
|
||||
cto->wparam = val1 + faces() * dir1;
|
||||
}
|
||||
|
||||
EX void draw_die(cell *c, const shiftmatrix& V) {
|
||||
prepare();
|
||||
int val = c->wparam % faces();
|
||||
int dir = c->wparam / faces();
|
||||
queuestr(V, .5, its(val+1), 0xFFFFFFFF);
|
||||
auto& side = sides[val];
|
||||
int si = isize(side);
|
||||
|
||||
for(int i=0; i<si; i++) {
|
||||
int d = dir + c->type * i / isize(side);
|
||||
d = gmod(d, c->type);
|
||||
hyperpoint nxt = tC0(currentmap->adj(c, d));
|
||||
hyperpoint mid = normalize(C0 * 1.3 + nxt * -.3);
|
||||
queuestr(V * rgpushxto0(mid), .25, its(side[i]+1), 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
shiftmatrix V1 = V * iddspin(c, dir) * spin(M_PI);
|
||||
|
||||
vector<bool> face_drawn(faces(), false);
|
||||
|
||||
vector<pair<transmatrix, int> > facequeue;
|
||||
|
||||
auto add_to_queue = [&] (const transmatrix& T, int d) {
|
||||
if(face_drawn[d]) return;
|
||||
face_drawn[d] = true;
|
||||
facequeue.emplace_back(T, d);
|
||||
};
|
||||
|
||||
add_to_queue(Id, val);
|
||||
|
||||
ld outradius, inradius;
|
||||
|
||||
if(1) {
|
||||
dynamicval<eGeometry> g(geometry, gSphere);
|
||||
ld alpha = 360 * degree / order;
|
||||
inradius = edge_of_triangle_with_angles(alpha, 60*degree, 60*degree);
|
||||
outradius = edge_of_triangle_with_angles(60*degree, alpha, 60*degree);
|
||||
}
|
||||
|
||||
ld dieradius = 0.5;
|
||||
|
||||
ld base_to_base;
|
||||
|
||||
if(1) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace534);
|
||||
hyperpoint h = cspin(2, 0, outradius) * zpush0(-dieradius);
|
||||
base_to_base = binsearch(-5, 5, [h] (ld d) {
|
||||
return (zpush(d) * h)[2] >= sin_auto(vid.depth);
|
||||
});
|
||||
// ld base_to_base = cspin(2, 0, outradius) * zpush0(-dieradius);
|
||||
}
|
||||
|
||||
vector<pair<ld, int> > ordering;
|
||||
|
||||
for(int i=0; i<faces(); i++) {
|
||||
|
||||
transmatrix T = facequeue[i].first;
|
||||
int ws = facequeue[i].second;
|
||||
|
||||
for(int d=0; d<si; d++) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace534);
|
||||
add_to_queue(T * cspin(0, 1, 2*M_PI*d/si) * cspin(2, 0, inradius) * cspin(0, 1, M_PI-2*M_PI*spins[ws][d]/si), sides[ws][d]);
|
||||
}
|
||||
|
||||
if(1) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace534);
|
||||
hyperpoint h = zpush(base_to_base) * T * zpush0(dieradius);
|
||||
ld z = asin_auto(h[2]);
|
||||
ordering.emplace_back(-z, i);
|
||||
}
|
||||
}
|
||||
|
||||
sort(ordering.begin(), ordering.end());
|
||||
|
||||
for(auto o: ordering) {
|
||||
int i = o.second;
|
||||
transmatrix T = facequeue[i].first;
|
||||
|
||||
for(int d=0; d<=si; d++) {
|
||||
hyperpoint h;
|
||||
ld z = 0;
|
||||
if(1) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace534);
|
||||
h = zpush(base_to_base) * T * cspin(0, 1, 2*M_PI*(d+.5)/si) * cspin(2, 0, outradius) * zpush0(dieradius);
|
||||
z = asin_auto(h[2]);
|
||||
h /= cos_auto(z);
|
||||
}
|
||||
h[2] = h[3]; h[3] = 0;
|
||||
h = zshift(h, geom3::scale_at_lev(z));
|
||||
curvepoint(h);
|
||||
}
|
||||
queuecurve(V1, 0xFFFFFFFF, 0x40A040FF, PPR::WALL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EX }
|
||||
|
||||
}
|
||||
|
11
content.cpp
11
content.cpp
@ -1690,6 +1690,17 @@ ITEM('/', 0x211F6F, "Cursed Gold", itCursed, IC_TREASURE, ZERO, RESERVED, osNone
|
||||
ITEM('o', 0x208020, "Orb of the Woods", itOrbWoods, IC_ORB, ZERO, RESERVED, osTerraform,
|
||||
"Lets you swap positions with the trees.")
|
||||
|
||||
LAND(0xC0C0FF, "Land of Dice", laDice, 0, itCursed, RESERVED,
|
||||
"This land is full of dice!")
|
||||
|
||||
ITEM('/', 0xD0D0D8, "Crystal Die", itDice, IC_TREASURE, ZERO, RESERVED, osNone,
|
||||
"A nice souvenir from the Land of Dice. Make sure to collect the whole set!")
|
||||
|
||||
WALL('d', 0x181818, "Rollable Die", waDie, WF_WALL | WF_PUSHABLE, RESERVED, 0, sgNone, NODESC)
|
||||
|
||||
WALL('d', 0x181818, "Rollable Die", waDie1, ZERO, RESERVED, 0, sgNone, NODESC)
|
||||
WALL('d', 0x181818, "Rollable Die", waDie2, ZERO, RESERVED, 0, sgNone, NODESC)
|
||||
|
||||
|
||||
//shmupspecials
|
||||
MONSTER( '@', 0xC0C0C0, "Rogue", moPlayer, CF_FACE_UP | CF_PLAYER, RESERVED, moNone, "In the Shoot'em Up mode, you are armed with thrown Knives.")
|
||||
|
4
game.cpp
4
game.cpp
@ -374,6 +374,8 @@ EX void pushThumper(const movei& mi) {
|
||||
cto->wall = waCrateOnTarget;
|
||||
th->wall = waCrateTarget;
|
||||
}
|
||||
else if(w == waDie)
|
||||
dice::roll(mi);
|
||||
else
|
||||
cto->wall = w;
|
||||
if(explode) cto->wall = waFireTrap, cto->wparam = explode;
|
||||
@ -382,6 +384,8 @@ EX void pushThumper(const movei& mi) {
|
||||
}
|
||||
|
||||
EX bool canPushThumperOn(cell *tgt, cell *thumper, cell *player) {
|
||||
if(thumper->wall == waDie && tgt->type == 7)
|
||||
return false;
|
||||
if(tgt->wall == waBoat || tgt->wall == waStrandedBoat) return false;
|
||||
if(isReptile(tgt->wall)) return false;
|
||||
if(isWatery(tgt) && !tgt->monst)
|
||||
|
@ -745,7 +745,7 @@ EX namespace geom3 {
|
||||
// projection: projection parameter
|
||||
// factor: zoom factor
|
||||
|
||||
ld abslev_to_projection(ld abslev) {
|
||||
EX ld abslev_to_projection(ld abslev) {
|
||||
if(sphere || euclid) return vid.camera+abslev;
|
||||
return tanh(abslev) / tanh(vid.camera);
|
||||
}
|
||||
|
14
landgen.cpp
14
landgen.cpp
@ -2585,6 +2585,20 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
break;
|
||||
}
|
||||
|
||||
case laDice: {
|
||||
if(fargen) {
|
||||
int pct = hrand(100);
|
||||
if(pct < 10)
|
||||
c->wall = waDie;
|
||||
// c->wall = pick(waNone, waNone, waStone, waNone, waNone, waStone, waNone, waNone, waStone, waBigStatue, waCrateCrate, waDie);
|
||||
if(c->wall == waDie) {
|
||||
if(ctof(c)) c->wall = waNone;
|
||||
else dice::generate_on(c);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case laCursed: {
|
||||
if(fargen) {
|
||||
c->wall = waStone;
|
||||
|
Loading…
Reference in New Issue
Block a user