From d8428f2ec3ca03ce6e63bf6a0501079a3bf80ce9 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 6 Mar 2019 16:36:10 +0100 Subject: [PATCH] crystal::3d:: transformation --- cell.cpp | 1 + crystal.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ euclid.cpp | 2 +- geom-exp.cpp | 3 + hyper.h | 2 + 5 files changed, 161 insertions(+), 1 deletion(-) diff --git a/cell.cpp b/cell.cpp index f9394fe4..dc96eb22 100644 --- a/cell.cpp +++ b/cell.cpp @@ -296,6 +296,7 @@ void unlink_cdata(heptagon *h) { } void clearfrom(heptagon *at) { + if(!at) return; queue q; unlink_cdata(at); q.push(at); diff --git a/crystal.cpp b/crystal.cpp index 16d57379..a2031340 100644 --- a/crystal.cpp +++ b/crystal.cpp @@ -1259,6 +1259,160 @@ void may_place_compass(cell *c) { c->item = itCompass; } #endif + +#if CAP_CRYSTAL && MAXMDIM >= 4 + +euclid3::coord crystal_to_euclid(coord x) { + euclid3::coord c = 0; + c += x[0]; + c += x[1] * euclid3::COORDMAX; + c += x[2] * euclid3::COORDMAX * euclid3::COORDMAX; + return c/2; + } + +coord euclid3_to_crystal(euclid3::coord x) { + coord res; + auto tmp = euclid3::getcoord(x); + for(int i=0; i<3; i++) res[i] = tmp[i] * 2; + for(int i=3; ihcoords) { + auto co = crystal_to_euclid(p.second); + e->spacemap[co] = p.first; + e->ispacemap[p.first] = co; + + cell* c = p.first->c7; + + // rearrange the monster directions + if(c->mondir < S7 && c->move(c->mondir)) { + auto co1 = crystal_to_euclid(m->hcoords[c->move(c->mondir)->master]) - co; + for(int i=0; i<6; i++) + if(co1 == e->shifttable[i]) + c->mondir = i; + } + + for(int i=0; imove(i) = NULL; + } + + // clean hcoords and heptagon_at so that the map is not deleted when we delete m + m->hcoords.clear(); + m->heptagon_at.clear(); + delete m; + + for(int i=0; ispacemap) { + auto& co = p.first; + auto& h = p.second; + for(int i=0; ispacemap.count(co + e->shifttable[i])) + h->move(i) = e->spacemap[co + e->shifttable[i]], + h->c.setspin(i, (i + 3) % 6, false), + h->c7->move(i) = h->move(i)->c7, + h->c7->c.setspin(i, (i + 3) % 6, false); + } + + clearAnimations(); + cwt.spin = neighborId(cwt.at, infront); + View = iddspin(cwt.at, cwt.spin, M_PI/2); + if(!flipplayer) View = cspin(0, 2, M_PI) * View; + } + +void transform_euclid_to_crystal () { + geometry = gCrystal; + ginf[gCrystal].sides = 6; + ginf[gCrystal].vertex = 4; + ginf[gCrystal].tiling_name = "{6,4}"; + need_reset_geometry = true; + ginf[gCrystal].distlimit = distlimit_table[6]; + + auto e = euclid3::cubemap(); + auto m = new hrmap_crystal; + auto infront = cwt.cpeek(); + + for(auto& p: e->ispacemap) { + auto co = euclid3_to_crystal(p.second); + m->heptagon_at[co] = p.first; + m->hcoords[p.first] = co; + } + + for(auto& p: e->ispacemap) { + cell *c = p.first->c7; + if(c->mondir < S7 && c->move(c->mondir)) { + auto co = euclid3_to_crystal(p.second); + for(int d=0; dmakewalker(co, d); + auto co1 = add(co, lw, FULLSTEP); + if(m->heptagon_at.count(co1) && m->heptagon_at[co1] == c->move(c->mondir)->master) + c->mondir = d; + } + } + for(int i=0; imove(i) = NULL; + } + + e->spacemap.clear(); + e->ispacemap.clear(); + delete e; + + for(int i=0; iheptagon_at) { + auto& co = p.first; + auto& h = p.second; + for(int i=0; imakewalker(co, i); + auto co1 = add(co, lw, FULLSTEP); + if(m->heptagon_at.count(co1)) { + auto lw1 = lw+wstep; + h->move(i) = m->heptagon_at[co1], + h->c.setspin(i, lw1.spin, false), + h->c7->move(i) = h->move(i)->c7; + h->c7->c.setspin(i, h->c.spin(i), false); + } + } + } + + View = Id; + clearAnimations(); + cwt.spin = neighborId(cwt.at, infront); + } + +void add_crystal_transform(char c) { + if(shmup::on) return; + if(geometry == gCrystal && ginf[gCrystal].sides == 6) { + dialog::addItem("convert Crystal to 3D", c); + dialog::add_action(transform_crystal_to_euclid); + } + if(geometry == gCubeTiling) { + dialog::addItem("convert 3D to Crystal", c); + dialog::add_action(transform_euclid_to_crystal); + } + } + +#endif + } } + + diff --git a/euclid.cpp b/euclid.cpp index a32b6b35..32184832 100644 --- a/euclid.cpp +++ b/euclid.cpp @@ -527,8 +527,8 @@ namespace euclid3 { for(int i=0; i= 4 + crystal::add_crystal_transform('x'); + #endif dialog::addBreak(50); diff --git a/hyper.h b/hyper.h index b74ceb0e..e4cf10f9 100644 --- a/hyper.h +++ b/hyper.h @@ -820,6 +820,8 @@ void loadcs(FILE *f, charstyle& cs, int vernum); #define MAXAXE 16 #define MAXHAT 4 +extern bool flipplayer; + namespace multi { extern bool alwaysuse;