mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
starbattle:: undo, lines have fixed colors, nicer lines, and other minor improvements
This commit is contained in:
parent
626999525e
commit
b50c32e775
@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
EX namespace sumotron {
|
EX namespace starbattle {
|
||||||
|
|
||||||
|
eWall empty = waChasm;
|
||||||
|
|
||||||
bool in = false;
|
bool in = false;
|
||||||
|
|
||||||
@ -17,7 +19,7 @@ bool dialog_shown = false;
|
|||||||
|
|
||||||
bool view_errors = false;
|
bool view_errors = false;
|
||||||
bool view_lines = true;
|
bool view_lines = true;
|
||||||
bool view_regions = false;
|
bool view_regions = true;
|
||||||
|
|
||||||
int stars_per_line = 1;
|
int stars_per_line = 1;
|
||||||
int stars_per_region = 1;
|
int stars_per_region = 1;
|
||||||
@ -40,7 +42,19 @@ struct starwalker : cellwalker {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using line_t = vector<starwalker>;
|
bool stop_undo;
|
||||||
|
|
||||||
|
vector<reaction_t> undos;
|
||||||
|
|
||||||
|
void push_stop() {
|
||||||
|
undos.push_back([] { stop_undo = true; });
|
||||||
|
}
|
||||||
|
|
||||||
|
struct line_t {
|
||||||
|
vector<starwalker> cells;
|
||||||
|
color_t color;
|
||||||
|
};
|
||||||
|
|
||||||
vector<line_t> lines;
|
vector<line_t> lines;
|
||||||
|
|
||||||
starwalker rev(starwalker sw) {
|
starwalker rev(starwalker sw) {
|
||||||
@ -54,6 +68,11 @@ starwalker change_flip(starwalker sw) {
|
|||||||
return sw;
|
return sw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
starwalker add_step(starwalker sw) {
|
||||||
|
sw += wstep;
|
||||||
|
return rev(sw);
|
||||||
|
}
|
||||||
|
|
||||||
enum ePenMode {
|
enum ePenMode {
|
||||||
pmSolve,
|
pmSolve,
|
||||||
pmDraw,
|
pmDraw,
|
||||||
@ -61,6 +80,14 @@ enum ePenMode {
|
|||||||
pmWalls
|
pmWalls
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hyperpoint adjust(starwalker sw) {
|
||||||
|
if(!(sw.at->type & 1)) return C0;
|
||||||
|
hyperpoint h1 = currentmap->adj(sw.at, sw.spin) * C0;
|
||||||
|
auto swr = rev(sw);
|
||||||
|
hyperpoint h2 = currentmap->adj(swr.at, swr.spin) * C0;
|
||||||
|
return normalize(C0 * 2 + h1 + h2);
|
||||||
|
}
|
||||||
|
|
||||||
void create_lines() {
|
void create_lines() {
|
||||||
set<starwalker> used;
|
set<starwalker> used;
|
||||||
lines.clear();
|
lines.clear();
|
||||||
@ -75,22 +102,39 @@ void create_lines() {
|
|||||||
if(used.count(sw) || used.count(rev(sw))) continue;
|
if(used.count(sw) || used.count(rev(sw))) continue;
|
||||||
|
|
||||||
starwalker sw0 = sw;
|
starwalker sw0 = sw;
|
||||||
vector<starwalker> line;
|
line_t line;
|
||||||
|
line.color = ((hrand(0xFFFFFF) << 8) | 0x80808080) & 0xEFEFEF80;
|
||||||
bool even = true;
|
bool even = true;
|
||||||
while(true) {
|
while(true) {
|
||||||
if(sw.at->type & 1) even = false;
|
if(sw.at->type & 1) even = false;
|
||||||
line.push_back(sw);
|
line.cells.push_back(sw);
|
||||||
used.insert(sw);
|
used.insert(sw);
|
||||||
sw += wstep;
|
sw = add_step(sw);
|
||||||
sw = rev(sw);
|
|
||||||
if(!sdata.count(sw.at)) break;
|
if(!sdata.count(sw.at)) break;
|
||||||
if(sw == sw0) break;
|
if(sw == sw0) break;
|
||||||
}
|
}
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
if(even) for(auto li: line) used.insert(change_flip(li));
|
if(even) for(auto li: line.cells) used.insert(change_flip(li));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_to_puzzle(cell *c) {
|
||||||
|
sdata[c] = stardata{color_t(0xFFFFFF), false, false};
|
||||||
|
c->wall = waNone;
|
||||||
|
c->land = laCanvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_from_puzzle(cell *c) {
|
||||||
|
sdata.erase(c);
|
||||||
|
c->wall = waChasm;
|
||||||
|
c->land = laNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_undo(cell *c) {
|
||||||
|
auto old = sdata[c];
|
||||||
|
undos.push_back([c, old] { sdata[c] = old; });
|
||||||
|
}
|
||||||
|
|
||||||
void init_starbattle() {
|
void init_starbattle() {
|
||||||
for(cell *c: currentmap->allcells())
|
for(cell *c: currentmap->allcells())
|
||||||
sdata[c] = stardata{color_t(0xFFFFFF), false, false};
|
sdata[c] = stardata{color_t(0xFFFFFF), false, false};
|
||||||
@ -100,7 +144,9 @@ void init_starbattle() {
|
|||||||
ePenMode pen = pmSolve;
|
ePenMode pen = pmSolve;
|
||||||
|
|
||||||
bool draw_star(cell *c, const shiftmatrix& V) {
|
bool draw_star(cell *c, const shiftmatrix& V) {
|
||||||
if(!in || !sdata.count(c)) return false;
|
if(!in) return false;
|
||||||
|
if(c->wall == waSea) c->wall = waChasm;
|
||||||
|
if(!sdata.count(c)) return false;
|
||||||
|
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
c->wall = waNone;
|
c->wall = waNone;
|
||||||
@ -145,46 +191,44 @@ color_t new_region() {
|
|||||||
|
|
||||||
color_t extregion;
|
color_t extregion;
|
||||||
|
|
||||||
vector<color_t> linecolors = {
|
|
||||||
0xFF000040, 0x0000FF40, 0x00FF0040,
|
|
||||||
0xFFFF0040, 0xFF00FF40, 0x00FFFF40,
|
|
||||||
0xFFD50040, 0x40806040
|
|
||||||
};
|
|
||||||
|
|
||||||
void draw_line(line_t& li, color_t col) {
|
void draw_line(line_t& li, color_t col) {
|
||||||
vid.linewidth *= 10;
|
vid.linewidth *= 10;
|
||||||
for(auto& lii: li) {
|
for(auto& lii: li.cells) {
|
||||||
for(const shiftmatrix& V: current_display->all_drawn_copies[lii.at])
|
for(const shiftmatrix& V: current_display->all_drawn_copies[lii.at])
|
||||||
if(sdata.count(lii.peek()))
|
if(sdata.count(lii.peek()))
|
||||||
queueline(V*C0, V*currentmap->adj(lii.at, lii.spin)*C0, col);
|
queueline(V*adjust(lii), V*currentmap->adj(lii.at, lii.spin)*adjust(add_step(lii)), col);
|
||||||
}
|
}
|
||||||
vid.linewidth /= 10;
|
vid.linewidth /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
void starbattle_puzzle() {
|
void starbattle_puzzle() {
|
||||||
|
|
||||||
clearMessages();
|
clearMessages();
|
||||||
|
|
||||||
if(currentmap->gamestart()->wall == waSea)
|
if(currentmap->gamestart()->wall == waChasm)
|
||||||
init_starbattle();
|
init_starbattle();
|
||||||
|
|
||||||
getcstat = '-';
|
getcstat = '-';
|
||||||
cmode = 0;
|
cmode = 0;
|
||||||
if(dialog_shown) cmode = sm::SIDE | sm::DIALOG_STRICT_X | sm::MAYDARK;
|
if(dialog_shown) cmode = sm::SIDE | sm::DIALOG_STRICT_X | sm::MAYDARK;
|
||||||
|
|
||||||
|
dynamicval d1(vid.use_smart_range);
|
||||||
|
dynamicval d2(vid.smart_range_detail);
|
||||||
|
if(euclid) {
|
||||||
|
vid.use_smart_range = 2;
|
||||||
|
vid.smart_range_detail = 2;
|
||||||
|
}
|
||||||
gamescreen(0);
|
gamescreen(0);
|
||||||
|
|
||||||
if(view_lines && mouseover) {
|
if(view_lines && mouseover) {
|
||||||
int lci = 0;
|
|
||||||
initquickqueue();
|
initquickqueue();
|
||||||
int dir = neighborId(mouseover, mouseover2);
|
// int dir = neighborId(mouseover, mouseover2);
|
||||||
for(auto& li: lines) {
|
for(auto& li: lines) {
|
||||||
bool has = false;
|
bool has = false;
|
||||||
for(auto& lii: li) if(lii.at == mouseover && (dir == -1 || lii.spin == dir || rev(lii).spin == dir)) has = true;
|
for(auto& lii: li.cells) if(lii.at == mouseover /* && (dir == -1 || lii.spin == dir || rev(lii).spin == dir) */) has = true;
|
||||||
if(has) {
|
if(has) {
|
||||||
draw_line(li, linecolors[lci]);
|
draw_line(li, li.color);
|
||||||
lci++;
|
}
|
||||||
lci %= isize(linecolors);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
quickqueue();
|
quickqueue();
|
||||||
}
|
}
|
||||||
@ -205,11 +249,15 @@ void starbattle_puzzle() {
|
|||||||
}
|
}
|
||||||
for(auto& li: lines) {
|
for(auto& li: lines) {
|
||||||
int sc = 0;
|
int sc = 0;
|
||||||
for(auto& lii: li) if(sdata[lii.at].starred) sc++;
|
for(auto& lii: li.cells) if(sdata[lii.at].starred) sc++;
|
||||||
if(sc < stars_per_line)
|
if(sc < stars_per_line) {
|
||||||
draw_line(li, 0x0000FF80);
|
draw_line(li, 0x0000FF80);
|
||||||
if(sc > stars_per_line)
|
draw_line(li, (li.color & 0xFFFFFF00) | 0x10);
|
||||||
|
}
|
||||||
|
if(sc > stars_per_line) {
|
||||||
draw_line(li, 0xFF000080);
|
draw_line(li, 0xFF000080);
|
||||||
|
draw_line(li, (li.color & 0xFFFFFF00) | 0x10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
quickqueue();
|
quickqueue();
|
||||||
}
|
}
|
||||||
@ -254,6 +302,21 @@ void starbattle_puzzle() {
|
|||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
|
|
||||||
|
dialog::addItem("undo", 'z');
|
||||||
|
dialog::add_action([] {
|
||||||
|
stop_undo = true;
|
||||||
|
while(stop_undo && !undos.empty()) {
|
||||||
|
stop_undo = false;
|
||||||
|
undos.back()();
|
||||||
|
undos.pop_back();
|
||||||
|
}
|
||||||
|
while(!stop_undo && !undos.empty()) {
|
||||||
|
stop_undo = false;
|
||||||
|
undos.back()();
|
||||||
|
undos.pop_back();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
dialog::addItem("save this puzzle", 'S');
|
dialog::addItem("save this puzzle", 'S');
|
||||||
dialog::add_action([] {
|
dialog::add_action([] {
|
||||||
mapstream::saveMap("starbattle.lev");
|
mapstream::saveMap("starbattle.lev");
|
||||||
@ -299,10 +362,14 @@ void starbattle_puzzle() {
|
|||||||
keyhandler = [] (int sym, int uni) {
|
keyhandler = [] (int sym, int uni) {
|
||||||
handlePanning(sym, uni);
|
handlePanning(sym, uni);
|
||||||
dialog::handleNavigation(sym, uni);
|
dialog::handleNavigation(sym, uni);
|
||||||
|
|
||||||
|
if(among(sym, '-', SDLK_F1) && !holdmouse) push_stop();
|
||||||
|
|
||||||
if(sym == SDLK_F1 && mouseover && !holdmouse) {
|
if(sym == SDLK_F1 && mouseover && !holdmouse) {
|
||||||
cell *c = mouseover;
|
cell *c = mouseover;
|
||||||
if(pen == pmSolve) {
|
if(pen == pmSolve) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
|
save_undo(c);
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
sd.illegal = !sd.illegal;
|
sd.illegal = !sd.illegal;
|
||||||
if(sd.illegal) sd.starred = false;
|
if(sd.illegal) sd.starred = false;
|
||||||
@ -311,6 +378,7 @@ void starbattle_puzzle() {
|
|||||||
}
|
}
|
||||||
if(pen == pmCreate) {
|
if(pen == pmCreate) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
|
save_undo(c);
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
extregion = sd.region;
|
extregion = sd.region;
|
||||||
}
|
}
|
||||||
@ -318,20 +386,21 @@ void starbattle_puzzle() {
|
|||||||
mapeditor::dt_erase(mouseh);
|
mapeditor::dt_erase(mouseh);
|
||||||
}
|
}
|
||||||
if(pen == pmWalls) {
|
if(pen == pmWalls) {
|
||||||
if(!sdata.count(c)) return;
|
|
||||||
if(c == currentmap->gamestart()) return;
|
|
||||||
sdata.erase(c);
|
|
||||||
c->wall = waSea;
|
|
||||||
c->land = laNone;
|
|
||||||
create_lines();
|
|
||||||
holdmouse = true;
|
holdmouse = true;
|
||||||
extregion = 0;
|
extregion = 0;
|
||||||
|
if(!sdata.count(c)) return;
|
||||||
|
if(c == currentmap->gamestart()) return;
|
||||||
|
save_undo(c);
|
||||||
|
undos.push_back([c] { add_to_puzzle(c); create_lines(); });
|
||||||
|
remove_from_puzzle(c);
|
||||||
|
create_lines();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(sym == '-' && mouseover && !holdmouse) {
|
if(sym == '-' && mouseover && !holdmouse) {
|
||||||
cell *c = mouseover;
|
cell *c = mouseover;
|
||||||
if(pen == pmSolve) {
|
if(pen == pmSolve) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
|
save_undo(c);
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
sd.starred = !sd.starred;
|
sd.starred = !sd.starred;
|
||||||
if(sd.starred) sd.illegal = false;
|
if(sd.starred) sd.illegal = false;
|
||||||
@ -340,6 +409,7 @@ void starbattle_puzzle() {
|
|||||||
}
|
}
|
||||||
if(pen == pmCreate) {
|
if(pen == pmCreate) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
|
save_undo(c);
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
sd.region = extregion = new_region();
|
sd.region = extregion = new_region();
|
||||||
}
|
}
|
||||||
@ -348,42 +418,46 @@ void starbattle_puzzle() {
|
|||||||
holdmouse = true;
|
holdmouse = true;
|
||||||
}
|
}
|
||||||
if(pen == pmWalls) {
|
if(pen == pmWalls) {
|
||||||
if(sdata.count(c)) return;
|
|
||||||
c->wall = waNone;
|
|
||||||
c->land = laCanvas;
|
|
||||||
sdata[c] = stardata{color_t(0xFFFFFF), false, false};
|
|
||||||
create_lines();
|
|
||||||
holdmouse = true;
|
holdmouse = true;
|
||||||
extregion = 1;
|
extregion = 1;
|
||||||
|
if(sdata.count(c)) return;
|
||||||
|
undos.push_back([c] { remove_from_puzzle(c); create_lines(); });
|
||||||
|
add_to_puzzle(c);
|
||||||
|
create_lines();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(mouseover && mousepressed) {
|
if(mouseover && mousepressed) {
|
||||||
cell *c = mouseover;
|
cell *c = mouseover;
|
||||||
if(pen == pmSolve) {
|
if(pen == pmSolve) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
|
save_undo(c);
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
if(extregion >= 2)
|
if(extregion >= 2) {
|
||||||
sd.illegal = extregion == 3;
|
sd.illegal = extregion == 3;
|
||||||
else
|
if(sd.illegal) sd.starred = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
sd.starred = extregion == 1;
|
sd.starred = extregion == 1;
|
||||||
|
if(sd.starred) sd.illegal = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(pen == pmWalls && extregion == 1) {
|
if(pen == pmWalls && extregion == 1) {
|
||||||
if(sdata.count(c)) return;
|
if(sdata.count(c)) return;
|
||||||
c->wall = waNone;
|
undos.push_back([c] { remove_from_puzzle(c); create_lines(); });
|
||||||
c->land = laCanvas;
|
add_to_puzzle(c);
|
||||||
sdata[c] = stardata{color_t(0xFFFFFF), false, false};
|
|
||||||
create_lines();
|
create_lines();
|
||||||
}
|
}
|
||||||
if(pen == pmWalls && extregion == 0) {
|
if(pen == pmWalls && extregion == 0) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
if(c == currentmap->gamestart()) return;
|
if(c == currentmap->gamestart()) return;
|
||||||
sdata.erase(c);
|
save_undo(c);
|
||||||
c->wall = waSea;
|
undos.push_back([c] { add_to_puzzle(c); create_lines(); });
|
||||||
c->land = laNone;
|
remove_from_puzzle(c);
|
||||||
create_lines();
|
create_lines();
|
||||||
}
|
}
|
||||||
if(pen == pmCreate) {
|
if(pen == pmCreate) {
|
||||||
if(!sdata.count(c)) return;
|
if(!sdata.count(c)) return;
|
||||||
|
save_undo(c);
|
||||||
auto& sd = sdata[c];
|
auto& sd = sdata[c];
|
||||||
sd.region = extregion;
|
sd.region = extregion;
|
||||||
}
|
}
|
||||||
@ -401,7 +475,7 @@ void launch() {
|
|||||||
/* setup */
|
/* setup */
|
||||||
stop_game();
|
stop_game();
|
||||||
specialland = firstland = laCanvas;
|
specialland = firstland = laCanvas;
|
||||||
canvas_default_wall = waSea;
|
canvas_default_wall = waChasm;
|
||||||
start_game();
|
start_game();
|
||||||
screens[0] = starbattle_puzzle;
|
screens[0] = starbattle_puzzle;
|
||||||
|
|
||||||
@ -411,8 +485,6 @@ void launch() {
|
|||||||
|
|
||||||
vid.linequality = 2;
|
vid.linequality = 2;
|
||||||
patterns::whichShape = '9';
|
patterns::whichShape = '9';
|
||||||
vid.use_smart_range = 2;
|
|
||||||
vid.smart_range_detail = 2;
|
|
||||||
|
|
||||||
showstartmenu = false;
|
showstartmenu = false;
|
||||||
mapeditor::drawplayer = false;
|
mapeditor::drawplayer = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user