From 549dfcbc8cbba16ff856a67ef6cf0a0210a6e566 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 21 Dec 2025 14:20:38 +0100 Subject: [PATCH] ru:: combat avoidance experience --- rogueviz/ru/classes.cpp | 21 +++++++++++++++++---- rogueviz/ru/entity.cpp | 10 ++++++++++ rogueviz/ru/load-world.cpp | 9 +++++++++ rogueviz/ru/map.ru | 12 +++++++++++- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index dfb06e6b..2add1c47 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -248,6 +248,7 @@ struct entity { virtual struct shopitem* as_shopitem() { return nullptr; } virtual struct trader* as_trader() { return nullptr; } virtual struct missile* as_missile() { return nullptr; } + virtual struct enemy* as_enemy() { return nullptr; } virtual bool is_disarmer() { return false; } @@ -517,16 +518,21 @@ struct trader : public npc_or_trader { }; struct enemy : public located_entity { - int num_kills; - void on_kill() override { - entity::on_kill(); + int num_kills; // actually includes avoidances too + bool avoided; + void score() { num_kills++; m.experience += (base_xp() * 25 + 24) / (4 + num_kills) / (4 + num_kills); } - virtual void hs(stater& s) override { located_entity::hs(s); s.only_full().act("kills", num_kills, 0); } + void on_kill() override { + entity::on_kill(); + if(!avoided) score(); + } + virtual void hs(stater& s) override { located_entity::hs(s); s.only_full().act("kills", num_kills, 0); s.act("avoided", avoided, false); } void attacked(int s) override; virtual int base_xp() { return 0; } bool hit_by_missile(missile *m) override { return true; } + enemy* as_enemy() override { return this; } }; struct vtrap : public located_entity { @@ -738,6 +744,13 @@ struct hint : public located_entity { bool can_be_hallucinated() override { return false; } }; +struct avoid : public hint { + enemy *whom; + bool done; + void act() override; + virtual void hs(stater& s) override { hint::hs(s); s.act("done", done, false); } + }; + struct item : public located_entity { power *p; int qty; diff --git a/rogueviz/ru/entity.cpp b/rogueviz/ru/entity.cpp index 05063832..0b69980c 100644 --- a/rogueviz/ru/entity.cpp +++ b/rogueviz/ru/entity.cpp @@ -539,6 +539,16 @@ void hint::act() { state = cur; } +void avoid::act() { + bool cur = intersect(get_pixel_bbox(), m.get_pixel_bbox()); + if(gframeid < 300) cur = 0; + if(whom && cur && !state && !whom->avoided && whom->existing && !done) { + whom->avoided = true; done = true; whom->score(); + addMessage(parse_markup(hint_text)); + } + state = cur; + } + xy ferris_platform::location_at(ld t) { return from_hyper(rgpushxto0(to_hyper(ctr)) * xspinpush0(t / game_fps + shift, radius)); } diff --git a/rogueviz/ru/load-world.cpp b/rogueviz/ru/load-world.cpp index d53a8663..516d51ab 100644 --- a/rogueviz/ru/load-world.cpp +++ b/rogueviz/ru/load-world.cpp @@ -309,6 +309,15 @@ void load_room(fhstream& f, cell *c) { b->hint_text = scanline_noblank(f); r.entities.emplace_back(std::move(b)); } + else if(cap == "AVOID") { + auto b = std::make_unique(); + b->respawn = get_xy(); b->size = get_xy(); + b->hint_text = scanline_noblank(f); + b->id = b->hint_text; + for(auto& e: r.entities) if(e->as_enemy()) b->whom = e->as_enemy(); + if(!b->whom) { println(hlog, "AVOID not after any enemy"); } + r.entities.emplace_back(std::move(b)); + } else if(cap == "VISION") { auto b = std::make_unique(); b->col = get_color(); diff --git a/rogueviz/ru/map.ru b/rogueviz/ru/map.ru index 5fb1a4b4..01a02885 100644 --- a/rogueviz/ru/map.ru +++ b/rogueviz/ru/map.ru @@ -233,7 +233,17 @@ 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 BOAR Peppo 210 60 +AVOID 210 300 16 16 +You have avoided combat. You feel like an experienced Rogue. +AVOID 318 176 5 200 +Better to destroy a tree than an animal. Skills of an experienced Wizard. +AVOID 267 87 100 2 +Experienced morphers know that small animals evade big ones. BOAR Pempo 113 255 +AVOID 110 300 16 16 +Avoiding combat feels amazing. +AVOID 60 160 40 2 +Trick and RUN! ITEM 442 65 furry ring Someone lost a small, weird ring here. Hopefully it will be useful to you. @@ -249,7 +259,7 @@ HINT 500 146 60 60 HINT 82 81 10 10 ... but sometimes, you wish you practiced other jumps. HINT 390 50 10 60 -Are you sure you want to fight? Maybe better to use your training instead ('v'-'i' for inventory)? +Are you sure you want to fight with a dagger? Maybe better use your training instead ('v'-'i' for inventory)? OK MOVE 2 Forest Path