mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-07-20 18:02:50 +00:00
ru:: shops
This commit is contained in:
parent
30e0adef50
commit
5bd984e508
@ -166,6 +166,8 @@ struct entity {
|
||||
xy zero_vel; /* relative to the platform */
|
||||
|
||||
virtual struct moving_platform* as_platform() { return nullptr; }
|
||||
virtual struct shopitem* as_shopitem() { return nullptr; }
|
||||
virtual struct trader* as_trader() { return nullptr; }
|
||||
|
||||
int hp;
|
||||
int invinc_end;
|
||||
@ -313,19 +315,33 @@ struct pendulum_platform : public moving_platform {
|
||||
string get_help() override { return "These pendulum platforms go back and forth between two locations, taking the shortest path possible."; }
|
||||
};
|
||||
|
||||
struct npc : public entity {
|
||||
string sglyph, name;
|
||||
color_t col;
|
||||
struct npc_or_trader : public entity {
|
||||
string text;
|
||||
string name;
|
||||
int talk_on;
|
||||
xy siz() override { return {12, 12}; }
|
||||
void act() override;
|
||||
string get_name() override { return name; }
|
||||
};
|
||||
|
||||
struct npc : public npc_or_trader {
|
||||
string sglyph;
|
||||
color_t col;
|
||||
xy siz() override { return {12, 12}; }
|
||||
string glyph() override { return sglyph; }
|
||||
color_t color() override { return col; }
|
||||
void act() override;
|
||||
string get_name() override { return name; }
|
||||
string get_help() override { return "Stay awhile and listen."; }
|
||||
};
|
||||
|
||||
struct trader : public npc_or_trader {
|
||||
xy siz() override { return {18, 18}; }
|
||||
string glyph() override { return "@"; }
|
||||
color_t color() override { return 0x2020D0FF; }
|
||||
void act() override;
|
||||
string get_help() override { return "Stay awhile and listen. Or use gold to pay."; }
|
||||
virtual struct trader* as_trader() { return this; }
|
||||
};
|
||||
|
||||
struct enemy : public entity {
|
||||
xy respawn;
|
||||
int num_kills;
|
||||
@ -452,6 +468,26 @@ struct item : public entity {
|
||||
string get_help() override { return powers[id].get_desc(); }
|
||||
};
|
||||
|
||||
struct shopitem : public item {
|
||||
int qty1;
|
||||
int price;
|
||||
bool bought;
|
||||
string glyph() override;
|
||||
color_t color() override;
|
||||
bool last_intersect;
|
||||
void act() override {
|
||||
kino();
|
||||
bool next_intersect = intersect(get_pixel_bbox(), m.get_pixel_bbox());
|
||||
if(next_intersect && !last_intersect) {
|
||||
addMessage("This costs " + its(price) + " gold.");
|
||||
}
|
||||
last_intersect = next_intersect;
|
||||
}
|
||||
string get_name() override { if(bought) return its(price) + " gold"; return item::get_name(); }
|
||||
string get_help() override { if(bought) return "You have bought something from this shop. The trader has stored the gold here."; return item::get_help() + "\n\nPrice: " + its(price); }
|
||||
shopitem* as_shopitem() override { return this; }
|
||||
};
|
||||
|
||||
struct missile : public entity {
|
||||
missile() { destroyed = false; }
|
||||
xy siz() override { return {4, 4}; }
|
||||
|
@ -247,14 +247,14 @@ void missile::act() {
|
||||
if(where.x > screen_x || where.x < 0 || where.y < 0 || where.y > screen_y) destroyed = true;
|
||||
}
|
||||
|
||||
void npc::act() {
|
||||
void npc_or_trader::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::menu;
|
||||
pushScreen([&] { cmode = mode::playing; popScreen(); });
|
||||
pushScreen([&] {
|
||||
dialog::init(name, col >> 8);
|
||||
dialog::init(name, color() >> 8);
|
||||
dialog::addHelp(text);
|
||||
dialog::addBreak(100);
|
||||
dialog::addBack();
|
||||
@ -263,6 +263,27 @@ void npc::act() {
|
||||
}
|
||||
}
|
||||
|
||||
extern int gold_id;
|
||||
|
||||
string shopitem::glyph() { if(bought) return powers[gold_id].get_glyph(); else return item::glyph(); }
|
||||
color_t shopitem::color() { if(bought) return powers[gold_id].get_color(); else return item::color(); }
|
||||
|
||||
void trader::act() {
|
||||
bool any_purchases = false;
|
||||
for(auto& e: current_room->entities) if(auto si = e->as_shopitem()) if(!si->existing) any_purchases = true;
|
||||
if(any_purchases) {
|
||||
walls[wShopDoor].glyph = '+';
|
||||
walls[wShopDoor].flags = W_BLOCK | W_BLOCKBIRD;
|
||||
}
|
||||
else {
|
||||
walls[wShopDoor].glyph = '\'';
|
||||
walls[wShopDoor].flags = W_TRANS;
|
||||
}
|
||||
|
||||
if(any_purchases) talk_on = m.last_action;
|
||||
npc_or_trader::act();
|
||||
}
|
||||
|
||||
void boar::act() {
|
||||
stay_on_screen();
|
||||
kino();
|
||||
|
@ -1182,6 +1182,15 @@ Why is there always gold lying in these mazes...
|
||||
ITEM 308 261
|
||||
toughness
|
||||
You find a beautiful ring.
|
||||
SHOPITEM 421 238 50 1 0
|
||||
toughness
|
||||
You find a beautiful ring in this store.
|
||||
SHOPITEM 420 200 50 1 0
|
||||
wisdom
|
||||
You find another beautiful ring in this store.
|
||||
TRADER 458 247
|
||||
John the trader
|
||||
Hello here! Please buy something from my shop!
|
||||
OK
|
||||
|
||||
MOVE 2 Mazes of Menace
|
||||
|
@ -146,6 +146,12 @@ power& gen_power(int key, string name, string desc, string glyph, color_t color,
|
||||
power *extra_life;
|
||||
int gold_id;
|
||||
|
||||
void power_death_revert(power& p) {
|
||||
int q0 = p.qty_filled;
|
||||
int q1 = p.qty_owned;
|
||||
add_revert(death_revert, [&p, q0, q1] { p.qty_filled = q0; p.qty_owned = q1; });
|
||||
}
|
||||
|
||||
void gen_powers() {
|
||||
powers.reserve(100);
|
||||
|
||||
@ -405,13 +411,69 @@ void gen_powers() {
|
||||
|
||||
gold_id = isize(powers);
|
||||
|
||||
gen_power('g', "gold",
|
||||
gen_power('t', "gold",
|
||||
"For some weird reason, people love gold, and they will give you anything if you give them enough gold.\n\n"
|
||||
"This can be used to buy things in shops. "
|
||||
"Just stand on the item, press the hotkey, go to the shopkeeper, and press the hotkey again.\n\n"
|
||||
"If you decide not to buy, press the hotkey without going to the shopkeeper.",
|
||||
"$", 0xFFD500FF,
|
||||
[] (data& d) {}
|
||||
[] (data& d) {
|
||||
if(d.keystate == 1) {
|
||||
trader *tr;
|
||||
for(auto& e: current_room->entities) if(auto t = e->as_trader()) tr = t;
|
||||
bool on_trader = intersect(tr->get_pixel_bbox(), m.get_pixel_bbox());
|
||||
bool done_something = false;
|
||||
for(int it: {0, 1})
|
||||
for(auto& e: current_room->entities) if(auto si = e->as_shopitem()) {
|
||||
bool on = intersect(si->get_pixel_bbox(), m.get_pixel_bbox());
|
||||
if(it == 0 && on && si->existing && !si->bought) {
|
||||
done_something = true;
|
||||
addMessage(si->pickup_message);
|
||||
power_death_revert(powers[si->id]);
|
||||
powers[si->id].qty_owned += si->qty; powers[si->id].qty_filled += si->qty1;
|
||||
add_revert(death_revert, [si] { si->existing = true; });
|
||||
si->existing = false;
|
||||
}
|
||||
else if(it == 0 && on && si->existing && si->bought) {
|
||||
done_something = true;
|
||||
addMessage("You get some gold.");
|
||||
power_death_revert(powers[gold_id]);
|
||||
powers[gold_id].qty_owned += si->price; powers[gold_id].qty_filled += si->price;
|
||||
add_revert(death_revert, [si] { si->existing = true; });
|
||||
si->existing = false;
|
||||
}
|
||||
else if((it ? !done_something : on) && !si->existing && !si->bought) {
|
||||
done_something = true;
|
||||
addMessage("You rethink your purchase.");
|
||||
power_death_revert(powers[si->id]);
|
||||
powers[si->id].qty_owned -= si->qty; powers[si->id].qty_filled -= si->qty1;
|
||||
add_revert(death_revert, [si] { si->existing = false; });
|
||||
si->existing = true;
|
||||
}
|
||||
else if((it ? !done_something : on) && !si->existing && si->bought) {
|
||||
done_something = true;
|
||||
addMessage("You rethink your actions.");
|
||||
power_death_revert(powers[gold_id]);
|
||||
powers[gold_id].qty_owned -= si->price; powers[gold_id].qty_filled -= si->price;
|
||||
add_revert(death_revert, [si] { si->existing = false; });
|
||||
si->existing = true;
|
||||
}
|
||||
else if(it == 0 && on_trader && !si->existing && d.p->qty_owned >= si->price) {
|
||||
done_something = true;
|
||||
addMessage("You buy the " + powers[si->id].get_name() + ".");
|
||||
power_death_revert(powers[gold_id]);
|
||||
powers[gold_id].qty_owned -= si->price; powers[gold_id].qty_filled -= si->price;
|
||||
si->existing = true; si->bought = true;
|
||||
add_revert(death_revert, [si] { si->existing = false; si->bought = false; });
|
||||
}
|
||||
else if(it == 0 && on_trader && !si->existing && !si->bought) {
|
||||
done_something = true;
|
||||
addMessage("You have not enough gold to buy the " + powers[si->id].get_name() + ".");
|
||||
}
|
||||
}
|
||||
if(!done_something) addMessage("You count your gold. You have " + its(d.p->qty_owned) + " gold.");
|
||||
}
|
||||
}
|
||||
).be_resource("pieces of gold");
|
||||
|
||||
};
|
||||
|
@ -120,6 +120,17 @@ void load_room(fhstream& f, cell *c) {
|
||||
b->pickup_message = scanline_noblank(f);
|
||||
r.entities.emplace_back(std::move(b));
|
||||
}
|
||||
else if(cap == "SHOPITEM") {
|
||||
auto b = std::make_unique<shopitem>();
|
||||
b->qty = 1; b->qty1 = 0;
|
||||
sscanf(param.c_str(), "%lf%lf%d%d%d", &b->where.x, &b->where.y, &b->price, &b->qty, &b->qty1);
|
||||
s = scanline_noblank(f);
|
||||
b->id = -1;
|
||||
for(int i=0; i<isize(powers); i++) if(powers[i].name == s) b->id = i;
|
||||
if(b->id == -1) println(hlog, "error: unknown item name ", s), b->id = 0;
|
||||
b->pickup_message = scanline_noblank(f);
|
||||
r.entities.emplace_back(std::move(b));
|
||||
}
|
||||
else if(cap == "NPC") {
|
||||
auto b = std::make_unique<npc>();
|
||||
sscanf(param.c_str(), "%lf%lf%08x", &b->where.x, &b->where.y, &b->col);
|
||||
@ -129,6 +140,13 @@ void load_room(fhstream& f, cell *c) {
|
||||
b->text = scanline_noblank(f);
|
||||
r.entities.emplace_back(std::move(b));
|
||||
}
|
||||
else if(cap == "TRADER") {
|
||||
auto b = std::make_unique<trader>();
|
||||
sscanf(param.c_str(), "%lf%lf", &b->where.x, &b->where.y);
|
||||
b->name = scanline_noblank(f);
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user