1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-05-16 22:24:07 +00:00

ru:: stats, redefine keys in the inventory screen

This commit is contained in:
Zeno Rogue 2025-05-04 22:37:00 +02:00
parent 40b06218d9
commit 5a761c43c5
7 changed files with 110 additions and 21 deletions

View File

@ -132,6 +132,17 @@ struct xy {
xy& operator /= (ld s) { x /= s; y /= s; return self; }
};
enum class stat { str, con, wis, dex };
constexpr stat allstats[] = { stat::str, stat::con, stat::wis, stat::dex };
constexpr int qstat = 4;
template<class T> struct statarray : array<T, qstat> {
statarray() {};
T& operator [] (stat s) { return array<T, qstat>::operator[] ((int) s); };
const T& operator [] (stat s) const { return array<T, qstat>::operator[] ((int) s); };
};
struct entity {
virtual xy siz() = 0;
xy where, vel;
@ -232,7 +243,17 @@ struct man : public entity {
int last_action;
man() { facing = 1; attack_facing = 1; postfix(); }
int experience;
statarray<int> base_stats, current_stats, next_stats;
virtual int max_hp() { return 10 * current_stats[stat::con]; }
man() {
facing = 1; attack_facing = 1;
for(auto s: allstats) base_stats[s] = 10;
next_stats = base_stats; current_stats = base_stats;
postfix();
}
xy siz() override { return {12, 12}; }
string glyph() override { return hallucinating ? "f" : "@"; }
color_t color() override { return hallucinating ? 0x808080FF : 0xFF8080FF; }

View File

@ -246,7 +246,7 @@ void npc::act() {
kino();
if(gframeid > m.last_action + 300 && intersect(extend_all(get_pixel_bbox(), get_scale()*12), m.get_pixel_bbox()) && talk_on != m.last_action) {
talk_on = m.last_action = gframeid;
cmode = mode::talking;
cmode = mode::menu;
pushScreen([&] { cmode = mode::playing; popScreen(); });
pushScreen([&] {
dialog::init(name, col >> 8);

View File

@ -124,14 +124,14 @@ extern array<array<location, 256>, 256> all_locations;
enum class mapmode { standard, poincare, klein };
enum class mode { editmap, menu, playing, paused, inventory, talking };
enum class mode { editmap, menu, playing, paused };
mode cmode = mode::playing;
mapmode cmapmode = mapmode::standard;
void switch_mapmode_to(mapmode m);
bool should_apply_fov() { return among(cmode, mode::playing, mode::paused, mode::inventory); }
bool should_apply_fov() { return among(cmode, mode::playing, mode::paused, mode::menu); }
void enable();
@ -146,4 +146,6 @@ void render_room_objects(room *r);
void asciiletter(ld minx, ld miny, ld maxx, ld maxy, const string& ch, color_t col);
void render_the_map();
}

View File

@ -5,6 +5,8 @@ void handle_powers(data& d);
void man::act() {
kino();
current_stats = next_stats;
next_stats = base_stats;
auto dat = get_dat();
coyote_time = next_coyote_time; next_coyote_time = 0;

View File

@ -117,7 +117,7 @@ void gen_powers() {
m.attack_facing = m.facing; m.attack_when = gframeid;
auto pb = m.get_pixel_bbox_at(xy{m.where.x + m.attack_facing * m.dsiz().x, m.where.y});
auto bb = pixel_to_block(pb);
for(auto& e: current_room->entities) if(e->existing && intersect(e->get_pixel_bbox(), pb)) e->attacked(15);
for(auto& e: current_room->entities) if(e->existing && intersect(e->get_pixel_bbox(), pb)) e->attacked((m.current_stats[stat::str] + 1) * 3 / 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);
@ -207,6 +207,8 @@ void gen_powers() {
"Is it safe to put this ring on?",
"=", 0xC04040FF,
[] (data& d) {
if(d.p->flags & ACTIVE)
m.next_stats[stat::str] += d.p->qty_filled;
if(d.keystate == 1) {
d.p->flags ^= ACTIVE;
d.p->flags |= IDENTIFIED;
@ -239,23 +241,44 @@ void handle_powers(data& d) {
}
}
void draw_inventory() {
void draw_inventory_frame() {
flat_model_enabler fme;
initquickqueue();
for(int a: {0, 1, 3, 2, 0})
curvepoint(eupoint((a&1)?16:vid.xres-16, (a&2)?16:vid.yres-16));
queuecurve(atscreenpos(0, 0), 0xFFFFFFFF, 0x000000E0, PPR::LINE);
quickqueue();
}
void draw_inventory() {
render_the_map();
draw_inventory_frame();
dialog::init();
int next_y = 48;
int st = vid.fsize * 1.2;
displaystr(32, next_y, 0, vid.fsize, "Your inventory:", 0xC0C0C0, 0);
next_y += st * 1.5;
for(auto& p: powers) if(p.qty_owned) {
string key = p.key == ' ' ? "" : dialog::keyname(p.key);
displaystr(100, next_y, 0, vid.fsize, key, p.color >> 8, 16);
displaystr(130, next_y, 0, vid.fsize, p.get_glyph(), p.color >> 8, 8);
displaystr(160, next_y, 0, vid.fsize, p.get_name(), p.color >> 8, 0);
if(displaystr(100, next_y, 0, vid.fsize, key, p.color >> 8, 16)) getcstat = p.key;
if(displaystr(130, next_y, 0, vid.fsize, p.get_glyph(), p.color >> 8, 8)) getcstat = p.key;
if(displaystr(160, next_y, 0, vid.fsize, p.get_name(), p.color >> 8, 0)) getcstat = p.key;
next_y += st;
dialog::add_key_action(p.key, [&p] { pushScreen([&p] {
render_the_map();
draw_inventory_frame();
dialog::init(p.get_name(), p.color);
dialog::addHelp(p.get_desc());
dialog::addItem("press a key to redefine", SDLK_ESCAPE);
dialog::display();
dialog::addBack();
keyhandler = [&p] (int sym, int uni) {
if(sym == 0) return;
if(sym == SDLK_ESCAPE) return popScreen();
for(auto& p1: powers) if(p1.key == sym) p1.key = p.key;
p.key = sym;
};
}); });
}
}

View File

@ -33,6 +33,7 @@ Have fun!
#include "portals.cpp"
#include "powers.cpp"
#include "save.cpp"
#include "stats.cpp"
namespace rogue_unlike {
@ -298,25 +299,19 @@ void run() {
draw_pentagon();
break;
case mode::inventory:
render_the_map();
draw_inventory();
dialog::add_key_action('v', [] { cmode = mode::menu; });
break;
case mode::talking:
break;
case mode::menu:
nomap = true;
emptyscreen();
render_the_map();
draw_inventory_frame();
dialog::init();
dialog::addTitle("Fountains of Alchemy", 0x4040C0, 150);
dialog::addItem("return to game", 'v');
dialog::add_action([] { cmode = mode::playing; });
dialog::addItem("inventory", 'i');
dialog::add_action([] { clearMessages(); cmode = mode::inventory; });
dialog::add_action_push(draw_inventory);
dialog::addItem("character", 'k');
dialog::add_action_push(draw_stats);
dialog::addItem("map editor", 'e');
dialog::add_action([] { cmode = mode::editmap; });

46
rogueviz/ru/stats.cpp Normal file
View File

@ -0,0 +1,46 @@
namespace rogue_unlike {
struct statinfo {
char key;
string name;
string desc;
};
statarray<statinfo> statdata;
void draw_stats() {
statdata[stat::str] = {'s', "Strength", "Affects the strength of your mundane melee attacks."};
statdata[stat::con] = {'t', "Toughness", "Affects the amount of hitpoints you have."};
statdata[stat::wis] = {'w', "Wisdom", "Affects the power of your alchemy."};
statdata[stat::dex] = {'d', "Dexterity", "Affects the strength of your mundane missile attacks."};
render_the_map();
draw_inventory_frame();
dialog::init("the Alchemist", 0xC000C0);
dialog::addSelItem("free experience", its(m.experience), 'x');
for(auto st: allstats) {
string s = its(m.base_stats[st]);
if(m.current_stats[st] != m.base_stats[st]) s += " (" + its(m.current_stats[st]) + ")";
dialog::addSelItem(statdata[st].name, s, statdata[st].key);
dialog::add_action_push([st] {
render_the_map();
draw_inventory_frame();
dialog::init(statdata[st].name, 0xC000C0);
dialog::addHelp(statdata[st].desc);
dialog::addBreak(100);
dialog::addSelItem("base value", its(m.base_stats[st]), 0);
dialog::addSelItem("current value", its(m.current_stats[st]), 0);
dialog::addBreak(100);
dialog::addBack();
dialog::display();
});
}
dialog::addBack();
dialog::display();
}
}