1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-05-10 03:04:06 +00:00

ru:: the first monster, the boar

This commit is contained in:
Zeno Rogue 2025-04-27 12:42:22 +02:00
parent 1fb931836a
commit 77759538ae
8 changed files with 80 additions and 16 deletions

View File

@ -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;

View File

@ -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<ld>(vel_x - dat.d * dat.moda * 0.05, 0);
if(vel_x < 0) vel_x = min<ld>(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) {

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -7,16 +7,14 @@ 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();
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() {

View File

@ -64,7 +64,9 @@ vector<power> 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; y<bb.maxy; y++)
for(int x=bb.minx; x<bb.maxx; x++) {
int b = current_room->at(x, y);

View File

@ -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<boar>();
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<hint>();
sscanf(param.c_str(), "%lf%lf%d%d", &b->where_x, &b->where_y, &b->width, &b->height);