diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index ac900813..beced6a4 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -143,6 +143,8 @@ struct entity { hp = max_hp(); } + data get_dat(); + struct bbox get_pixel_bbox_at(double x, double y); struct bbox get_pixel_bbox() { return get_pixel_bbox_at(where_x, where_y); } @@ -162,6 +164,8 @@ struct entity { virtual void draw(); + virtual void attacked(int s) {} + virtual string glyph() = 0; virtual color_t color() = 0; @@ -215,6 +219,16 @@ struct npc : public entity { void act() override; }; +struct boar : public entity { + double sx() override { return 18; } + double sy() override { return 18; } + string glyph() override { return "B"; } + color_t color() override { return 0x804000FF; } + void act() override; + boar() { postfix(); } + void attacked(int s) override; + }; + struct hint : public entity { string hint_text; int state; diff --git a/rogueviz/ru/entity.cpp b/rogueviz/ru/entity.cpp index 827f2782..047294cb 100644 --- a/rogueviz/ru/entity.cpp +++ b/rogueviz/ru/entity.cpp @@ -20,15 +20,21 @@ bool entity::visible(room *r) { return false; } +data entity::get_dat() { + data dat; + dat.d = get_scale(); + dat.modv = 60. / game_fps; + dat.moda = dat.modv * dat.modv; + dat.dx = 0; + return dat; + } + 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; + auto dat = get_dat(); + vel_y += dat.d * grav() * dat.moda * 16/9.; } void entity::kino() { @@ -203,6 +209,36 @@ void npc::act() { } } +void boar::act() { + kino(); + if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) { + addMessage("The wild boar gores you!"); + int s = where_x < m.where_x ? -1 : 1; + m.reduce_hp(15); + auto dat = get_dat(); + auto mdat = m.get_dat(); + if(m.on_floor) m.vel_x = mdat.d * mdat.modv * -s * 1.5, m.vel_y = -mdat.d * mdat.modv * 2; + if(on_floor) vel_x = dat.d * dat.modv * s * 1.5; + } + if(on_floor) { + auto dat = get_dat(); + if(vel_x > 0) vel_x = max(vel_x - dat.d * dat.moda * 0.05, 0); + if(vel_x < 0) vel_x = min(vel_x + dat.d * dat.moda * 0.05, 0); + if(gframeid > invinc_end) { + if(intersect(extend(get_pixel_bbox(), 60 * dat.d, 0, 0, 0), m.get_pixel_bbox())) vel_x -= dat.d * dat.moda * 0.2; + if(intersect(extend(get_pixel_bbox(), 0, 60 * dat.d, 0, 0), m.get_pixel_bbox())) vel_x += dat.d * dat.moda * 0.2; + } + } + } + +void boar::attacked(int dmg) { + reduce_hp(dmg); + if(destroyed) addMessage("You kill the wild boar."); else addMessage("You hit the wild boar."); + auto dat = get_dat(); + int s = where_x < m.where_x ? -1 : 1; + if(on_floor) vel_x = dat.d * dat.modv * s * 2, vel_y = -dat.d * dat.modv * 2.5; + } + void hint::act() { bool cur = intersect(get_pixel_bbox(), m.get_pixel_bbox()); if(cur && !state) { diff --git a/rogueviz/ru/geometry.cpp b/rogueviz/ru/geometry.cpp index 39061d06..584b14e0 100644 --- a/rogueviz/ru/geometry.cpp +++ b/rogueviz/ru/geometry.cpp @@ -97,6 +97,16 @@ bbox join(bbox a, bbox b) { bbox room_bb{0, 0, room_x, room_y}; bbox screen_bb{0, 0, screen_x, screen_y}; +bbox extend(bbox a, int l, int r, int u, int d) { + a.minx -= l; + a.maxx += r; + a.miny -= u; + a.maxy += d; + return a; + } + +bbox extend_all(bbox a, int x) { return extend(a, x, x, x, x); } + bbox get_intersect(bbox a, bbox b) { bbox r; r.minx = max(a.minx, b.minx); diff --git a/rogueviz/ru/man.cpp b/rogueviz/ru/man.cpp index 408cdc8a..e43f832a 100644 --- a/rogueviz/ru/man.cpp +++ b/rogueviz/ru/man.cpp @@ -5,11 +5,7 @@ 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; + auto dat = get_dat(); coyote_time = next_coyote_time; next_coyote_time = 0; jump_control = next_jump_control; next_jump_control = 0; diff --git a/rogueviz/ru/map.ru b/rogueviz/ru/map.ru index 1ec09ad4..432a3577 100644 --- a/rogueviz/ru/map.ru +++ b/rogueviz/ru/map.ru @@ -212,6 +212,8 @@ 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 +BOAR 256 60 +BOAR 113 255 ITEM 279 65 furry ring Someone lost a small, weird ring here. Hopefully it will be useful to you. @@ -262,6 +264,7 @@ 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 +BOAR 348 202 OK MOVE 1 Climbing the Hill diff --git a/rogueviz/ru/portals.cpp b/rogueviz/ru/portals.cpp index f9bb4061..92e18084 100644 --- a/rogueviz/ru/portals.cpp +++ b/rogueviz/ru/portals.cpp @@ -7,16 +7,14 @@ bool gravision; array, 256> all_locations; void entity::apply_portal_grav() { - ld modv = 60. / game_fps; - ld moda = modv * modv; - auto d = get_scale(); + auto dat = get_dat(); 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; + vel_x += dat.d * grav() * dat.moda * px * 16/9.; + vel_y += dat.d * grav() * dat.moda * py * 16/9.; } void load_nonhyperbolic() { diff --git a/rogueviz/ru/powers.cpp b/rogueviz/ru/powers.cpp index ece6c3c2..6d0baa41 100644 --- a/rogueviz/ru/powers.cpp +++ b/rogueviz/ru/powers.cpp @@ -64,7 +64,9 @@ vector powers = { [] (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)); + auto pb = m.get_pixel_bbox_at(m.where_x + m.attack_facing * m.dsx(), m.where_y); + auto bb = pixel_to_block(pb); + for(auto& e: current_room->entities) if(intersect(e->get_pixel_bbox(), pb)) e->attacked(15); for(int y=bb.miny; yat(x, y); diff --git a/rogueviz/ru/save.cpp b/rogueviz/ru/save.cpp index 48ef3152..4eaefc74 100644 --- a/rogueviz/ru/save.cpp +++ b/rogueviz/ru/save.cpp @@ -127,6 +127,11 @@ void load_room(fhstream& f, cell *c) { b->text = scanline_noblank(f); r.entities.emplace_back(std::move(b)); } + else if(cap == "BOAR") { + auto b = std::make_unique(); + sscanf(param.c_str(), "%lf%lf", &b->where_x, &b->where_y); + r.entities.emplace_back(std::move(b)); + } else if(cap == "HINT") { auto b = std::make_unique(); sscanf(param.c_str(), "%lf%lf%d%d", &b->where_x, &b->where_y, &b->width, &b->height);