mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-08-30 01:07:57 +00:00
ru:: axe weapon
This commit is contained in:
@@ -228,7 +228,7 @@ struct entity {
|
|||||||
|
|
||||||
data get_dat();
|
data get_dat();
|
||||||
|
|
||||||
struct bbox get_pixel_bbox_at(xy);
|
struct bbox get_pixel_bbox_at(xy, ld scalex = 1, ld scaley = 1);
|
||||||
struct bbox get_pixel_bbox() { return get_pixel_bbox_at(where); }
|
struct bbox get_pixel_bbox() { return get_pixel_bbox_at(where); }
|
||||||
|
|
||||||
virtual double grav() { return 0.1; }
|
virtual double grav() { return 0.1; }
|
||||||
@@ -299,12 +299,22 @@ struct statdata {
|
|||||||
vector<tuple<power*, mod, int>> mods;
|
vector<tuple<power*, mod, int>> mods;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using boxfun = hr::function<bbox(int)>;
|
||||||
|
|
||||||
|
struct effect {
|
||||||
|
power *p;
|
||||||
|
int attack_facing;
|
||||||
|
int attack_when;
|
||||||
|
boxfun f;
|
||||||
|
};
|
||||||
|
|
||||||
struct man : public entity {
|
struct man : public entity {
|
||||||
int facing;
|
int facing;
|
||||||
int attack_facing;
|
int attack_facing;
|
||||||
int attack_when;
|
int attack_when;
|
||||||
int on_floor_when;
|
int on_floor_when;
|
||||||
entity *morphed = nullptr;
|
entity *morphed = nullptr;
|
||||||
|
vector<effect> effects;
|
||||||
|
|
||||||
int last_action;
|
int last_action;
|
||||||
|
|
||||||
@@ -349,6 +359,7 @@ struct man : public entity {
|
|||||||
addMessage("OUCH! These spikes hurt!");
|
addMessage("OUCH! These spikes hurt!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void launch_attack(power *p, int fac, boxfun f);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern man m;
|
extern man m;
|
||||||
|
@@ -2,15 +2,18 @@ namespace rogue_unlike {
|
|||||||
|
|
||||||
man m;
|
man m;
|
||||||
|
|
||||||
bbox entity::get_pixel_bbox_at(xy p) {
|
bbox entity::get_pixel_bbox_at(xy p, ld scalex, ld scaley) {
|
||||||
bbox b;
|
bbox b;
|
||||||
double d = get_scale_at(p.y);
|
double d = get_scale_at(p.y);
|
||||||
|
ld dx = d * scalex;
|
||||||
|
ld dy = d * scaley;
|
||||||
double man_x = siz().x;
|
double man_x = siz().x;
|
||||||
double man_y = siz().y;
|
double man_y = siz().y;
|
||||||
b.minx = p.x - man_x * d / 2;
|
b.minx = p.x - man_x * dx / 2;
|
||||||
b.maxx = p.x + man_x * d / 2 + 1;
|
b.maxx = p.x + man_x * dx / 2 + 1;
|
||||||
b.miny = p.y - man_y * d / 2;
|
b.miny = p.y - man_y * dy / 2;
|
||||||
b.maxy = p.y + man_y * d / 2 + 1;
|
b.maxy = p.y + man_y * dy / 2 + 1;
|
||||||
|
if(ldebug) println(hlog, tie(man_x, man_y, d));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -101,4 +101,42 @@ void revert_all(revert_stack& s) {
|
|||||||
while(!s.empty()) { s.back()(); s.pop_back(); }
|
while(!s.empty()) { s.back()(); s.pop_back(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void man::launch_attack(power *p, int fac, boxfun f) {
|
||||||
|
effects.emplace_back();
|
||||||
|
auto& e = effects.back();
|
||||||
|
e.p = p;
|
||||||
|
e.attack_facing = fac;
|
||||||
|
e.attack_when = gframeid;
|
||||||
|
e.f = f;
|
||||||
|
auto pb = f(0);
|
||||||
|
auto bb = pixel_to_block(pb);
|
||||||
|
for(auto& e: current_room->entities)
|
||||||
|
if(e->existing && intersect(e->get_pixel_bbox(), pb)) {
|
||||||
|
int sav = e->invinc_end;
|
||||||
|
e->attacked((m.current.stats[stat::str] + 1) * 3 / 2);
|
||||||
|
for(auto& [m, qty]: p->mods) {
|
||||||
|
if(m == mod::burning) { e->invinc_end = sav; e->attacked(qty); }
|
||||||
|
if(m == mod::freezing) { e->invinc_end = sav; e->attacked(qty); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
if(b == wDoor) {
|
||||||
|
current_room->replace_block_frev(x, y, wSmashedDoor);
|
||||||
|
addMessage("You smash the door!");
|
||||||
|
}
|
||||||
|
for(auto& [m, qty]: p->mods) {
|
||||||
|
if(m == mod::burning && b == wWoodWall) {
|
||||||
|
current_room->replace_block_frev(x, y, wAir);
|
||||||
|
addMessage("You burn the wall!");
|
||||||
|
}
|
||||||
|
if(m == mod::freezing && b == wWater) {
|
||||||
|
current_room->replace_block_frev(x, y, wFrozen);
|
||||||
|
addMessage("You freeze the water!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -317,36 +317,17 @@ void gen_powers() {
|
|||||||
")", 0xFFFFFFFF,
|
")", 0xFFFFFFFF,
|
||||||
[] (data& d) {
|
[] (data& d) {
|
||||||
if(d.keystate != 1) return;
|
if(d.keystate != 1) return;
|
||||||
m.attack_facing = m.facing; m.attack_when = gframeid;
|
for(auto fac: {1, -1})
|
||||||
auto pb = m.get_pixel_bbox_at(xy{m.where.x + m.attack_facing * m.dsiz().x, m.where.y});
|
m.launch_attack(d.p, fac, [fac] (int t) { return m.get_pixel_bbox_at(xy{m.where.x + fac * (1-0.01 * t) * m.dsiz().x, m.where.y}); });
|
||||||
auto bb = pixel_to_block(pb);
|
}).be_weapon(),
|
||||||
for(auto& e: current_room->entities)
|
|
||||||
if(e->existing && intersect(e->get_pixel_bbox(), pb)) {
|
gen_power('x', "axe",
|
||||||
int sav = e->invinc_end;
|
"This axe is very sharp and strong! It could even destroy heavy doors.",
|
||||||
e->attacked((m.current.stats[stat::str] + 1) * 3 / 2);
|
")", 0xFFFFFFFF,
|
||||||
for(auto& [m, qty]: d.p->mods) {
|
[] (data& d) {
|
||||||
if(m == mod::burning) { e->invinc_end = sav; e->attacked(qty); }
|
if(d.keystate != 1) return;
|
||||||
if(m == mod::freezing) { e->invinc_end = sav; e->attacked(qty); }
|
int fac = m.facing;
|
||||||
}
|
m.launch_attack(d.p, fac, [fac] (int t) { return m.get_pixel_bbox_at(xy{m.where.x + fac * (1-0.01 * t) * m.dsiz().x, m.where.y}, 2, 2); });
|
||||||
}
|
|
||||||
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);
|
|
||||||
if(b == wDoor) {
|
|
||||||
current_room->replace_block_frev(x, y, wSmashedDoor);
|
|
||||||
addMessage("You smash the door!");
|
|
||||||
}
|
|
||||||
for(auto& [m, qty]: d.p->mods) {
|
|
||||||
if(m == mod::burning && b == wWoodWall) {
|
|
||||||
current_room->replace_block_frev(x, y, wAir);
|
|
||||||
addMessage("You burn the wall!");
|
|
||||||
}
|
|
||||||
if(m == mod::freezing && b == wWater) {
|
|
||||||
current_room->replace_block_frev(x, y, wFrozen);
|
|
||||||
addMessage("You freeze the water!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).be_weapon(),
|
}).be_weapon(),
|
||||||
|
|
||||||
gen_power('o', "strange blue crystal ball", "You feel an urge to look into it.",
|
gen_power('o', "strange blue crystal ball", "You feel an urge to look into it.",
|
||||||
|
@@ -245,19 +245,24 @@ void entity::draw() {
|
|||||||
void man::draw() {
|
void man::draw() {
|
||||||
entity::draw();
|
entity::draw();
|
||||||
|
|
||||||
ld t = gframeid - attack_when;
|
auto efs = effects.begin();
|
||||||
if(t < 50) {
|
|
||||||
auto af = attack_facing * (1 - t * 0.01);
|
for(auto& e: effects) {
|
||||||
auto ds = dsiz();
|
ld t = gframeid - e.attack_when;
|
||||||
auto col = find_power("dagger").get_color();
|
if(t < 50) {
|
||||||
auto& alpha = part(col, 0);
|
auto col = find_power("dagger").get_color();
|
||||||
alpha = max<int> (0, alpha - 5 * t);
|
auto& alpha = part(col, 0);
|
||||||
asciiletter(
|
alpha = max<int> (0, alpha - 5 * t);
|
||||||
where.x + af * ds.x - ds.x/2, where.y - ds.y/2,
|
auto box = e.f(t);
|
||||||
where.x + af * ds.x + ds.x/2, where.y + ds.y/2,
|
asciiletter(
|
||||||
attack_facing == -1 ? "(" : ")", col
|
box.minx, box.miny, // where.x + af * ds.x - ds.x/2, where.y - ds.y/2,
|
||||||
);
|
box.maxx, box.maxy, // where.x + af * ds.x + ds.x/2, where.y + ds.y/2,
|
||||||
|
e.attack_facing == -1 ? "(" : ")", col
|
||||||
|
);
|
||||||
|
*(efs++) = e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
effects.resize(efs - effects.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_room_objects(room *r) {
|
void render_room_objects(room *r) {
|
||||||
|
@@ -133,7 +133,7 @@ void stat_screen(bool editable) {
|
|||||||
cmode = mode::playing;
|
cmode = mode::playing;
|
||||||
switch(m.profession) {
|
switch(m.profession) {
|
||||||
case stat::str:
|
case stat::str:
|
||||||
find_power("dagger").gain(1, 1); // no axe yet
|
find_power("axe").gain(1, 1);
|
||||||
break;
|
break;
|
||||||
case stat::con:
|
case stat::con:
|
||||||
find_power("polymorph").gain(1, 1).flags |= IDENTIFIED | PARTIAL;
|
find_power("polymorph").gain(1, 1).flags |= IDENTIFIED | PARTIAL;
|
||||||
|
Reference in New Issue
Block a user