mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-05-10 11:14:07 +00:00
ru:: first commit
This commit is contained in:
parent
ff22efaed0
commit
7629b89245
202
rogueviz/ru/classes.cpp
Normal file
202
rogueviz/ru/classes.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
struct data {
|
||||
int keystate;
|
||||
double d;
|
||||
ld modv;
|
||||
ld moda;
|
||||
int dx;
|
||||
};
|
||||
|
||||
using powerfun = hr::function<void(data&)>;
|
||||
|
||||
struct power {
|
||||
int key;
|
||||
string name;
|
||||
string desc;
|
||||
string glyph;
|
||||
color_t color;
|
||||
flagtype flags;
|
||||
powerfun pf;
|
||||
power(int key, string name, string desc, string glyph, color_t color, flagtype f, powerfun pf) : key(key), name(name), desc(desc), glyph(glyph), color(color), flags(f), pf(pf) {
|
||||
}
|
||||
};
|
||||
|
||||
extern vector<power> powers;
|
||||
|
||||
struct bbox {
|
||||
int minx, miny, maxx, maxy;
|
||||
bool operator != (bbox& a) { return minx != a.minx || miny != a.miny || maxx != a.maxx || maxy != a.maxy; }
|
||||
};
|
||||
|
||||
bool intersect(bbox a, bbox b);
|
||||
|
||||
struct room {
|
||||
// texture::texture_data *room_texture;
|
||||
string roomname;
|
||||
renderbuffer *rbuf;
|
||||
cell *where;
|
||||
char block_at[room_y][room_x];
|
||||
bool fov[room_y][room_x];
|
||||
bool which_map_rendered;
|
||||
bool infile, need_rerender;
|
||||
|
||||
vector<unique_ptr<struct entity>> entities;
|
||||
|
||||
eWall at(int x, int y) {
|
||||
return eWall(block_at[y][x] >> 3);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for(int y=0; y<room_y; y++) for(int x=0; x<room_x; x++) block_at[y][x] = 0;
|
||||
}
|
||||
|
||||
void clearfov() {
|
||||
for(int y=0; y<room_y; y++) for(int x=0; x<room_x; x++) fov[y][x] = false;
|
||||
}
|
||||
|
||||
void initial() {
|
||||
int ylev = where->master->distance;
|
||||
if(ylev <= 0)
|
||||
for(int y=room_y-6; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
block_at[y][x] = 8 + 4 + (x&1) + (y&1)*2;
|
||||
if(ylev < 0)
|
||||
for(int y=0; y<room_y-6; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
block_at[y][x] = 8;
|
||||
|
||||
roomname = "UNNAMED-";
|
||||
for(int i=0; i<8; i++) roomname += char('A' + rand() % 26);
|
||||
println(hlog, "generated roomname as ", roomname);
|
||||
}
|
||||
|
||||
void place_small(int x, int y) {
|
||||
block_at[y][x] = 8;
|
||||
}
|
||||
|
||||
void place_big(int x, int y) {
|
||||
block_at[y][x] = 8+4;
|
||||
block_at[y][x+1] = 8+5;
|
||||
block_at[y+1][x] = 8+6;
|
||||
block_at[y+1][x+1] = 8+7;
|
||||
}
|
||||
|
||||
void place_block_full(int x, int y, int b);
|
||||
|
||||
void replace_block(int x, int y, eWall w) {
|
||||
int b = 8 * w;
|
||||
if(block_at[y][x] & 4) b += 4;
|
||||
place_block_full(x, y, b);
|
||||
}
|
||||
|
||||
void generate();
|
||||
|
||||
void reveal(int cx, int cy);
|
||||
void reveal_around(int cx, int cy);
|
||||
void fov_from(int sx, int sy);
|
||||
|
||||
void create_texture();
|
||||
};
|
||||
|
||||
struct entity {
|
||||
virtual double sx() = 0;
|
||||
virtual double sy() = 0;
|
||||
double where_x, where_y;
|
||||
double vel_x, vel_y;
|
||||
|
||||
ld dsx() { return get_scale() * sx(); }
|
||||
ld dsy() { return get_scale() * sy(); }
|
||||
|
||||
double gwhere_x, gwhere_y;
|
||||
double gvel_x, gvel_y;
|
||||
|
||||
void clearg() {
|
||||
gwhere_x = where_x;
|
||||
gwhere_y = where_y;
|
||||
gvel_x = vel_x;
|
||||
gvel_y = vel_y;
|
||||
}
|
||||
|
||||
entity() {
|
||||
where_x = screen_x / 2.;
|
||||
where_y = screen_y / 2.;
|
||||
vel_x = 0;
|
||||
vel_y = 0;
|
||||
destroyed = false;
|
||||
clearg();
|
||||
};
|
||||
|
||||
struct bbox get_pixel_bbox_at(double x, double y);
|
||||
struct bbox get_pixel_bbox() { return get_pixel_bbox_at(where_x, where_y); }
|
||||
|
||||
virtual double grav() { return 0.1; }
|
||||
|
||||
bool on_floor;
|
||||
bool fallthru;
|
||||
bool on_ice;
|
||||
|
||||
bool destroyed;
|
||||
void kino();
|
||||
void apply_grav();
|
||||
void apply_portal_grav();
|
||||
virtual void act() { kino(); }
|
||||
|
||||
double get_scale() { return get_scale_at(where_y); }
|
||||
virtual bool freezing() { return false; }
|
||||
virtual void hit_wall() {};
|
||||
|
||||
virtual void draw();
|
||||
|
||||
virtual string glyph() = 0;
|
||||
virtual color_t color() = 0;
|
||||
};
|
||||
|
||||
struct man : public entity {
|
||||
int facing;
|
||||
int attack_facing;
|
||||
int attack_when;
|
||||
man() { facing = 1; attack_facing = 1; }
|
||||
double sx() override { return 12; }
|
||||
double sy() override { return 12; }
|
||||
string glyph() override { return hallucinating ? "f" : "@"; }
|
||||
color_t color() override { return hallucinating ? 0x808080FF : 0xFF8080FF; }
|
||||
void act() override;
|
||||
void draw() override;
|
||||
};
|
||||
|
||||
extern man m;
|
||||
|
||||
struct sage : public entity {
|
||||
double sx() override { return 12; }
|
||||
double sy() override { return 12; }
|
||||
string glyph() override { return hallucinating ? "D" : "A"; }
|
||||
color_t color() override { return hallucinating ? 0xFF0000FF : 0x90FF90FF; }
|
||||
};
|
||||
|
||||
struct item : public entity {
|
||||
int id;
|
||||
double sx() override { return 12; }
|
||||
double sy() override { return 12; }
|
||||
string glyph() override { return powers[id].glyph; }
|
||||
color_t color() override { return powers[id].color; }
|
||||
void act() override {
|
||||
if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) {
|
||||
addMessage("You pick up the " + powers[id].name + ".");
|
||||
destroyed = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct missile : public entity {
|
||||
missile() { destroyed = false; }
|
||||
double sx() override { return 4; }
|
||||
double sy() override { return 4; }
|
||||
string glyph() override { return "*"; }
|
||||
color_t color() override { return 0x8080FFFF; }
|
||||
void act() override;
|
||||
bool freezing() override { return true; }
|
||||
void hit_wall() override { destroyed = true; }
|
||||
};
|
||||
|
||||
}
|
170
rogueviz/ru/entity.cpp
Normal file
170
rogueviz/ru/entity.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
int gframeid = 0;
|
||||
|
||||
man m;
|
||||
|
||||
bbox entity::get_pixel_bbox_at(double x, double y) {
|
||||
bbox b;
|
||||
double d = get_scale_at(y);
|
||||
double man_x = sx();
|
||||
double man_y = sy();
|
||||
b.minx = x - man_x * d / 2;
|
||||
b.maxx = x + man_x * d / 2 + 1;
|
||||
b.miny = y - man_y * d / 2;
|
||||
b.maxy = y + man_y * d / 2 + 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
void entity::apply_grav() {
|
||||
|
||||
if(non_hyperbolic) return apply_portal_grav();
|
||||
|
||||
ld modv = 80. / game_fps;
|
||||
ld moda = modv * modv;
|
||||
auto d = get_scale();
|
||||
|
||||
vel_y += d * grav() * moda;
|
||||
}
|
||||
|
||||
void entity::kino() {
|
||||
on_floor = false;
|
||||
on_ice = false;
|
||||
|
||||
// ld modv = 60. / game_fps;
|
||||
|
||||
apply_grav();
|
||||
again:
|
||||
|
||||
auto obb = pixel_to_block(get_pixel_bbox());
|
||||
auto nbb = pixel_to_block(get_pixel_bbox_at(where_x + vel_x, where_y + vel_y));
|
||||
auto jbb = join(obb, nbb);
|
||||
|
||||
flagtype blocking = (vel_y < 0 || fallthru) ? W_BLOCK : (W_BLOCK | W_PLATFORM);
|
||||
|
||||
for(int x = obb.minx; x < obb.maxx; x++) for(int y = obb.maxy; y < jbb.maxy; y++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
if(walls[b].flags & blocking) {
|
||||
on_floor = true;
|
||||
if(b == wFrozen) on_ice = true;
|
||||
vel_y /= 2;
|
||||
if(abs(vel_y) < 1e-6) vel_y = 0;
|
||||
if(freezing()) {
|
||||
if(b == wWater) current_room->replace_block(x, y, wFrozen);
|
||||
else if(b != wFrozen) hit_wall();
|
||||
}
|
||||
if(pixel_to_block(get_pixel_bbox_at(where_x + vel_x, where_y + vel_y)).maxy <= y) where_y += vel_y;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = obb.minx; x < obb.maxx; x++) for(int y = jbb.miny; y < obb.miny; y++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
if(walls[b].flags & W_BLOCK) {
|
||||
vel_y /= 2;
|
||||
if(abs(vel_y) < 1e-6) vel_y = 0;
|
||||
if(pixel_to_block(get_pixel_bbox_at(where_x + vel_x, where_y + vel_y)).miny > y) where_y += vel_y;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
if(!fallthru) for(int x = nbb.minx; x < nbb.maxx; x++) for(int y = jbb.maxy-1; y < jbb.maxy; y++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
if(walls[b].flags & W_STAIRCASE) {
|
||||
on_floor = true;
|
||||
if(vel_y > 0) { vel_y = 0; goto again; }
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = obb.maxx; x < jbb.maxx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
if(b == wFountain0) {
|
||||
current_room->replace_block(x, y, wFountain1);
|
||||
addMessage("A magic fountain! You feel safe and refill your potions.");
|
||||
}
|
||||
if(walls[b].flags & W_BLOCK) {
|
||||
if(freezing()) { hit_wall(); }
|
||||
vel_x = (vel_x - max<ld>(vel_y, 0)/10) / 2;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = jbb.minx; x < obb.minx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
if(b == wFountain0) {
|
||||
current_room->replace_block(x, y, wFountain1);
|
||||
addMessage("A magic fountain! You feel safe and refill your potions.");
|
||||
}
|
||||
if(walls[b].flags & W_BLOCK) {
|
||||
if(freezing()) { hit_wall(); }
|
||||
vel_x = (vel_x + max<ld>(vel_y, 0)/10) / 2;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
int bx0 = floor(where_x / block_x);
|
||||
int by0 = floor(where_y / block_y);
|
||||
where_x += vel_x;
|
||||
where_y += vel_y;
|
||||
|
||||
int bx1 = floor(where_x / block_x);
|
||||
int by1 = floor(where_y / block_y);
|
||||
|
||||
if(non_hyperbolic) {
|
||||
auto& loc = all_locations[by0][bx0];
|
||||
if(bx1 > bx0) {
|
||||
auto& loc1 = loc.get(0);
|
||||
where_x += block_x * (loc1.x - (loc.x + 1));
|
||||
where_y += block_y * (loc1.y - loc.y);
|
||||
}
|
||||
if(bx1 < bx0) {
|
||||
auto& loc1 = loc.get(2);
|
||||
where_x += block_x * (loc1.x - (loc.x - 1));
|
||||
where_y += block_x * (loc1.y - loc.y);
|
||||
}
|
||||
if(by1 < by0) {
|
||||
auto& loc1 = loc.get(1);
|
||||
where_x += block_x * (loc1.x - loc.x);
|
||||
where_y += block_x * (loc1.y - (loc.y - 1));
|
||||
}
|
||||
if(by1 > by0) {
|
||||
auto& loc1 = loc.get(3);
|
||||
where_x += block_x * (loc1.x - loc.x);
|
||||
where_y += block_x * (loc1.y - (loc.y + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// ld test_x, test_y;
|
||||
// tie(test_x, test_y) = from_hyper(h_at);
|
||||
|
||||
/*println(hlog, tie(where_x, where_y), " TO ", h_at, " TO ", tie(test_x, test_y));
|
||||
exit(1); */
|
||||
|
||||
if(true || !non_hyperbolic) {
|
||||
hyperpoint h_at = to_hyper(where_x, where_y);
|
||||
hyperpoint h_was = to_hyper(where_x - vel_x, where_y - vel_y);
|
||||
hyperpoint h_willbe = rgpushxto0(h_at) * MirrorX * MirrorY * gpushxto0(h_at) * h_was;
|
||||
ld next_x, next_y;
|
||||
tie(next_x, next_y) = from_hyper(h_willbe);
|
||||
vel_x = next_x - where_x;
|
||||
vel_y = next_y - where_y;
|
||||
}
|
||||
|
||||
apply_grav();
|
||||
|
||||
gwhere_x += gvel_x;
|
||||
gwhere_y += gvel_y;
|
||||
|
||||
ld delta = 1/60.;
|
||||
if((where_x - gwhere_x) * (gvel_x - vel_x) + (where_y - gwhere_y) * (gvel_y - vel_y) < 0) delta *= 2;
|
||||
ld ndelta = 1-delta;
|
||||
gvel_x = ndelta * gvel_x + delta * (where_x - gwhere_x);
|
||||
gvel_y = ndelta * gvel_y + delta * (where_y - gwhere_y);
|
||||
}
|
||||
|
||||
void missile::act() {
|
||||
kino();
|
||||
if(where_x > screen_x || where_x < 0 || where_y < 0 || where_y > screen_y) destroyed = true;
|
||||
}
|
||||
|
||||
}
|
121
rogueviz/ru/geometry.cpp
Normal file
121
rogueviz/ru/geometry.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
hyperpoint to_hyper(ld x, ld y) {
|
||||
if(non_hyperbolic) return hyperpoint(x, y, 1, 1);
|
||||
y -= t_margin_at;
|
||||
y += actual_screen_y;
|
||||
x -= xctr;
|
||||
|
||||
y /= mscale;
|
||||
x /= mscale;
|
||||
|
||||
y += .5;
|
||||
ld d = x*x + y*y;
|
||||
x /= d;
|
||||
y /= d;
|
||||
y -= 1;
|
||||
hyperpoint h;
|
||||
h[0] = -x; h[1] = y; h[2] = 1;
|
||||
h = spin270() * h;
|
||||
return perspective_to_space(h, 1, gcHyperbolic);
|
||||
}
|
||||
|
||||
pair<ld, ld> from_hyper(hyperpoint h) {
|
||||
if(non_hyperbolic) return {h[0], h[1]};
|
||||
h = spin90() * h; h[0] = -h[0];
|
||||
h[2] += 1;
|
||||
h /= h[2];
|
||||
|
||||
h[1] += 1;
|
||||
ld d = h[0]*h[0] + h[1]*h[1];
|
||||
h /= d;
|
||||
h[1] -= .5;
|
||||
|
||||
double x = h[0], y = h[1];
|
||||
|
||||
y *= mscale;
|
||||
x *= mscale;
|
||||
|
||||
y -= actual_screen_y;
|
||||
y += t_margin_at;
|
||||
x += xctr;
|
||||
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
// room connections
|
||||
|
||||
void switch_to_room(room *r) {
|
||||
current_room->need_rerender = true;
|
||||
current_room = r;
|
||||
current_room->need_rerender = true;
|
||||
}
|
||||
|
||||
bool is_right(room *r) {
|
||||
cell *c = r->where;
|
||||
c->cmove(3);
|
||||
return c->c.spin(3) == 0;
|
||||
}
|
||||
|
||||
room *get_adjacent(room *r, int i) {
|
||||
cell *c = r->where;
|
||||
c->cmove(i);
|
||||
c = c->cmove(i);
|
||||
return get_room_at(c);
|
||||
}
|
||||
|
||||
void switch_to_adjacent_room(int i) {
|
||||
switch_to_room(get_adjacent(current_room, i));
|
||||
}
|
||||
|
||||
ld get_scale_at(ld y) {
|
||||
if(non_hyperbolic) return 1;
|
||||
return (actual_screen_y + (y - t_margin_at)) / (actual_screen_y * 3/2.);
|
||||
}
|
||||
|
||||
bbox pixel_to_block(bbox b) {
|
||||
b.minx /= block_x;
|
||||
b.miny /= block_y;
|
||||
b.maxx = (b.maxx + block_x-1) / block_x;
|
||||
b.maxy = (b.maxy + block_y-1) / block_y;
|
||||
if(b.minx < 0) b.minx = 0;
|
||||
if(b.miny < 0) b.miny = 0;
|
||||
if(b.maxx >= room_x) b.maxx = room_x;
|
||||
if(b.maxy >= room_y) b.maxy = room_y;
|
||||
return b;
|
||||
}
|
||||
|
||||
bbox join(bbox a, bbox b) {
|
||||
bbox r;
|
||||
r.minx = min(a.minx, b.minx);
|
||||
r.miny = min(a.miny, b.miny);
|
||||
r.maxx = max(a.maxx, b.maxx);
|
||||
r.maxy = max(a.maxy, b.maxy);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool intersect(bbox a, bbox b) {
|
||||
return max(a.minx, b.minx) < min(a.maxx, b.maxx) && max(a.miny, b.miny) < min(a.maxy, b.maxy);
|
||||
}
|
||||
|
||||
void print(hstream& hs, const bbox& b) {
|
||||
print(hs, "[", b.minx,",",b.miny, ",",b.maxx,",",b.maxy,"]");
|
||||
}
|
||||
|
||||
hyperpoint rupf(ld x, ld y) {
|
||||
return hyperpoint(x, y, 1, 0);
|
||||
}
|
||||
|
||||
shiftmatrix asp(ld x, ld y, ld scale, ld scalex, ld scaley) {
|
||||
transmatrix V = Id;
|
||||
|
||||
V[0][2] = (x - screen_x/2) * scale;
|
||||
V[1][2] = (y - screen_y/2) * scale;
|
||||
V[0][0] = 2 * cgi.hcrossf / cgi.crossf * scale * scalex;
|
||||
V[1][1] = 2 * cgi.hcrossf / cgi.crossf * scale * scaley;
|
||||
V[2][2] = 1;
|
||||
|
||||
return shiftless(V);
|
||||
}
|
||||
|
||||
}
|
138
rogueviz/ru/globals.cpp
Normal file
138
rogueviz/ru/globals.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
using namespace hr;
|
||||
|
||||
/* the size of a block, in pixels */
|
||||
constexpr int block_x = 8;
|
||||
constexpr int block_y = 8;
|
||||
|
||||
/* the size of a room (screen), in blocks */
|
||||
constexpr int room_x = 80;
|
||||
constexpr int room_y = 40;
|
||||
|
||||
/* the size of a room, in pixels */
|
||||
constexpr int screen_x = block_x * room_x;
|
||||
constexpr int screen_y = block_y * room_y;
|
||||
|
||||
/* the size of the area shared between right/left blocks */
|
||||
constexpr int lr_margin = 4;
|
||||
|
||||
/* the size of the area shared with the block above */
|
||||
constexpr int t_margin = 2;
|
||||
|
||||
/* the size of the area shared with the block below */
|
||||
constexpr int b_margin = 2 * t_margin;
|
||||
|
||||
/* the position of margins in pixels */
|
||||
constexpr int l_margin_at = lr_margin * block_x / 2;
|
||||
constexpr int r_margin_at = screen_x - block_x * lr_margin / 2;
|
||||
constexpr int t_margin_at = t_margin * block_y / 2;
|
||||
constexpr int b_margin_at = screen_y - b_margin * block_y / 2;
|
||||
|
||||
/* between the margins */
|
||||
constexpr int actual_screen_x = r_margin_at - l_margin_at;
|
||||
constexpr int actual_screen_y = b_margin_at - t_margin_at;
|
||||
|
||||
int game_fps = 300;
|
||||
bool bottom = 1;
|
||||
|
||||
constexpr auto yctr = (t_margin_at + b_margin_at) / 2.;
|
||||
constexpr auto xctr = (l_margin_at + r_margin_at) / 2.;
|
||||
|
||||
double mscale = 100;
|
||||
|
||||
bool non_hyperbolic;
|
||||
bool one_room;
|
||||
|
||||
struct ruwall {
|
||||
string name;
|
||||
string glyph;
|
||||
color_t color;
|
||||
flagtype flags;
|
||||
};
|
||||
|
||||
enum eWall { wAir, wWall, wBouncy, wSpike, wWater, wFrozen, wDoor, wSmashedDoor, wFountain0, wFountain1, wBluePortal, wOrangePortal, wPlatform };
|
||||
|
||||
flagtype W_BLOCK = 1;
|
||||
flagtype W_TRANS = 2;
|
||||
flagtype W_PLATFORM = 4;
|
||||
flagtype W_STAIRCASE = 8;
|
||||
flagtype W_PAIN = 16;
|
||||
|
||||
constexpr int qwall = 14;
|
||||
|
||||
ruwall walls[qwall] = {
|
||||
{"air", ".", 0x40404080, W_TRANS},
|
||||
{"wall", "#", 0xFFFFFFFF, W_BLOCK},
|
||||
{"bouncy wall", "#", 0x80FF80FF, W_BLOCK},
|
||||
{"spike", "^", 0xC08080FF, W_BLOCK | W_TRANS},
|
||||
{"water", "~", 0x0000FFFF, W_BLOCK | W_TRANS},
|
||||
{"frozen water", "#", 0xC0C0FFFF, W_BLOCK},
|
||||
{"door", "+", 0xC06000FF, W_BLOCK},
|
||||
{"smashed door", "'", 0xC06000FF, W_TRANS},
|
||||
{"magic fountain", "!", 0x8080C0FF, W_TRANS},
|
||||
{"magic fountain (active)", "!", 0xA0A0FFFF, W_TRANS},
|
||||
{"blue portal", "=", 0x4040C0FF, W_TRANS},
|
||||
{"orange portal", "=", 0xC08040FF, W_TRANS},
|
||||
{"platform", "-", 0xFFFFFFFF, W_PLATFORM | W_TRANS },
|
||||
{"staircase", "-", 0xFFFF80FF, W_PLATFORM | W_TRANS | W_STAIRCASE },
|
||||
};
|
||||
|
||||
int sel = 1;
|
||||
|
||||
bool hallucinating;
|
||||
|
||||
template<class T> bool in_range(T val, T minv, T maxv) { return val >= minv && val <= maxv; }
|
||||
|
||||
map<cell*, struct room> rooms;
|
||||
|
||||
struct room *current_room;
|
||||
|
||||
basic_textureinfo roomtinf;
|
||||
hpcshape roomshape, roomshape_big;
|
||||
|
||||
bool is_right(struct room *r);
|
||||
struct room *get_adjacent(struct room *r, int i);
|
||||
|
||||
ld get_scale_at(ld y);
|
||||
room *get_room_at(cell *c);
|
||||
|
||||
// gravity portals
|
||||
|
||||
extern bool gravision;
|
||||
|
||||
struct location {
|
||||
int x, y;
|
||||
char ch;
|
||||
bool fixed;
|
||||
ld potential;
|
||||
array<location*, 4> neighbors;
|
||||
location& get(int id) { return neighbors[id][0]; }
|
||||
};
|
||||
|
||||
extern array<array<location, 256>, 256> all_locations;
|
||||
|
||||
enum class mapmode { standard, poincare, klein };
|
||||
|
||||
enum class mode { editmap, menu, playing, paused, inventory };
|
||||
|
||||
mode cmode = mode::playing;
|
||||
|
||||
mapmode cmapmode = mapmode::standard;
|
||||
void switch_mapmode_to(mapmode m);
|
||||
|
||||
bool should_apply_fov() { return among(cmode, mode::playing, mode::paused, mode::inventory); }
|
||||
|
||||
void enable();
|
||||
|
||||
void update_keystate();
|
||||
bool keyheld(int id);
|
||||
bool keywasheld(int id);
|
||||
bool keypressed(int id);
|
||||
|
||||
void sync_map();
|
||||
|
||||
void render_room_objects(room *r);
|
||||
|
||||
|
||||
}
|
30
rogueviz/ru/man.cpp
Normal file
30
rogueviz/ru/man.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
void handle_powers(data& d);
|
||||
|
||||
void man::act() {
|
||||
kino();
|
||||
|
||||
data dat;
|
||||
dat.d = get_scale();
|
||||
dat.modv = 60. / game_fps;
|
||||
dat.moda = dat.modv * dat.modv;
|
||||
dat.dx = 0;
|
||||
|
||||
fallthru = false;
|
||||
|
||||
handle_powers(dat);
|
||||
|
||||
if(on_floor && !on_ice) {
|
||||
vel_x = dat.dx * dat.d * dat.modv * 2.5;
|
||||
}
|
||||
else {
|
||||
vel_x += dat.dx * dat.d * .05 * dat.moda;
|
||||
}
|
||||
|
||||
if(dat.dx) facing = dat.dx;
|
||||
|
||||
current_room->fov_from(where_x / block_x, where_y / block_y);
|
||||
}
|
||||
|
||||
}
|
438
rogueviz/ru/map.ru
Normal file
438
rogueviz/ru/map.ru
Normal file
@ -0,0 +1,438 @@
|
||||
ROOM Red Rooster Inn
|
||||
# wall
|
||||
+ door
|
||||
- platform
|
||||
s staircase
|
||||
. air
|
||||
MAP
|
||||
...................##.............................+-...-+..---...##.............
|
||||
..................##################################----############............
|
||||
.................##.....................#.............s.......#....##...........
|
||||
................##......................#............s........#.....##..........
|
||||
...............##.......................#...........s.........#......##.........
|
||||
..............##........................#..........s..........#.......##........
|
||||
.............##.........................#.........s...........#........##.......
|
||||
............##..........................+........s............+.........##......
|
||||
...........##...........................+.......s.............+..........##.....
|
||||
..........############################################----##################....
|
||||
.........###........................................##.s............##....##....
|
||||
..........#b........................................#b..s...........#b....#b....
|
||||
..........##........................................##...s..........##....##....
|
||||
..........#b....---------..----------..----------...#b....s.........#b....#b....
|
||||
..........##........................................##.....s........##....##....
|
||||
..........#b........................................#b......s.......#b....#b....
|
||||
..........##........................................##.......s......##....##....
|
||||
..........#b....---------..----------..----------...#b........s.....#b....#b....
|
||||
..........##........................................##.........s....##....##....
|
||||
..........#b........................................#b..........s...#b....#b....
|
||||
..........##........................................##...........s..+.....##....
|
||||
..........#b........................................#b............s.+.....#b....
|
||||
..........##....---------..----------..----------...##...........s##########....
|
||||
..........#b........................................#b..........s...#b....#b....
|
||||
..........##........................................##.........s....##....##....
|
||||
..........#b........................................#b........s.....#b....#b....
|
||||
..........##....---------..----------..----------...##.......s......##....##....
|
||||
..........#b........................................#b......s.......#b....#b....
|
||||
..........##........................................##.....s........##....##....
|
||||
..........#b........................................#b....s.........#b....#b....
|
||||
..........++....---------..----------..----------...++...s..........##....##....
|
||||
..........+b........................................+b..s...........#b....#b....
|
||||
..........++........................................++.s............++....##....
|
||||
..........+b........................................+bs.............+b....#b....
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
||||
MOVE 0 Red Rooster Inn
|
||||
ROOM Red Rooster Inn, guest rooms
|
||||
# wall
|
||||
+ door
|
||||
- platform
|
||||
. air
|
||||
MAP
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
#####################################...........................................
|
||||
................##..........##...#####..........................................
|
||||
................#b..........#b....#b#b#.........................................
|
||||
................##..........##.....#####........................................
|
||||
................#b..........#b......#b#b#.......................................
|
||||
................##..........##.......#####......................................
|
||||
................#b..........#b........#b#b#.....................................
|
||||
................++..........++.........#####....................................
|
||||
................+b..........+b..........#b#b#...................................
|
||||
................++..........++...........#####..................................
|
||||
................+b..........+b............#b#b#.................................
|
||||
########################--######################................................
|
||||
......................#b-b........#b........#b#b#...............................
|
||||
......................##--........##.........#####..............................
|
||||
......................#b-b........#b..........#b#b#.............................
|
||||
......................##--........##...........#####............................
|
||||
......................#b-b........#b............#b#b#...........................
|
||||
......................++--........++.............#####..........................
|
||||
......................+b-b........+b..............#b#b#.........................
|
||||
......................++--......--++....------......####........................
|
||||
......................+b-b......-b+b....-b-b-b......#b#b........................
|
||||
##########################--------########################......................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b-b-b-b-b#b#b#b#b#b#b#b#b#b#b#b#b......................
|
||||
START 344 274
|
||||
ITEM 382 287
|
||||
dagger
|
||||
OK
|
||||
|
||||
MOVE 1 Red Rooster Inn
|
||||
ROOM Red Rooster Inn, host rooms
|
||||
# wall
|
||||
. air
|
||||
MAP
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................##..............
|
||||
................................................................#b..............
|
||||
................................................................##..............
|
||||
................................................................#b..............
|
||||
................................................................##..............
|
||||
.......................................................##########b##############
|
||||
......................................................#####.....................
|
||||
.....................................................##b#b......................
|
||||
....................................................#####.......................
|
||||
...................................................##b#b........................
|
||||
..................................................#####.........................
|
||||
.................................................##b#b..........................
|
||||
................................................#####...........................
|
||||
...............................................##b#b............................
|
||||
..............................................#####.............................
|
||||
.............................................##b#b..............................
|
||||
............................................####################################
|
||||
...........................................##b#b................................
|
||||
..........................................#####.................................
|
||||
.........................................##b#b..................................
|
||||
........................................#####...................................
|
||||
.......................................##b#b....................................
|
||||
......................................#####.....................................
|
||||
.....................................##b#b......................................
|
||||
....................................####........................................
|
||||
....................................#b#b........................................
|
||||
..................................##############################################
|
||||
..................................#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
||||
MOVE 2 Red Rooster Inn
|
||||
ROOM Forest Path
|
||||
# wall
|
||||
- platform
|
||||
. air
|
||||
^ spike
|
||||
x air
|
||||
MAP
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
....^...........................................................................
|
||||
....^...........................................................................
|
||||
....^...........................................................................
|
||||
....^...........................................................................
|
||||
....^...........................................................................
|
||||
....^...........................................................................
|
||||
....^.......^.......^........^...............^.....^.......^....................
|
||||
....^....----------------------------------------------------------.............
|
||||
....^....^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.##.^...............................##--..
|
||||
....^..................................##.................................##....
|
||||
....^..................................##.................................##....
|
||||
....^--...............................-##-................................##....
|
||||
....^..................................##.............................----##....
|
||||
....^..................................##.................................##....
|
||||
....^..................................##-................................##--..
|
||||
....^.....^...........................-##.................^........^......##....
|
||||
....^--------------......----------....##.......--------------------------##....
|
||||
....^.^.^.^.^.^.^.^.......^.^.^.^.^....##.................................##....
|
||||
....^..................................##-................................##....
|
||||
....^...............^...^..............##...--..................................
|
||||
......................^...............###.......................................
|
||||
.......................................##.......................................
|
||||
.......................................###......................................
|
||||
..................................--...##.......................................
|
||||
.......................................##.......................................
|
||||
......................................^##.......................................
|
||||
..............................--.......##^....--................................
|
||||
.......................................xx.......................................
|
||||
.......................................xx.......................................
|
||||
......................................x#x#......................................
|
||||
................^.....................#b#b...................^..................
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
||||
MOVE 2 Forest Path
|
||||
ROOM Climbing the Hill
|
||||
# wall
|
||||
. air
|
||||
MAP
|
||||
################................................................................
|
||||
#################...............................................................
|
||||
##################..............................................................
|
||||
#b#b#b#b#b#b#b#b#b#.............................................................
|
||||
####################............................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#...........................................................
|
||||
######################..........................................................
|
||||
#b#b#b#b#b###b#b#b#b##..........................................................
|
||||
#######################.........................................................
|
||||
#b#b#b#b#b#b#b#b#b#b###.........................................................
|
||||
########################........................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b........................................................
|
||||
#########################.......................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#.......................................................
|
||||
##########################......................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#.....................................................
|
||||
############################....................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#...................................................
|
||||
##############################..................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#.................................................
|
||||
################################................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#...............................................
|
||||
##################################..............................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b##............................................
|
||||
######################################..........................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b##........................................
|
||||
##########################################......................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b###...................................
|
||||
################################################................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b####............................
|
||||
########################################################........................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#####...................
|
||||
################################################################................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#######.........
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
################################################################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
||||
MOVE 1 Climbing the Hill
|
||||
ROOM Dungeon Entrance
|
||||
# wall
|
||||
+ door
|
||||
. air
|
||||
^ spike
|
||||
MAP
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
................................................................................
|
||||
#...............................................................................
|
||||
##..............................................................................
|
||||
###.............................................................................
|
||||
####............................................................................
|
||||
#####...........................................................................
|
||||
######..........................................................................
|
||||
#######.........................................................................
|
||||
########........................................................................
|
||||
#########.......................................................................
|
||||
##########......................................................................
|
||||
###########.....................................................................
|
||||
############....................................................................
|
||||
#############...................................................................
|
||||
##############..................................................................
|
||||
##################..............................................................
|
||||
#####################.^.........................................................
|
||||
######################^.........................................................
|
||||
#######################.........................................................
|
||||
..................++............................................................
|
||||
..................+b............................................................
|
||||
..................++............................................................
|
||||
..................+b............................................................
|
||||
###########################.....................................................
|
||||
#############################...................................................
|
||||
##############################..................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b..................................................
|
||||
################################................................................
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b................................................
|
||||
OK
|
||||
|
||||
MOVE 2 Climbing the Hill
|
||||
ROOM Will be Hard to Return
|
||||
# wall
|
||||
. air
|
||||
MAP
|
||||
########################################################....####################
|
||||
########################################################....####################
|
||||
########################################################....####################
|
||||
#b###############################b#b#b#b#b#b#b#########b....#b###############b#b
|
||||
########################################################....####################
|
||||
#b#######################b#b#b#b#b#b#b#######b#b#######b....#b###############b#b
|
||||
########################################################....####################
|
||||
#b###########b#b#b#b#b#b#b#############b###########b###b....#b###b#b#####b###b#b
|
||||
########################################################....####################
|
||||
#b#######b#b#b#b###########b#b#b#b#b#b#b#b#b#######b###b....#b#####b#b#b#b###b#b
|
||||
########################################################....####################
|
||||
#b#####b#b###############b#b###############b#b#b#b#b###b....#b#######b#b#####b#b
|
||||
########################################################....####################
|
||||
#b#####b###################################b###########b....#b#######b#b#####b#b
|
||||
########################################################....####################
|
||||
#b###b#####################################b###########b....#b###b#b###b#####b#b
|
||||
########################################################....####################
|
||||
#b###b#b###################b#b#b###########b###########b....#b###b#######b###b#b
|
||||
########################################################....####################
|
||||
#b#####b#####b#b#b#b#b#b#b#b#####b#b#####b#############b....#b###b#b#####b###b#b
|
||||
########################################################....####################
|
||||
#b#####b#b#b#b###b#################b#b###b###########b#b....#b#####b#b###b###b#b
|
||||
########################################################....####################
|
||||
#b#######b#b#####b#################b#b#####b#########b#b....#b#######b###b#b#b#b
|
||||
########################################################....####################
|
||||
#b#########b###b#######b#b###b#b#b#b#######b#########b#b....#b#####b#b#####b#b#b
|
||||
########################################################....####################
|
||||
#b###########b###########b#b#b#########################b....#b#####b#######b#b#b
|
||||
########################################################....####################
|
||||
#b###########b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#########b....#b###########b#b#b#b
|
||||
########################################################....####################
|
||||
#b###################################b#b###############b....#b#######b###b###b#b
|
||||
########################################################....####################
|
||||
#b#####################################################b....#b#####b#b#b#b###b#b
|
||||
########################################################....####################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b....#b#b#b#b#b#b#b#b#b#b
|
||||
########################################################....####################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b....#b#b#b#b#b#b#b#b#b#b
|
||||
########################################################....####################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b....#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
||||
MOVE 3 Climbing the Hill
|
||||
ROOM Dungeons of Doom
|
||||
# wall
|
||||
+ door
|
||||
- staircase
|
||||
. air
|
||||
A platform
|
||||
MAP
|
||||
#############################..#################################################
|
||||
#############################..#################################################
|
||||
########################..............##########################################
|
||||
########################..............####################..............########
|
||||
####............########..............########..........++..............########
|
||||
####............########..............########..........+b..............########
|
||||
####............++....++..............++........##########..............########
|
||||
####............+b....+b..............+b........##########..............########
|
||||
####............########..............####################-.............########
|
||||
####............########..............####################-.............########
|
||||
####...........-########..............####################-.............########
|
||||
####...........-##########################################-.............########
|
||||
####...........-##########################..........######-.............########
|
||||
##########AA##############################..........#################AA#########
|
||||
##########..##############################..........#################..#########
|
||||
##########AA##############################..........#################AA#########
|
||||
##########.......#########################..........++.................#########
|
||||
##########.......#########################..........+b.................#########
|
||||
###############..#########################..........###########--###############
|
||||
###############--##############################################--###############
|
||||
########.......--...###########################################--###############
|
||||
########.......--...##########################################.--........#######
|
||||
########.......--...############............##################.--........#######
|
||||
########.......--...############............##################.--........#######
|
||||
########.......--...++........++............##################.--........#######
|
||||
########.......--...+b........+b............##################.--........#######
|
||||
########.......--...############............##################.--........#######
|
||||
########............############............##################.--........#######
|
||||
########............############............++..............++.--........#######
|
||||
################################............+b..............+b.--........#######
|
||||
################################...........A##################...........#######
|
||||
################################............##################...........#######
|
||||
####################################AAAA######################...........#######
|
||||
####################################AbAb########################################
|
||||
####################################..--########################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b..-b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
####################################..--########################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b..-b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
####################################..--########################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b..-b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
||||
MOVE 2 Dungeon Entrance
|
||||
ROOM Dark Passage
|
||||
# wall
|
||||
. air
|
||||
MAP
|
||||
########################################################################........
|
||||
########################################################################........
|
||||
#########################################################################.......
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#############b#b#####b#.......
|
||||
##########################################################################......
|
||||
#b#####b#b#b#b#b#b#b#b#b#b###################b#b#b#b#b#############b######......
|
||||
###########################################################################.....
|
||||
#b#############b#b###################b#b#b#b###############################.....
|
||||
###########################################################################.....
|
||||
#b###########b#b###############b#b#b#b######################################....
|
||||
############################################################################....
|
||||
#b#########b#b#############b#b#b###################b#b#b#b#b#b#b#b##########....
|
||||
#############################################################################...
|
||||
#b#######b#############b#b#################b#b#b#b############################..
|
||||
###############################################################################.
|
||||
#b#####b#b#########b#b#b#############b#b#b######################################
|
||||
################################################################################
|
||||
#b#####b#########b#b#############b#b#b#########################b#b##############
|
||||
################################################################################
|
||||
#b###b#b#######b#b###########b#b#b#####################b#b#b#b###b###########b##
|
||||
################################################################################
|
||||
#b###########b#b###########b#b#################b#b#b#b###############b#b#b#b#b##
|
||||
################################################################################
|
||||
#b###########b#########b#b#b#############b#b#b#b###############b#b#b#b##########
|
||||
################################################################################
|
||||
#b###########b#######b#b###############b#b#################b#b##################
|
||||
################################################################################
|
||||
#b###########b##################################################################
|
||||
################################################################################
|
||||
#b###############b#########b####################################################
|
||||
##################################..............................................
|
||||
#b#########b#b#b#######b#b#######b..............................................
|
||||
##################################..............................................
|
||||
#b#######b###########b#b#########b..............................................
|
||||
##################################..........####################################
|
||||
#b###############################b..........#...#######.....................####
|
||||
##################################........######################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b........#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
##################################........######################################
|
||||
#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b........#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b#b
|
||||
OK
|
||||
|
101
rogueviz/ru/portals.cpp
Normal file
101
rogueviz/ru/portals.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
// an experiment on potential-correct gravity
|
||||
|
||||
namespace rogue_unlike {
|
||||
|
||||
bool gravision;
|
||||
|
||||
array<array<location, 256>, 256> all_locations;
|
||||
|
||||
void entity::apply_portal_grav() {
|
||||
ld modv = 60. / game_fps;
|
||||
ld moda = modv * modv;
|
||||
auto d = get_scale();
|
||||
int bx0 = floor(where_x / block_x);
|
||||
int by0 = floor(where_y / block_y);
|
||||
auto& loc = all_locations[by0][bx0];
|
||||
auto px = (loc.get(0).potential - loc.get(2).potential) * 255 / 2;
|
||||
auto py = (loc.get(3).potential - loc.get(1).potential) * 255 / 2;
|
||||
vel_x += d * grav() * moda * px;
|
||||
vel_y += d * grav() * moda * py;
|
||||
}
|
||||
|
||||
void load_nonhyperbolic() {
|
||||
enable();
|
||||
non_hyperbolic = true;
|
||||
one_room = true;
|
||||
fhstream f("rogueviz/ru/rumap.txt", "rt");
|
||||
vector<string> rumap;
|
||||
for(int y=0; y<room_y; y++) rumap.push_back(scan<string>(f));
|
||||
println(hlog, rumap);
|
||||
|
||||
auto& cr = *current_room;
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
cr.block_at[y][x] =
|
||||
rumap[y][x] == '#' ? 8 :
|
||||
rumap[y][x] == '-' ? 12*8 :
|
||||
rumap[y][x] == '.' ? 0 :
|
||||
rumap[y][x] >= 'a' && rumap[y][x] <= 'z' ? 10*8 :
|
||||
rumap[y][x] >= 'A' && rumap[y][x] <= 'Z' ? 11*8 :
|
||||
1;
|
||||
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++) cr.fov[y][x] = true;
|
||||
|
||||
actual_view_transform = Id;
|
||||
|
||||
map<char, location*> where_is;
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
where_is[rumap[y][x]] = &all_locations[y][x];
|
||||
|
||||
for(int y=0; y<256; y++)
|
||||
for(int x=0; x<256; x++) {
|
||||
auto& loc = all_locations[y][x];
|
||||
loc.x = x;
|
||||
loc.y = y;
|
||||
loc.fixed = false;
|
||||
loc.ch = (y < room_y && x < room_x) ? rumap[y][x] : 0;
|
||||
loc.neighbors[0] = &all_locations[y][(x+1)&255];
|
||||
loc.neighbors[1] = &all_locations[(y-1)&255][x];
|
||||
loc.neighbors[2] = &all_locations[y][(x-1)&255];
|
||||
loc.neighbors[3] = &all_locations[(y+1)&255][x];
|
||||
}
|
||||
|
||||
for(int y=0; y<256; y++)
|
||||
for(int x=0; x<256; x++) {
|
||||
auto& loc = all_locations[y][x];
|
||||
if(in_range(loc.get(1).ch, 'a', 'z')) {
|
||||
auto& up_below = loc;
|
||||
auto& up_above = loc.get(1);
|
||||
auto& down_below = where_is[loc.get(1).ch ^ 32][0];
|
||||
auto& down_above = down_below.get(1);
|
||||
swap(up_below.neighbors[1], down_below.neighbors[1]);
|
||||
swap(up_above.neighbors[3], down_above.neighbors[3]);
|
||||
}
|
||||
}
|
||||
|
||||
for(int x=0; x<256; x++) for(int y=0; y<256; y++) {
|
||||
int flip_y = (y - room_y/2 + 128) & 255;
|
||||
auto& loc = all_locations[y][x];
|
||||
loc.potential = flip_y / 255.;
|
||||
if(flip_y == 0 || flip_y == 255) loc.fixed = true;
|
||||
}
|
||||
|
||||
int it = 0;
|
||||
while(true) {
|
||||
ld err = 0;
|
||||
for(int y=0; y<256; y++) for(int x=0; x<256; x++) {
|
||||
auto& loc = all_locations[y][x];
|
||||
if(loc.fixed) continue;
|
||||
ld pot = (loc.get(0).potential + loc.get(1).potential + loc.get(2).potential + loc.get(3).potential) / 4;
|
||||
err += abs(pot - loc.potential);
|
||||
loc.potential = pot;
|
||||
}
|
||||
it++;
|
||||
if(err < 1e-2) break;
|
||||
}
|
||||
}
|
||||
|
||||
auto portal_chk = arg::add3("-nonh", load_nonhyperbolic);
|
||||
}
|
125
rogueviz/ru/powers.cpp
Normal file
125
rogueviz/ru/powers.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
flagtype STARTING = Flag(1);
|
||||
flagtype WHILE_PAUSED = Flag(2);
|
||||
|
||||
vector<power> powers = {
|
||||
power('1', "Potion of Extra Life",
|
||||
"You are really proud of this potion, which, after you die, will let you return to the moment of time when you drank it. "
|
||||
"Unfortunately it still requires an ingredient found only in the magical fountains of the Dungeons of Alchemy.\n\n"
|
||||
"You can only drink this potion when at a magical fountain. To protect yourself from dying permanently, it is drank "
|
||||
"automatically whenever you are at a magical fountain.",
|
||||
"!", 0xFFFF00FF, STARTING,
|
||||
[] (data& d) { }
|
||||
),
|
||||
|
||||
power('d', "move right",
|
||||
"A special power of human beings, and most other animals, that they earn early in their life.",
|
||||
">", 0xFF0000FF, STARTING,
|
||||
[] (data& d) { if(d.keystate & 1) d.dx += 1; }
|
||||
),
|
||||
|
||||
power('a', "move left",
|
||||
"Moving to the right was a mistake? If so, this special power can be used to ignore the consequences. In most cases, at least...",
|
||||
"<", 0xFF0000FF, STARTING,
|
||||
[] (data& d) { if(d.keystate & 1) d.dx -= 1; }
|
||||
),
|
||||
|
||||
power('w', "jump",
|
||||
"This power can be used to reach higher parts of the world. Its power is quite limited compared to move left and right, but "
|
||||
"you expect to find some ways to make it more powerful.",
|
||||
"^", 0xFF0000FF, STARTING,
|
||||
[] (data& d) {
|
||||
if((d.keystate & 1) && m.on_floor) m.vel_y = -(non_hyperbolic ? 3 : 5) * d.d * d.modv;
|
||||
}
|
||||
),
|
||||
|
||||
power('s', "fall",
|
||||
"If you are on a platform, this ability can be used to drop down.",
|
||||
"v", 0xFF0000FF, STARTING,
|
||||
[] (data& d) {
|
||||
m.fallthru = (d.keystate & 1);
|
||||
}
|
||||
),
|
||||
|
||||
power('p', "pause",
|
||||
"Becoming an alchemist requires intelligence: thinking quickly to react to surprising effects of experiments. "
|
||||
"To reflect this, you can use this power at any time to give yourself more time to think about the situation.",
|
||||
"-", 0xFF0000FF, STARTING | WHILE_PAUSED,
|
||||
[] (data& d) {
|
||||
if(d.keystate == 1) cmode = mode::paused;
|
||||
}),
|
||||
|
||||
power(' ', "dagger",
|
||||
"This sharp dagger is very useful during the preparation of alchemical ingredients, but it works as a basic weapon too.",
|
||||
")", 0xFFFFFFFF, 0,
|
||||
[] (data& d) {
|
||||
if(d.keystate != 1) return;
|
||||
m.attack_facing = m.facing; m.attack_when = gframeid;
|
||||
auto bb = pixel_to_block(m.get_pixel_bbox_at(m.where_x + m.attack_facing * m.dsx(), m.where_y));
|
||||
for(int y=bb.miny; y<bb.maxy; y++)
|
||||
for(int x=bb.minx; x<bb.maxx; x++) {
|
||||
int b = current_room->at(x, y);
|
||||
if(b == wDoor) {
|
||||
current_room->replace_block(x, y, wSmashedDoor);
|
||||
addMessage("You smash the door!");
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
power('o', "Poincaré's Crystal Ball",
|
||||
"This crystal ball will not let you predict the future or see things elsewhere, but will let you easily map the "
|
||||
"parts of the world you have seen so far. This artifact is rumored to have been actually created by Beltrami, but "
|
||||
"it was bought and presented to people by the famous wizard Poincaré, and people thought it was Poincaré's creation.",
|
||||
"o", 0x00FF00FF, WHILE_PAUSED,
|
||||
[] (data& d) {
|
||||
if(d.keystate != 1) return;
|
||||
switch_mapmode_to(cmapmode == mapmode::poincare ? mapmode::standard : mapmode::poincare);
|
||||
}
|
||||
),
|
||||
|
||||
power('b', "Beltrami's Crystal Ball",
|
||||
"Created by the ancient wizard Beltrami, this crystal ball will not let you predict the future or see things elsewhere, "
|
||||
"but will let you easily map the parts of the world you have seen so far. Contrary to Poincaré's ball, straight lines are "
|
||||
"mapped faithfully.",
|
||||
"o", 0x00FFFFFF, WHILE_PAUSED,
|
||||
[] (data& d) {
|
||||
if(d.keystate != 1) return;
|
||||
switch_mapmode_to(cmapmode == mapmode::klein ? mapmode::standard : mapmode::klein);
|
||||
}
|
||||
),
|
||||
|
||||
};
|
||||
|
||||
void handle_powers(data& d) {
|
||||
for(auto& p: powers) {
|
||||
if(cmode == mode::paused && !(p.flags & WHILE_PAUSED)) continue;
|
||||
d.keystate = 0;
|
||||
if(keyheld(p.key)) d.keystate |= 1;
|
||||
if(keywasheld(p.key)) d.keystate |= 2;
|
||||
p.pf(d);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_inventory() {
|
||||
initquickqueue();
|
||||
for(int a: {0, 1, 3, 2, 0})
|
||||
curvepoint(hyperpoint((a&1)?16:screen_x-16, (a&2)?16:screen_y-16, 1, 0));
|
||||
queuecurve(scrm, 0xFFFFFFFF, 0x000000E0, PPR::LINE);
|
||||
quickqueue();
|
||||
int sy = 200 * vid.yres / 1440;
|
||||
int sx = 100 * vid.xres / 2560;
|
||||
auto st = vid.fsize * 1.2;
|
||||
displaystr(sx, sy, 0, vid.fsize, "Your inventory:", 0xC0C0C0, 0);
|
||||
int lineid = 2;
|
||||
for(auto& p: powers) {
|
||||
string s = ""; s += dialog::keyname(p.key);
|
||||
s += " ";
|
||||
s += p.glyph;
|
||||
s += " ";
|
||||
s += p.name;
|
||||
displaystr(sx, sy + st * (lineid++), 0, vid.fsize, s, p.color >> 8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
288
rogueviz/ru/render.cpp
Normal file
288
rogueviz/ru/render.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
shiftmatrix scrm;
|
||||
|
||||
void prepare_tinf() {
|
||||
|
||||
auto add_vertex = [&] (double bx, double by) {
|
||||
roomtinf.tvertices.push_back(glhr::makevertex(bx / screen_x, 1 - by / screen_y, 0));
|
||||
cgi.hpc.push_back(to_hyper(bx, by));
|
||||
};
|
||||
|
||||
cgi.bshape(roomshape, PPR::WALL);
|
||||
for(int by=t_margin_at; by<b_margin_at; by+=block_y)
|
||||
for(int bx=l_margin_at; bx<r_margin_at; bx+=block_x) {
|
||||
add_vertex(bx, by);
|
||||
add_vertex(bx+block_x, by);
|
||||
add_vertex(bx+block_x, by+block_y);
|
||||
add_vertex(bx, by);
|
||||
add_vertex(bx, by+block_y);
|
||||
add_vertex(bx+block_x, by+block_y);
|
||||
}
|
||||
cgi.last->flags |= POLY_TRIANGLES;
|
||||
cgi.last->tinf = &roomtinf;
|
||||
cgi.last->texture_offset = 0;
|
||||
|
||||
int q = isize(roomtinf.tvertices);
|
||||
|
||||
cgi.bshape(roomshape_big, PPR::WALL_TOP);
|
||||
for(int by=0; by<screen_y; by+=block_y)
|
||||
for(int bx=0; bx<screen_x; bx+=block_x) {
|
||||
add_vertex(bx, by);
|
||||
add_vertex(bx+block_x, by);
|
||||
add_vertex(bx+block_x, by+block_y);
|
||||
add_vertex(bx, by);
|
||||
add_vertex(bx, by+block_y);
|
||||
add_vertex(bx+block_x, by+block_y);
|
||||
}
|
||||
cgi.last->flags |= POLY_TRIANGLES;
|
||||
cgi.last->tinf = &roomtinf;
|
||||
cgi.last->texture_offset = q;
|
||||
|
||||
cgi.finishshape();
|
||||
cgi.extra_vertices();
|
||||
|
||||
println(hlog, "sizes: ", tuple(roomshape_big.e - roomshape_big.s, roomshape.e - roomshape.s));
|
||||
}
|
||||
|
||||
void room::create_texture() {
|
||||
/* if(room_texture) return;
|
||||
room_texture = new texture::texture_data;
|
||||
|
||||
auto& tex = *room_texture;
|
||||
|
||||
tex.twidth = tex.theight = 256;
|
||||
|
||||
tex.tx = screen_x;
|
||||
tex.ty = screen_y;
|
||||
tex.stretched = false;
|
||||
tex.strx = tex.tx;
|
||||
tex.stry = tex.ty;
|
||||
tex.base_x = 0;
|
||||
tex.base_y = (tex.theight - tex.ty) / 2; */
|
||||
|
||||
if(rbuf) return;
|
||||
rbuf = new renderbuffer(screen_x, screen_y, true);
|
||||
}
|
||||
|
||||
struct dqi_poly_tex : dqi_poly {
|
||||
int texture_id;
|
||||
void draw() override { if(tinf) tinf->texture_id = texture_id; dqi_poly::draw(); }
|
||||
};
|
||||
|
||||
basic_textureinfo sprite_vertices;
|
||||
|
||||
void render_room(room *r);
|
||||
|
||||
bool draw_room_on_map(cell *c, const shiftmatrix& V) {
|
||||
hr::addaura(tC0(V), pconf.alpha == 1 ? 0xFF00FF00 : 0xFF00FFFF, 0);
|
||||
if(!rooms.count(c)) {
|
||||
c->landparam = 0x101010;
|
||||
get_room_at(c);
|
||||
return false;
|
||||
}
|
||||
auto& r = rooms[c];
|
||||
if(!r.rbuf || &r == current_room || r.which_map_rendered != should_apply_fov() || r.need_rerender) {
|
||||
vector<unique_ptr<drawqueueitem>> alt_ptds;
|
||||
swap(ptds, alt_ptds);
|
||||
render_room(&r);
|
||||
swap(ptds, alt_ptds);
|
||||
calcparam();
|
||||
}
|
||||
if(!r.rbuf) return false;
|
||||
|
||||
bool big = (&r == current_room);
|
||||
auto& sh = big ? roomshape_big : roomshape;
|
||||
auto& p = queuea<dqi_poly_tex> (sh.prio);
|
||||
p.V = V;
|
||||
p.offset = sh.s;
|
||||
p.cnt = sh.e - sh.s;
|
||||
p.color = 0xFFFFFFFF;
|
||||
p.tab = &cgi.ourshape;
|
||||
p.flags = sh.flags;
|
||||
p.tinf = &roomtinf;
|
||||
p.tinf->texture_id = r.rbuf->renderedTexture;
|
||||
p.offset_texture = sh.texture_offset;
|
||||
p.texture_id = r.rbuf->renderedTexture;
|
||||
|
||||
if(big || cmode == mode::editmap) {
|
||||
dynamicval<color_t> po(poly_outline, 0x80FF80FF);
|
||||
queuepolyat(V, cgi.shFullFloor.b[0], 0, PPR::LINE);
|
||||
}
|
||||
|
||||
// render_room_objects(&r, render_at);
|
||||
return true;
|
||||
}
|
||||
|
||||
void asciiletter(ld minx, ld miny, ld maxx, ld maxy, const string& ch, color_t col);
|
||||
|
||||
void compute_scrm() {
|
||||
ld tx = screen_x;
|
||||
ld ty = screen_y;
|
||||
ld scalex = (vid.xres/2) / (current_display->radius * tx);
|
||||
ld scaley = (vid.yres/2) / (current_display->radius * ty);
|
||||
ld scale = min(scalex, scaley);
|
||||
scale *= 4;
|
||||
|
||||
scrm = shiftless(Id);
|
||||
scrm.T[0][2] = (- screen_x/2) * scale;
|
||||
scrm.T[1][2] = (- screen_y/2) * scale;
|
||||
scrm.T[0][0] = scale;
|
||||
scrm.T[1][1] = scale;
|
||||
scrm.T[2][2] = 1;
|
||||
}
|
||||
|
||||
void render_room_walls(room *r) {
|
||||
initquickqueue();
|
||||
bool af = should_apply_fov();
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++) {
|
||||
if(af && !r->fov[y][x]) continue;
|
||||
char c = r->block_at[y][x];
|
||||
|
||||
// ld sx = 1.5;
|
||||
// ld sy = 1.3;
|
||||
|
||||
int cc = c >> 3;
|
||||
|
||||
if((c & 7) == 0)
|
||||
asciiletter(x*block_x, y*block_y, (x+1)*block_x, (y+1)*block_y, walls[cc].glyph, walls[cc].color);
|
||||
|
||||
if((c & 7) == 4)
|
||||
asciiletter(x*block_x, y*block_y, (x+2)*block_x, (y+2)*block_y, walls[cc].glyph, walls[cc].color);
|
||||
|
||||
if(gravision) {
|
||||
int minx = x*block_x, maxx = (x+1)*block_x;
|
||||
int miny = y*block_y, maxy = (y+1)*block_y;
|
||||
for(int a: {0, 1, 3, 2, 0})
|
||||
curvepoint(hyperpoint((a&1)?minx:maxx, (a&2)?miny:maxy, 1, 0));
|
||||
color_t r = rainbow_color(1, all_locations[y][x].potential * 30);
|
||||
r <<= 8;
|
||||
queuecurve(scrm, r | 0xFF, r | 0x80, PPR::LINE);
|
||||
}
|
||||
}
|
||||
quickqueue();
|
||||
}
|
||||
|
||||
void render_room(room *r) {
|
||||
r->create_texture();
|
||||
|
||||
resetbuffer rb;
|
||||
r->rbuf->enable();
|
||||
|
||||
dynamicval<videopar> v(vid, vid);
|
||||
vid.xres = r->rbuf->tx;
|
||||
vid.yres = r->rbuf->ty;
|
||||
calcparam();
|
||||
|
||||
current_display->set_viewport(0);
|
||||
r->rbuf->clear(0xFF000000);
|
||||
|
||||
flat_model_enabler fme;
|
||||
compute_scrm();
|
||||
|
||||
render_room_walls(r);
|
||||
render_room_objects(r);
|
||||
|
||||
rb.reset();
|
||||
r->which_map_rendered = should_apply_fov();
|
||||
r->need_rerender = false;
|
||||
GLERR("render_room");
|
||||
}
|
||||
|
||||
transmatrix letterscales[128];
|
||||
|
||||
void init_scales() {
|
||||
for(int i=0; i<128; i++) letterscales[i] = Id;
|
||||
letterscales['#'] = euscale(1.5, 1.2);
|
||||
letterscales['*'] = eupush(0, 0.4) * euscale(1.5, 2);
|
||||
letterscales['~'] = eupush(0, -0.4) * euscale(1.5, 1.2);
|
||||
letterscales[')'] = euscale(2.5, 1);
|
||||
letterscales['('] = euscale(2.5, 1);
|
||||
}
|
||||
|
||||
void asciiletter(ld minx, ld miny, ld maxx, ld maxy, const string& ch, color_t col) {
|
||||
ld medx = (minx + maxx) / 2;
|
||||
ld medy = (miny + maxy) / 2;
|
||||
write_in_space(scrm * eupush(medx, medy) * euscale(maxx-minx, maxy-miny) * letterscales[int(ch[0])],
|
||||
max_glfont_size, 2, ch, col, 0, 8, PPR::TEXT, rupf);
|
||||
|
||||
if(anyshiftclick) {
|
||||
for(int a: {0, 1, 3, 2, 0})
|
||||
curvepoint(hyperpoint((a&1)?minx:maxx, (a&2)?miny:maxy, 1, 0));
|
||||
queuecurve(scrm, 0xFF0000FF, 0xFF000080, PPR::LINE);
|
||||
}
|
||||
}
|
||||
|
||||
void entity::draw() {
|
||||
|
||||
double d = get_scale();
|
||||
|
||||
gwhere_x = where_x; gwhere_y = where_y;
|
||||
|
||||
ld minx = min(where_x, gwhere_x) - sx() * d / 2;
|
||||
ld miny = min(where_y, gwhere_y) - sy() * d / 2;
|
||||
ld maxx = max(where_x, gwhere_x) + sx() * d / 2;
|
||||
ld maxy = max(where_y, gwhere_y) + sy() * d / 2;
|
||||
|
||||
asciiletter(minx, miny, maxx, maxy, glyph(), color());
|
||||
}
|
||||
|
||||
void man::draw() {
|
||||
entity::draw();
|
||||
|
||||
ld t = gframeid - attack_when;
|
||||
if(t < 50) {
|
||||
auto af = attack_facing * (1 - t * 0.01);
|
||||
asciiletter(
|
||||
where_x + af * dsx() - dsx()/2, where_y - dsy()/2,
|
||||
where_x + af * dsx() + dsx()/2, where_y + dsy()/2,
|
||||
attack_facing == -1 ? "(" : ")", 0xFFFFFF00 + (255 - t * 5)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void render_room_objects(room *r) {
|
||||
initquickqueue();
|
||||
if(r == current_room) m.draw();
|
||||
for(auto& e: r->entities) e->draw();
|
||||
quickqueue();
|
||||
}
|
||||
|
||||
int mousepx, mousepy;
|
||||
|
||||
void draw_room() {
|
||||
flat_model_enabler fme;
|
||||
|
||||
compute_scrm();
|
||||
|
||||
if(false) {
|
||||
basic_textureinfo bti;
|
||||
bti.texture_id = current_room->rbuf->renderedTexture;
|
||||
|
||||
ld cx[6] = {1,0,0,0,1,1};
|
||||
ld cy[6] = {1,1,0,0,0,1};
|
||||
|
||||
for(int i=0; i<6; i++) {
|
||||
bti.tvertices.emplace_back(glhr::makevertex(cx[i], 1 - cy[i], 0));
|
||||
curvepoint(eupoint(cx[i] * screen_x, cy[i] * screen_y));
|
||||
}
|
||||
|
||||
initquickqueue();
|
||||
auto& q = queuecurve(scrm, 0xFFFFFFFF, 0xFFFFFFFF, PPR::LINE);
|
||||
q.tinf = &bti; q.flags |= POLY_TRIANGLES; q.offset_texture = 0;
|
||||
quickqueue();
|
||||
}
|
||||
if(true) {
|
||||
render_room_walls(current_room);
|
||||
}
|
||||
|
||||
render_room_objects(current_room);
|
||||
|
||||
ld& scale = scrm.T[0][0];
|
||||
|
||||
mousepx = (mousex - current_display->xcenter) * 2 / scale / current_display->radius + screen_x/2;
|
||||
mousepy = (mousey - current_display->ycenter) * 2 / scale / current_display->radius + screen_y/2;
|
||||
}
|
||||
|
||||
}
|
144
rogueviz/ru/room.cpp
Normal file
144
rogueviz/ru/room.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
void room::place_block_full(int x, int y, int b) {
|
||||
need_rerender = true;
|
||||
indenter ind(2);
|
||||
infile = true;
|
||||
|
||||
if(x < 0 || y < 0 || x >= room_x || y >= room_y) return;
|
||||
if(b < 8) b = 0;
|
||||
if((b & 4) && (x&1) != (b&1)) x--;
|
||||
if((b & 4) && (2*(y&1)) != (b&2)) y--;
|
||||
if(y < t_margin && (b&4)) return;
|
||||
if(y > room_y - b_margin && !(b&4) && b) return;
|
||||
if(block_at[y][x] == b) return;
|
||||
|
||||
block_at[y][x] = b;
|
||||
if(b & 4) {
|
||||
place_block_full(x^1, y, b^1);
|
||||
place_block_full(x, y^1, b^2);
|
||||
}
|
||||
else {
|
||||
if(block_at[y][x^1] & 4)
|
||||
place_block_full(x^1, y, 0);
|
||||
if(block_at[y^1][x] & 4)
|
||||
place_block_full(x, y^1, 0);
|
||||
}
|
||||
|
||||
auto& nonh = non_hyperbolic;
|
||||
if(x < lr_margin)
|
||||
get_adjacent(this, nonh ? 2 : 2)->place_block_full(x + room_x - lr_margin, y, b);
|
||||
if(x >= room_x - lr_margin)
|
||||
get_adjacent(this, nonh ? 0 : 4)->place_block_full(x - room_x + lr_margin, y, b);
|
||||
if(y < t_margin) {
|
||||
if(nonh) {
|
||||
get_adjacent(this, 1)->place_block_full(x, y - room_y + t_margin, b);
|
||||
}
|
||||
else if(x < room_x / 2) {
|
||||
get_adjacent(this, 1)->place_block_full((x - lr_margin/2) * 2 + lr_margin/2, room_y - b_margin + 2*y, b^4);
|
||||
}
|
||||
else {
|
||||
get_adjacent(this, 0)->place_block_full((x - room_x/2) * 2 + lr_margin/2, room_y - b_margin + 2*y, b^4);
|
||||
}
|
||||
}
|
||||
|
||||
if(y >= room_y - b_margin && !nonh) {
|
||||
bool r = is_right(this);
|
||||
x -= lr_margin/2;
|
||||
x /= 2;
|
||||
x += (r ? room_x/2 : lr_margin/2);
|
||||
y = y - room_y + b_margin;
|
||||
y /= 2;
|
||||
b &= ~3;
|
||||
get_adjacent(this, 3)->place_block_full(x, y, b ^ 4);
|
||||
}
|
||||
|
||||
if(y >= room_y - t_margin && nonh) {
|
||||
get_adjacent(this, 1)->place_block_full(x, y + room_y - t_margin, b);
|
||||
}
|
||||
}
|
||||
|
||||
void room::generate() {
|
||||
clear();
|
||||
place_small(0, 0);
|
||||
place_small(room_x/2-1, 0);
|
||||
place_small(room_x/2, 0);
|
||||
place_small(room_x-1, 0);
|
||||
place_big(0, room_y-2);
|
||||
place_big(room_x-2, room_y-2);
|
||||
|
||||
/*
|
||||
for(int x=0; x<room_x; x+=2)
|
||||
if(hrand(100) < 10)
|
||||
place_big(x, room_y-2);
|
||||
|
||||
for(int x=0; x<room_x; x++)
|
||||
if(hrand(100) < 10)
|
||||
place_small(x, 0); */
|
||||
|
||||
for(int y=2; y<room_y-2; y+=2)
|
||||
for(int x=2; x<room_x-2; x+=2)
|
||||
if(hrand(room_y * 8) < y)
|
||||
place_big(x, y);
|
||||
|
||||
for(int y=2; y<room_y-2; y++)
|
||||
for(int x=2; x<room_x-2; x++)
|
||||
if(block_at[y][x] == 0)
|
||||
if(hrand((room_y) * 8) < y)
|
||||
place_small(x, y);
|
||||
|
||||
for(int y=room_y/2-2; y<room_y/2+2; y++)
|
||||
for(int x=room_x/2-2; x<room_x/2+2; x++)
|
||||
block_at[y][x] = 0;
|
||||
|
||||
infile = false;
|
||||
}
|
||||
|
||||
void room::reveal(int cx, int cy) {
|
||||
if(cx < 0 || cy < 0 || cx >= room_x || cy >= room_y) return;
|
||||
fov[cy][cx] = 1;
|
||||
auto b = block_at[cy][cx];
|
||||
if(b & 4) {
|
||||
if(b&1) cx--;
|
||||
if(b&2) cy--;
|
||||
fov[cy][cx+1] = fov[cy+1][cx] = fov[cy+1][cx+1] = fov[cy][cx] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void room::reveal_around(int cx, int cy) {
|
||||
for(int dx: {-1, 0, 1}) for(int dy: {-1, 0, 1}) reveal(cx+dx, cy+dy);
|
||||
}
|
||||
|
||||
void room::fov_from(int sx, int sy) {
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
if(x == 0 || y == 0 || x == room_x-1 || y == room_y-1) {
|
||||
int len = max(abs(x-sx), abs(y - sy)) * 2;
|
||||
auto sh = to_hyper((sx+0.5)*block_x, (sy+0.5)*block_y);
|
||||
auto th = to_hyper((x+0.5)*block_x, (y+0.5)*block_y);
|
||||
for(int l=0; l<len; l++) {
|
||||
auto h = lerp(sh, th, l * 1. / len);
|
||||
auto xy = from_hyper(h);
|
||||
int cx = int(xy.first / block_x);
|
||||
int cy = int(xy.second / block_y);
|
||||
if(cx < 0 || cy < 0 || cx >= room_x || cy >= room_y) break;
|
||||
if(!(walls[at(cx, cy)].flags & W_TRANS)) break;
|
||||
reveal_around(cx, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
room *get_room_at(cell *c) {
|
||||
bool create = !rooms.count(c);
|
||||
auto& r = rooms[c];
|
||||
if(create) {
|
||||
r.where = c;
|
||||
r.clear();
|
||||
r.initial();
|
||||
c->wall = waNone;
|
||||
c->land = laCanvas;
|
||||
}
|
||||
return &r;
|
||||
}
|
||||
|
||||
}
|
381
rogueviz/ru/ru.cpp
Normal file
381
rogueviz/ru/ru.cpp
Normal file
@ -0,0 +1,381 @@
|
||||
#include "../../rogueviz/rogueviz.h"
|
||||
|
||||
/** \brief Hyperbolic platformer.
|
||||
The implementation of the platformer from https://twitter.com/ZenoRogue/status/1467233150380089345
|
||||
To play, load platformer.lev (e.g. `-load platformer.lev`)
|
||||
Or create a new map by running with options:
|
||||
`-noscr -canvas B -geo dbin -platformer`
|
||||
|
||||
Keys:
|
||||
up/left/right -- move the guy
|
||||
c -- clear the current room (buggy, does not clear parts of the adjacent rooms)
|
||||
g -- generate the current room (buggy)
|
||||
m -- see the map (toggle)
|
||||
p -- pause (toggle)
|
||||
z -- screenshot menu
|
||||
v -- HyperRogue settings
|
||||
q -- quit
|
||||
s -- save to platformer.lev
|
||||
1 -- place a small block under the mouse
|
||||
2 -- place a big block under the mouse
|
||||
3 -- delete the block under the mouse
|
||||
|
||||
Have fun!
|
||||
*/
|
||||
|
||||
#include "globals.cpp"
|
||||
#include "classes.cpp"
|
||||
#include "geometry.cpp"
|
||||
#include "entity.cpp"
|
||||
#include "man.cpp"
|
||||
#include "room.cpp"
|
||||
#include "render.cpp"
|
||||
#include "portals.cpp"
|
||||
#include "powers.cpp"
|
||||
#include "save.cpp"
|
||||
|
||||
namespace rogue_unlike {
|
||||
|
||||
static double gtime = 0;
|
||||
|
||||
bool last_mkey = false;
|
||||
|
||||
extern int mousepx, mousepy;
|
||||
|
||||
void floodfill(int x, int y) {
|
||||
if(x < 0 || y < 0 || x >= room_x || y >= room_y) return;
|
||||
if(current_room->block_at[y][x] != 0) return;
|
||||
current_room->place_block_full(x, y, 8 * sel);
|
||||
floodfill(x+1, y);
|
||||
floodfill(x-1, y);
|
||||
floodfill(x, y+1);
|
||||
floodfill(x, y-1);
|
||||
}
|
||||
|
||||
bool last_keystate[KEYSTATES], cur_keystate[KEYSTATES];
|
||||
|
||||
bool keyheld(int id) { return cur_keystate[id]; }
|
||||
bool keywasheld(int id) { return last_keystate[id]; }
|
||||
bool keypressed(int id) { return cur_keystate[id] && !last_keystate[id]; }
|
||||
|
||||
void update_keystate() {
|
||||
const Uint8 *keystate = SDL12_GetKeyState(NULL);
|
||||
for(int i=0; i<KEYSTATES; i++) last_keystate[i] = cur_keystate[i], cur_keystate[i] = keystate[i];
|
||||
}
|
||||
|
||||
void editmap_frame() {
|
||||
if(keyheld('1'))
|
||||
current_room->place_block_full(mousepx / block_x, mousepy / block_y, 8*sel);
|
||||
if(keyheld('2'))
|
||||
current_room->place_block_full(mousepx / block_x, mousepy / block_y, 8*sel+4);
|
||||
if(keyheld('3'))
|
||||
current_room->place_block_full(mousepx / block_x, mousepy / block_y, 0);
|
||||
if(keypressed('4')) pushScreen([] {
|
||||
dialog::init();
|
||||
dialog::addTitle("what to add", 0x4040C0, 150);
|
||||
for(int i=1; i<qwall; i++) {
|
||||
dialog::addItem(walls[i].name, 'a'+i);
|
||||
dialog::add_action([i] { sel = i; popScreen(); });
|
||||
}
|
||||
dialog::display();
|
||||
});
|
||||
if(keypressed('f')) floodfill(mousepx / block_x, mousepy / block_y);
|
||||
}
|
||||
|
||||
void playing_frame() {
|
||||
m.act();
|
||||
|
||||
auto& ents = current_room->entities;
|
||||
|
||||
for(auto& e: ents) e->act();
|
||||
|
||||
auto mb = ents.begin();
|
||||
for(auto& e: ents) if(!e->destroyed) *(mb++) = std::move(e);
|
||||
ents.resize(mb - ents.begin());
|
||||
|
||||
auto& nonh = non_hyperbolic;
|
||||
if(one_room) return;
|
||||
|
||||
if(m.where_x < l_margin_at) {
|
||||
m.where_x += actual_screen_x;
|
||||
switch_to_adjacent_room(2);
|
||||
m.clearg();
|
||||
}
|
||||
if(m.where_x > r_margin_at) {
|
||||
m.where_x -= actual_screen_x;
|
||||
switch_to_adjacent_room(nonh ? 0 : 4);
|
||||
m.clearg();
|
||||
}
|
||||
|
||||
if(m.where_y < t_margin_at && !nonh) {
|
||||
m.where_y = (m.where_y - t_margin_at) * 2 + b_margin_at;
|
||||
m.where_x -= l_margin_at;
|
||||
m.where_x = 2 * m.where_x;
|
||||
if(m.where_x > actual_screen_x) {
|
||||
m.where_x -= actual_screen_x;
|
||||
switch_to_adjacent_room(0);
|
||||
}
|
||||
else
|
||||
switch_to_adjacent_room(1);
|
||||
m.where_x += l_margin_at;
|
||||
m.vel_x *= 2; m.vel_y *= 2;
|
||||
m.clearg();
|
||||
}
|
||||
if(m.where_y > b_margin_at && !nonh) {
|
||||
m.where_x -= l_margin_at;
|
||||
m.where_y -= b_margin_at;
|
||||
m.where_y /= 2;
|
||||
m.where_y += t_margin_at;
|
||||
if(is_right(current_room))
|
||||
m.where_x += actual_screen_x;
|
||||
switch_to_adjacent_room(3);
|
||||
m.where_x /= 2;
|
||||
m.where_x += l_margin_at;
|
||||
m.vel_x /= 2; m.vel_y /= 2;
|
||||
m.clearg();
|
||||
}
|
||||
}
|
||||
|
||||
void sync_map() {
|
||||
for(auto& p: rooms)
|
||||
if(&p.second == current_room)
|
||||
centerover = p.first;
|
||||
View = cspin90(1, 0);
|
||||
// if(cmode == mode::playing) View = View * inverse(parabolic13_at(to_hyper(m.where_x, m.where_y)));
|
||||
if(cmode == mode::playing) {
|
||||
hyperpoint p = to_hyper(m.where_x, m.where_y);
|
||||
transmatrix T = iso_inverse(parabolic13_at(deparabolic13(p)));
|
||||
View = View * T;
|
||||
}
|
||||
}
|
||||
|
||||
void switch_mapmode_to(mapmode m) {
|
||||
cmapmode = m;
|
||||
switch(cmapmode) {
|
||||
case mapmode::standard:
|
||||
nomap = true;
|
||||
break;
|
||||
case mapmode::poincare:
|
||||
case mapmode::klein:
|
||||
sync_map();
|
||||
pconf.scale = 0.95;
|
||||
pconf.alpha = cmapmode == mapmode::poincare ? 1 : 0;
|
||||
pmodel = mdDisk;
|
||||
nomap = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void render_the_map() {
|
||||
switch(cmapmode) {
|
||||
case mapmode::standard:
|
||||
emptyscreen();
|
||||
render_room(current_room);
|
||||
draw_room();
|
||||
drawmessages();
|
||||
nomsg = false;
|
||||
dialog::add_key_action('v', [] { cmode = mode::menu; });
|
||||
break;
|
||||
case mapmode::poincare:
|
||||
case mapmode::klein:
|
||||
gamescreen();
|
||||
if(cmode == mode::editmap) {
|
||||
getcstat = '-';
|
||||
dialog::add_key_action('-', [] { if(!mouseover) return; current_room = &rooms[mouseover]; switch_mapmode_to(mapmode::standard); });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void run() {
|
||||
// clearMessages();
|
||||
dialog::init();
|
||||
|
||||
switch(cmode) {
|
||||
case mode::editmap:
|
||||
case mode::playing:
|
||||
case mode::paused:
|
||||
if(cmode == mode::playing) sync_map();
|
||||
render_the_map();
|
||||
if(cmode == mode::editmap) dialog::add_key_action('p', [] { println(hlog, "p pressed"); switch_mapmode_to(mapmode::poincare); });
|
||||
if(cmode == mode::editmap) mouseovers = format("coordinates: %d %d", mousepx, mousepy);
|
||||
break;
|
||||
|
||||
case mode::inventory:
|
||||
render_the_map();
|
||||
draw_inventory();
|
||||
dialog::add_key_action('v', [] { cmode = mode::menu; });
|
||||
break;
|
||||
|
||||
case mode::menu:
|
||||
nomap = true;
|
||||
emptyscreen();
|
||||
dialog::init();
|
||||
dialog::addTitle("Fountains of Alchemy", 0x4040C0, 150);
|
||||
dialog::addItem("return to game", 'v');
|
||||
dialog::add_action([] { cmode = mode::playing; });
|
||||
|
||||
dialog::addItem("inventory", 'i');
|
||||
dialog::add_action([] { cmode = mode::inventory; });
|
||||
|
||||
dialog::addItem("map editor", 'e');
|
||||
dialog::add_action([] { cmode = mode::editmap; });
|
||||
|
||||
dialog::addItem("screenshot", 'z');
|
||||
dialog::add_action([] { pushScreen(shot::menu); });
|
||||
|
||||
dialog::addItem("save to editmap.ru", 's');
|
||||
dialog::add_key_action('s', [] {
|
||||
save_map("rogueviz/ru/editmap.ru");
|
||||
});
|
||||
|
||||
dialog::display();
|
||||
break;
|
||||
}
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
if(among(cmode, mode::paused, mode::editmap) && cmapmode != mapmode::standard)
|
||||
handlePanning(sym, uni);
|
||||
dialog::handleNavigation(sym, uni);
|
||||
};
|
||||
}
|
||||
|
||||
void add_platf_hooks();
|
||||
|
||||
void set_sval() {
|
||||
|
||||
ld s_min = 10, s_max = 1200;
|
||||
|
||||
for(int it=0; it<100; it++) {
|
||||
mscale = sqrt(s_min * s_max);
|
||||
hyperpoint atop = deparabolic13(to_hyper(0, t_margin_at));
|
||||
if(atop[0] < -log(2)/2) s_max = mscale;
|
||||
else s_min = mscale;
|
||||
}
|
||||
}
|
||||
|
||||
void enable() {
|
||||
|
||||
stop_game();
|
||||
|
||||
set_sval();
|
||||
init_scales();
|
||||
|
||||
hyperpoint aleft = deparabolic13(to_hyper(l_margin_at, yctr));
|
||||
hyperpoint aright = deparabolic13(to_hyper(r_margin_at, yctr));
|
||||
|
||||
vid.binary_width = abs(aright[1] - aleft[1]) / log(2);
|
||||
|
||||
start_game();
|
||||
cgi.prepare_shapes();
|
||||
|
||||
current_room = get_room_at(cwt.at);
|
||||
|
||||
prepare_tinf();
|
||||
|
||||
add_platf_hooks();
|
||||
load_map("rogueviz/ru/map.ru");
|
||||
switch_mapmode_to(mapmode::standard);
|
||||
}
|
||||
|
||||
void add_platf_hooks() {
|
||||
|
||||
rogueviz::rv_hook(hooks_prestats, 90, [=] {
|
||||
|
||||
if(nomap)
|
||||
draw_room();
|
||||
else
|
||||
render_room(current_room);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
rogueviz::rv_hook(hooks_resetGL, 90, [=] {
|
||||
for(auto& [w, r]: rooms) if(r.rbuf) { delete r.rbuf; r.rbuf = nullptr; }
|
||||
});
|
||||
|
||||
rogueviz::rv_hook(shmup::hooks_turn, 90, [=] (int d) {
|
||||
gtime += d;
|
||||
while(gtime > 1000. / game_fps) {
|
||||
gtime -= 1000. / game_fps;
|
||||
|
||||
gframeid++;
|
||||
update_keystate();
|
||||
|
||||
switch(cmode) {
|
||||
case mode::editmap:
|
||||
editmap_frame();
|
||||
break;
|
||||
|
||||
case mode::playing:
|
||||
playing_frame();
|
||||
break;
|
||||
|
||||
case mode::paused:
|
||||
data d;
|
||||
handle_powers(d);
|
||||
break;
|
||||
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
rogueviz::rv_hook(hooks_drawcell, 90, draw_room_on_map);
|
||||
|
||||
rogueviz::rv_hook(mapstream::hooks_savemap, 100, [] (hstream& f) {
|
||||
f.write<int>(67);
|
||||
for(auto& p: rooms) {
|
||||
f.write(mapstream::cellids[p.first]);
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
f.write(p.second.block_at[y][x]);
|
||||
f.write<int>(0);
|
||||
}
|
||||
f.write<int>(-1);
|
||||
f.write(mapstream::cellids[current_room->where]);
|
||||
f.write(m.where_x);
|
||||
f.write(m.where_y);
|
||||
f.write(m.vel_x);
|
||||
f.write(m.vel_y);
|
||||
});
|
||||
|
||||
pushScreen(run);
|
||||
}
|
||||
|
||||
auto chk = arg::add3("-ru", enable)
|
||||
+ addHook(mapstream::hooks_loadmap, 100, [] (hstream& f, int id) {
|
||||
if(id == 67) {
|
||||
println(hlog, "loading platformer");
|
||||
while(true) {
|
||||
int i = f.get<int>();
|
||||
if(i == -1) break;
|
||||
auto r = get_room_at(mapstream::cellbyid[i]);
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++)
|
||||
f.read(r->block_at[y][x]);
|
||||
r->clearfov();
|
||||
r->infile = true;
|
||||
f.get<int>();
|
||||
}
|
||||
int id = f.get<int>();
|
||||
current_room = get_room_at(mapstream::cellbyid[id]);
|
||||
f.read(m.where_x);
|
||||
f.read(m.where_y);
|
||||
f.read(m.vel_x);
|
||||
f.read(m.vel_y);
|
||||
add_platf_hooks();
|
||||
println(hlog, "done");
|
||||
set_sval();
|
||||
|
||||
cgi.prepare_shapes();
|
||||
prepare_tinf();
|
||||
init_scales();
|
||||
|
||||
cmode = mode::playing;
|
||||
println(hlog, "set mode to playing");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
142
rogueviz/ru/save.cpp
Normal file
142
rogueviz/ru/save.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
map<cell*, int> in_queue;
|
||||
|
||||
queue<cell*> q;
|
||||
|
||||
void visit(cell *c, int d) {
|
||||
if(in_queue.count(c)) return;
|
||||
in_queue[c] = d;
|
||||
q.push(c);
|
||||
}
|
||||
|
||||
void save_map(string fname) {
|
||||
in_queue.clear();
|
||||
q = {};
|
||||
visit(currentmap->gamestart(), -1);
|
||||
|
||||
fhstream f(fname, "w");
|
||||
|
||||
while(!q.empty()) {
|
||||
auto c = q.front();
|
||||
q.pop();
|
||||
auto& r = rooms[c];
|
||||
if(!r.infile) continue;
|
||||
auto inq = in_queue[c];
|
||||
if(inq != -1) {
|
||||
println(f, "MOVE ", c->c.spin(inq), " ", rooms[c->move(inq)].roomname);
|
||||
}
|
||||
println(f, "ROOM ", r.roomname);
|
||||
|
||||
map<int, char> code_for;
|
||||
map<char, int> code_used;
|
||||
char next_code = 'A';
|
||||
|
||||
for(int y=0; y<room_y; y++)
|
||||
for(int x=0; x<room_x; x++) {
|
||||
auto i = r.block_at[y][x] >> 3;
|
||||
auto& c = code_for[i];
|
||||
if(c == 0 && !code_used.count(walls[i].glyph[0])) c = walls[i].glyph[0];
|
||||
if(c == 0) c = next_code++;
|
||||
code_used[c] = i;
|
||||
}
|
||||
|
||||
for(auto [key, id]: code_used) println(f, format("%c", key), " ", walls[id].name);
|
||||
|
||||
println(f, "MAP");
|
||||
|
||||
for(int y=0; y<room_y; y++) {
|
||||
for(int x=0; x<room_x; x++) {
|
||||
auto v = r.block_at[y][x];
|
||||
print(f, format("%c", (v & 7) == 7 ? 'b' : code_for[v>>3]));
|
||||
}
|
||||
println(f);
|
||||
}
|
||||
|
||||
println(f, "OK\n");
|
||||
|
||||
for(int i=0; i<c->type; i++) visit(c->cmove(i), c->c.spin(i));
|
||||
}
|
||||
}
|
||||
|
||||
void err(string s, string context) {
|
||||
println(hlog, "while: ", context, " reading: ", s);
|
||||
throw hr_exception("ru read error");
|
||||
}
|
||||
|
||||
void load_room(fhstream& f, cell *c) {
|
||||
setdist(c, 7, nullptr);
|
||||
auto& r = *get_room_at(c);
|
||||
string s = scanline_noblank(f);
|
||||
if(s.substr(0, 5) == "ROOM ") r.roomname = s.substr(5);
|
||||
else err("load_room name ", s);
|
||||
println(hlog, "loading room named: ", r.roomname);
|
||||
map<char, int> codes;
|
||||
while(true) {
|
||||
string s = scanline_noblank(f);
|
||||
if(s == "") continue;
|
||||
if(s == "MAP") break;
|
||||
string t = s.substr(2);
|
||||
if(s.size() < 3 || s[1] != ' ') err("load codes", s);
|
||||
for(int i=0; i<qwall; i++) if(walls[i].name == t) {
|
||||
codes[s[0]] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(1) {
|
||||
vector<string> bmap;
|
||||
for(int y=0; y<room_y; y++) bmap.push_back(scanline_noblank(f));
|
||||
for(int y=0; y<room_y; y++) for(int x=0; x<room_x; x++) {
|
||||
if(bmap[y][x] == 'b') ;
|
||||
else if(y < room_y-1 && bmap[y+1][x] == 'b') ;
|
||||
else if(x < room_x-1 && bmap[y][x+1] == 'b') ;
|
||||
else if(y < room_y-1 && x < room_x-1 && bmap[y+1][x+1] == 'b')
|
||||
r.place_block_full(x, y, 8 * codes.at(bmap[y][x]) + 4);
|
||||
else
|
||||
r.place_block_full(x, y, 8 * codes.at(bmap[y][x]));
|
||||
}
|
||||
}
|
||||
while(true) {
|
||||
s = scanline_noblank(f);
|
||||
if(s == "OK") break;
|
||||
println(hlog, "s = ", s);
|
||||
auto pos = s.find(" ");
|
||||
if(pos != string::npos) {
|
||||
string cap = s.substr(0, pos);
|
||||
string param = s.substr(pos+1);
|
||||
if(cap == "START") {
|
||||
current_room = &r;
|
||||
sscanf(param.c_str(), "%lf%lf", &m.where_x, &m.where_y);
|
||||
}
|
||||
else if(cap == "ITEM") {
|
||||
auto b = std::make_unique<item>();
|
||||
sscanf(param.c_str(), "%lf%lf", &b->where_x, &b->where_y);
|
||||
s = scanline_noblank(f);
|
||||
b->id = -1;
|
||||
for(int i=0; i<isize(powers); i++) if(powers[i].name == s) b->id = i;
|
||||
if(b->id == -1) println(hlog, "error: unknown item name ", s), b->id = 0;
|
||||
r.entities.emplace_back(std::move(b));
|
||||
}
|
||||
else println(hlog, "unknown mapline ", s);
|
||||
}
|
||||
else println(hlog, "unknown mapline ", s);
|
||||
}
|
||||
}
|
||||
|
||||
void load_map(string fname) {
|
||||
fhstream f(fname, "r");
|
||||
load_room(f, currentmap->gamestart());
|
||||
while(!feof(f.f)) {
|
||||
string s = scanline_noblank(f);
|
||||
if(s == "") continue;
|
||||
if(s.substr(0, 4) == "MOVE") {
|
||||
int i = s[5] - '0';
|
||||
string roomname = s.substr(7);
|
||||
for(auto& [c,r]: rooms) if(r.roomname == roomname) load_room(f, c->move(i));
|
||||
}
|
||||
else err("load_map", s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user