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

ru:: morphing now respects the change in size, and is forbidden if not enough space

This commit is contained in:
Zeno Rogue
2026-03-29 15:27:09 +02:00
parent 9346567ab0
commit 925cc5ada1
3 changed files with 57 additions and 20 deletions

View File

@@ -407,6 +407,7 @@ struct man : public entity {
virtual int max_hp() { return 10 * current.stats[stat::con]; }
void handle_morph(entity *m);
bool can_see(entity& e);
man();
xy siz() override {

View File

@@ -215,4 +215,45 @@ void man::launch_attack(power *p, int fac, boxfun f) {
}
}
void man::handle_morph(entity *m) {
auto pre_size = get_pixel_bbox();
swap(m, morphed);
auto at = where;
if(on_floor) {
do {
where.y += 1;
}
while(get_pixel_bbox().maxy < pre_size.maxy);
do {
where.y -= 1;
}
while(get_pixel_bbox().maxy > pre_size.maxy);
}
println(hlog, "where moved from ", at.y, " to ", where.y);
auto bb = pixel_to_block(get_pixel_bbox());
println(hlog, "bblock is ", bb);
bool ok = true;
for(int x = bb.minx; x < bb.maxx; x++) for(int y = bb.miny; y < bb.maxy; y++) {
eWall b = current_room->at(x, y);
if(walls[b].flags & W_BLOCK) ok = false;
}
for(auto& e: current_room->entities) if(auto p = e->as_platform()) {
auto pb = p->get_pixel_bbox();
if(intersect(pb, bb)) ok = false;
}
if(ok) {
if(morphed) {
string adj = morphed->id == "capy" ? "lovely " : "";
addMessage("You morph into a " + adj + morphed->get_name() + "!");
}
else
addMessage("You morph back into a human.");
}
else {
swap(m, morphed); where = at;
addMessage("Not enough space here to morph!");
}
if(m) delete m;
}
}

View File

@@ -230,33 +230,28 @@ randeff ice_weapon("Chill Weapon", "Attacks with your [weapon] freeze things.",
flavor morph_cat_color;
cat *new_cat() {
auto c = new cat;
c->id = "cat";
c->col = morph_cat_color;
return c;
}
capybara *new_capy() {
auto c = new capybara;
c->id = "capy";
return c;
}
// morph powers
randeff morph_cat("Cat", "Turns you into a cat.", "You turn into a cat!", [] (data &d) {
if(d.mode == rev::start || (d.mode == rev::active && d.keystate == 1) || (d.mode == rev::stop && m.morphed)) {
if(m.morphed) {
delete(m.morphed), m.morphed = nullptr;
addMessage("You morph back into a human.");
}
else {
auto mcat = new cat;
mcat->id = "cat";
mcat->col = morph_cat_color;
m.morphed = mcat;
addMessage("You morph into a " + m.morphed->get_name() + "!");
}
m.handle_morph(m.morphed ? nullptr : new_cat());
}
});
randeff morph_capy("Capybara", "Turns you into a capybara.", "You turn into a capybara!", [] (data &d) {
if(d.mode == rev::start || (d.mode == rev::active && d.keystate == 1) || (d.mode == rev::stop && m.morphed)) {
if(m.morphed) {
delete(m.morphed), m.morphed = nullptr;
addMessage("You morph back into a human.");
}
else {
m.morphed = new capybara;
m.morphed->id = "capy";
addMessage("You morph into a lovely capybara!");
}
m.handle_morph(m.morphed ? nullptr : new_capy());
}
});