1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2026-04-16 15:01:23 +00:00

ru:: dark orbs

This commit is contained in:
Zeno Rogue
2026-04-03 10:50:23 +02:00
parent 0a04a76c69
commit bc37987e68
5 changed files with 47 additions and 7 deletions

View File

@@ -188,6 +188,7 @@ struct room {
void generate();
void reveal(int cx, int cy);
void unreveal(int cx, int cy);
void reveal_around(int cx, int cy);
void fov_from(int sx, int sy);
@@ -368,6 +369,8 @@ struct entity {
entity *hal();
virtual bool nonstatic() { return true; }
virtual void preact() {}
};
struct weaponmod {
@@ -559,6 +562,17 @@ struct timed_orb : public located_entity {
string get_help() override { return "These orbs activate mechanisms for a limited time."; }
};
struct dark_orb : public located_entity {
int duration;
bbox box;
xy siz() override { return {18, 18}; }
string glyph() override { return "O"; }
color_t color() override { return 0x303030FF; }
void preact() override;
string get_name() override { return "dark orb"; }
string get_help() override { return "These orbs make it impossible to map a part of room."; }
};
struct switch_event {
bbox box;
eWall wall;

View File

@@ -401,6 +401,16 @@ void timed_orb::act() {
current_room->timed_orb_end = gframeid + duration;
}
void dark_orb::preact() {
for(int y=box.miny; y<box.maxy; y++)
for(int x=box.minx; x<box.maxx; x++)
current_room->unreveal(x, y);
if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) {
addMessage("You shatter the orb of darkness!");
existing = false;
}
}
void trader::act() {
bool any_purchases = false;
for(auto& e: current_room->entities) if(auto si = e->as_shopitem()) if(!si->existing) any_purchases = true;

View File

@@ -164,6 +164,7 @@ void load_room(fhstream& f, cell *c) {
auto get_int = [&] () { return atoi(cutoff("0").c_str()); };
auto get_color = [&] () { color_t col; sscanf(cutoff("0").c_str(), "%08x", &col); return col; };
auto get_xy = [&] () { ld x = get_ld(); ld y = get_ld(); return xy{x, y}; };
auto get_box = [&] () { bbox b; b.minx = get_int(); b.miny = get_int(); b.maxx = get_int(); b.maxy = get_int(); return b; };
if(cap == "START") {
fountain_room = current_room = &r;
@@ -248,6 +249,12 @@ void load_room(fhstream& f, cell *c) {
b->duration = get_ld() * game_fps;
r.entities.emplace_back(std::move(b));
}
else if(cap == "DARKORB") {
auto b = std::make_unique<dark_orb>(); nam(*b);
b->respawn = get_xy();
b->box = get_box();
r.entities.emplace_back(std::move(b));
}
else if(cap == "BAT") {
auto b = std::make_unique<bat>(); nam(*b);
b->respawn = get_xy();
@@ -384,11 +391,7 @@ void load_room(fhstream& f, cell *c) {
if(!lmev) throw hr_exception("SWITCHEVENT without MAPSWITCH");
auto& ev = lmev->events;
ev.emplace_back();
ev.back().box.minx = get_int();
ev.back().box.miny = get_int();
ev.back().box.maxx = get_int();
ev.back().box.maxy = get_int();
ev.back().wall = wDoor;
ev.back().box = get_box();
bool ok = false;
for(int i=0; i<qwall; i++) if(walls[i].name + " " == param)
ev.back().wall = eWall(i), ok = true;

View File

@@ -102,6 +102,17 @@ void room::reveal(int cx, int cy) {
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::unreveal(int cx, int cy) {
if(cx < 0 || cy < 0 || cx >= room_x || cy >= room_y) return;
fov[cy][cx] = 0;
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] = 0;
}
}

View File

@@ -148,10 +148,12 @@ tuple<xy, ld, int> get_next_room(xy w, room *r, int which) {
vector<unique_ptr<struct entity>> new_entities;
void playing_frame() {
m.act();
auto& ents = current_room->entities;
for(auto& e: ents) if(e->existing) e->preact();
m.act();
for(auto& e: ents) if(e->existing) e->act(); else e->unact();
auto mb = ents.begin();