diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index 8d712ffc..71378c61 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -212,6 +212,8 @@ struct entity { void apply_portal_grav(); bool stay_on_screen(); /* returns true if flipped */ virtual void act() { kino(); } + /* for things which can act while not existing */ + virtual void unact() { } double get_scale() { return get_scale_at(where.y); } virtual bool freezing() { return false; } @@ -465,6 +467,7 @@ struct item : public entity { string glyph() override { return powers[id].get_glyph(); } color_t color() override { return powers[id].get_color(); } void act() override { + stay_on_screen(); kino(); if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) { addMessage(pickup_message); @@ -499,6 +502,25 @@ struct shopitem : public item { shopitem* as_shopitem() override { return this; } }; +struct loot : public item { + entity *owner; + bool dropped; + void act() { + item::act(); + if(on_floor) { + auto dat = get_dat(); + if(vel.x > 0) vel.x = max(vel.x - dat.d * dat.moda * 0.02, 0); + if(vel.x < 0) vel.x = min(vel.x + dat.d * dat.moda * 0.02, 0); + } + } + void unact() override { + if(!dropped && !owner->existing) { + where = owner->where, vel = owner->vel; + dropped = true; existing = true; + } + } + }; + struct missile : public entity { missile() { destroyed = false; } xy siz() override { return {4, 4}; } diff --git a/rogueviz/ru/ru.cpp b/rogueviz/ru/ru.cpp index 1efb49bf..18a49d19 100644 --- a/rogueviz/ru/ru.cpp +++ b/rogueviz/ru/ru.cpp @@ -100,7 +100,7 @@ void playing_frame() { auto& ents = current_room->entities; - for(auto& e: ents) if(e->existing) e->act(); + for(auto& e: ents) if(e->existing) e->act(); else e->unact(); auto mb = ents.begin(); for(auto& e: ents) if(!e->destroyed) *(mb++) = std::move(e); diff --git a/rogueviz/ru/save.cpp b/rogueviz/ru/save.cpp index d47952c3..53e486ea 100644 --- a/rogueviz/ru/save.cpp +++ b/rogueviz/ru/save.cpp @@ -120,6 +120,21 @@ void load_room(fhstream& f, cell *c) { b->pickup_message = scanline_noblank(f); r.entities.emplace_back(std::move(b)); } + else if(cap == "LOOT") { + auto b = std::make_unique(); + b->qty = 1; + b->owner = &*r.entities.back(); + sscanf(param.c_str(), "%d", &b->qty); + s = scanline_noblank(f); + b->id = -1; + b->where = xy(320, 200); + for(int i=0; iid = i; + if(b->id == -1) println(hlog, "error: unknown loot name ", s), b->id = 0; + b->pickup_message = scanline_noblank(f); + b->existing = false; b->dropped = false; + r.entities.emplace_back(std::move(b)); + println(hlog, "loot pushed"); + } else if(cap == "SHOPITEM") { auto b = std::make_unique(); b->qty = 1; b->qty1 = 0;