mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2026-10-14 05:11:42 +00:00
rogueviz:: ru:: extra reach powers implemented
This commit is contained in:
@@ -317,6 +317,7 @@ struct entity {
|
||||
|
||||
bool on_floor, fallthru, wallhug, on_bounce, is_stable;
|
||||
int on_ice;
|
||||
moving_platform *on_floor_platform;
|
||||
|
||||
bool destroyed;
|
||||
void kino();
|
||||
@@ -402,6 +403,8 @@ struct statdata {
|
||||
int jump_control, coyote_time, hallucinating;
|
||||
ld detect_area, detect_cross, rough_detect;
|
||||
int heavy_armor, spikes, max_mageshield, stealth_bonus, dodge_value;
|
||||
ld jump_power, gravity_value;
|
||||
int extra_jumps, boost_max;
|
||||
void reset();
|
||||
vector<weaponmod> mods;
|
||||
vector<hr::function<void(int&)>> on_hit;
|
||||
@@ -423,6 +426,7 @@ struct man : public entity {
|
||||
int facing;
|
||||
int on_floor_when;
|
||||
int dresstime;
|
||||
int jumps_used, boost_left;
|
||||
entity *morphed = nullptr;
|
||||
vector<effect> effects;
|
||||
power *use_next_turn;
|
||||
@@ -478,6 +482,7 @@ struct man : public entity {
|
||||
void launch_attack(power *p, int fac, boxfun f);
|
||||
|
||||
virtual void hs(stater& s);
|
||||
virtual double grav() { return entity::grav() / current.gravity_value; }
|
||||
};
|
||||
|
||||
extern man m;
|
||||
@@ -500,6 +505,40 @@ struct moving_platform : public entity {
|
||||
string get_name() override { return get_shape_name() + " platform"; }
|
||||
string get_help() override { return "Moving platforms move."; }
|
||||
bool nonstatic() override { return false; }
|
||||
virtual void jumped_on() {}
|
||||
};
|
||||
|
||||
struct freemoving_platform : public moving_platform {
|
||||
xy last_position;
|
||||
int position_time;
|
||||
xy location_at(ld t) override;
|
||||
virtual void hs(stater& s) {
|
||||
moving_platform::hs(s);
|
||||
s.act("last_position", last_position, xy(0,0))
|
||||
.act("position_time", position_time, 0);
|
||||
}
|
||||
};
|
||||
|
||||
struct floating_bubble_platform : public freemoving_platform {
|
||||
virtual int width() { return 1; }
|
||||
xy siz() override { return {6.*width(), 6}; }
|
||||
void act() override;
|
||||
string glyph() override { return "O"; }
|
||||
color_t color() override { return 0xC0FFFFFF; }
|
||||
string get_name() override { return "floating bubble"; }
|
||||
string get_help() override { return "This upward-floating bubble acts as a temporary platform."; }
|
||||
void jumped_on() override;
|
||||
};
|
||||
|
||||
struct levitating_bubble_platform : public freemoving_platform {
|
||||
virtual int width() { return 1; }
|
||||
xy siz() override { return {6.*width(), 6}; }
|
||||
void act() override;
|
||||
string glyph() override { return "O"; }
|
||||
color_t color() override { return 0xC0FFFFFF; }
|
||||
string get_name() override { return "levitating bubble"; }
|
||||
string get_help() override { return "This levitating bubble acts as a temporary platform."; }
|
||||
void jumped_on() override;
|
||||
};
|
||||
|
||||
struct ferris_platform : public moving_platform {
|
||||
|
||||
+59
-1
@@ -274,13 +274,17 @@ void entity::apply_walls() {
|
||||
bool reset = false;
|
||||
|
||||
if(p->platform_type() == wStaircase) {
|
||||
if(!fallthru) { on_floor = true; zero_vel = zvel; if(rvel.y > 0) rvel.y = 0; }
|
||||
if(!fallthru) {
|
||||
on_floor = true; zero_vel = zvel; if(rvel.y > 0) rvel.y = 0;
|
||||
on_floor_platform = p;
|
||||
}
|
||||
}
|
||||
|
||||
else if(intersect(pb, get_pixel_bbox_at(rmow))) { /* should not happen */ }
|
||||
|
||||
else if(!intersect(pb, get_pixel_bbox_at(rmow + xy(rvel.x, 0))) && rvel.y > 0) {
|
||||
on_floor = true;
|
||||
on_floor_platform = p;
|
||||
rvel.y /= 2;
|
||||
if(abs(rvel.y) < 1e-6) rvel.y = 0;
|
||||
reset = true;
|
||||
@@ -361,6 +365,7 @@ void entity::kill_off_screen() {
|
||||
|
||||
void entity::kino() {
|
||||
on_floor = false;
|
||||
on_floor_platform = nullptr;
|
||||
on_ice = 0;
|
||||
wallhug = false;
|
||||
on_bounce = false;
|
||||
@@ -846,6 +851,59 @@ void kestrel::act() {
|
||||
}
|
||||
}
|
||||
|
||||
xy freemoving_platform::location_at(ld t) {
|
||||
act();
|
||||
if(t == gframeid-1) return last_position;
|
||||
if(t == gframeid) return where;
|
||||
auto h1 = to_hyper(last_position);
|
||||
auto h2 = to_hyper(where);
|
||||
auto d = hdist(h1, h2);
|
||||
auto x = d * (t - (gframeid - 1));
|
||||
return from_hyper(rgpushxto0(h1) * rspintox(gpushxto0(h1) * h2) * xpush0(x));
|
||||
}
|
||||
|
||||
void floating_bubble_platform::act() {
|
||||
if(position_time == gframeid) return;
|
||||
last_position = where;
|
||||
position_time = gframeid;
|
||||
|
||||
stay_on_screen();
|
||||
apply_walls_reflect();
|
||||
apply_vel();
|
||||
|
||||
auto dat = get_dat();
|
||||
bool man_on = intersect(extend(get_pixel_bbox(), 0, 0, dat.d, 0), m.get_pixel_bbox());
|
||||
|
||||
if(man_on) vel.y += dat.d * dat.moda * 0.01;
|
||||
else vel.y -= dat.d * dat.moda * 0.01;
|
||||
|
||||
vel.x = lerp(vel.x, 0, 1. / game_fps);
|
||||
vel.y = lerp(vel.y, 0, 1. / game_fps);
|
||||
}
|
||||
|
||||
void floating_bubble_platform::jumped_on() {
|
||||
auto d = get_dat();
|
||||
vel.y += 1.5 * d.d * d.modv * m.current.jump_power;
|
||||
}
|
||||
|
||||
void levitating_bubble_platform::act() {
|
||||
if(position_time == gframeid) return;
|
||||
last_position = where;
|
||||
position_time = gframeid;
|
||||
|
||||
stay_on_screen();
|
||||
apply_walls_reflect();
|
||||
apply_vel();
|
||||
|
||||
vel.x = lerp(vel.x, 0, 10. / game_fps);
|
||||
vel.y = lerp(vel.y, 0, 10. / game_fps);
|
||||
}
|
||||
|
||||
void levitating_bubble_platform::jumped_on() {
|
||||
auto d = get_dat();
|
||||
vel.y += 1.5 * d.d * d.modv * m.current.jump_power;
|
||||
}
|
||||
|
||||
void healthbubble::act() {
|
||||
stay_on_screen();
|
||||
apply_walls_reflect();
|
||||
|
||||
@@ -54,6 +54,11 @@ void statdata::reset() {
|
||||
mods.clear();
|
||||
on_hit.clear();
|
||||
status_strings.clear();
|
||||
|
||||
jump_power = 1;
|
||||
gravity_value = 1;
|
||||
extra_jumps = 0;
|
||||
boost_max = 0;
|
||||
}
|
||||
|
||||
man::man() {
|
||||
@@ -83,6 +88,9 @@ void man::hs(stater& s) {
|
||||
int prof = (int) profession; s1.act("profession", prof, -1); profession = (stat) prof;
|
||||
for(auto st: allstats) s1.act(statinfos[st].name, base_stats[st], 10);
|
||||
|
||||
s1.act("jumps_used", jumps_used, 0);
|
||||
s1.act("boost_left", boost_left, 0);
|
||||
|
||||
auto sdata = [&s1] (statdata& sd, string prefix) {
|
||||
for(auto st: allstats) s1.act(prefix + statinfos[st].name, sd.stats[st], 10);
|
||||
s1.act(prefix + "jump_control", sd.jump_control, 0);
|
||||
@@ -97,6 +105,11 @@ void man::hs(stater& s) {
|
||||
s1.act(prefix + "max_mageshield", sd.max_mageshield, 0);
|
||||
s1.act(prefix + "stealth_bonus", sd.stealth_bonus, 0);
|
||||
s1.act(prefix + "dodge_value", sd.dodge_value, 0);
|
||||
|
||||
s1.act(prefix + "jump_power", sd.jump_power, 1);
|
||||
s1.act(prefix + "gravity_value", sd.gravity_value, 1);
|
||||
s1.act(prefix + "extra_jumps", sd.extra_jumps, 0);
|
||||
s1.act(prefix + "boost_max", sd.boost_max, 0);
|
||||
};
|
||||
|
||||
sdata(current, "curr.");
|
||||
|
||||
+12
-1
@@ -396,11 +396,22 @@ void gen_powers() {
|
||||
"^", 0xFF0000FF,
|
||||
[] (data& d) {
|
||||
if(d.keystate & 1) {
|
||||
if(m.on_floor) m.jumps_used = 0;
|
||||
bool can_jump = m.on_floor;
|
||||
if(gframeid <= m.on_floor_when + m.current.coyote_time) can_jump = true;
|
||||
if(m.dresstime) can_jump = false;
|
||||
if(can_jump) m.vel.y = m.zero_vel.y-(non_hyperbolic ? 3 : 5) * d.d * d.modv, m.on_floor_when = -1000;
|
||||
if(!can_jump && m.current.extra_jumps > m.jumps_used && !(d.keystate & 2) && !m.dresstime) {
|
||||
m.jumps_used++;
|
||||
can_jump = true;
|
||||
}
|
||||
if(can_jump) {
|
||||
if(m.on_floor_platform) m.on_floor_platform->jumped_on();
|
||||
m.vel.y = m.zero_vel.y-(non_hyperbolic ? 3 : 5) * d.d * d.modv * m.current.jump_power, m.on_floor_when = -1000;
|
||||
}
|
||||
if(m.boost_left > 0) m.next.gravity_value += 1, m.boost_left --;
|
||||
}
|
||||
if(m.boost_left < m.current.boost_max && m.on_floor) m.boost_left++;
|
||||
if(m.boost_left > m.current.boost_max) m.boost_left--;
|
||||
}
|
||||
).is_starting(),
|
||||
|
||||
|
||||
+66
-5
@@ -35,10 +35,71 @@ randeff confux("Confusion", "Makes you unable to tell left and right.", "You fee
|
||||
});
|
||||
|
||||
// jump powers
|
||||
randeff jump_double("Double Jump", "Lets you jump while already in air.", "You feel a strange force in your legs!", [] (data &d) { });
|
||||
randeff jump_high("High Jump", "Lets you jump higher.", "Your legs feel stronger!", [] (data &d) { });
|
||||
randeff jump_bubble("Bubble", "Lets you create bubbles to reach higher places.", "You feel strange bubbles growing in your mouth!", [] (data &d) { });
|
||||
randeff jump_light("Lightness", "Causes you to be less affected by gravity.", "You feel lighter!", [] (data &d) { });
|
||||
randeff jump_double("Double Jump", "Lets you jump while already in air.", "You feel a strange force in your legs!", [] (data &d) {
|
||||
m.next.extra_jumps++;
|
||||
});
|
||||
|
||||
randeff jump_high("High Jump", "Lets you jump higher.", "Your legs feel stronger!", [] (data &d) {
|
||||
m.next.jump_power += 0.5;
|
||||
});
|
||||
|
||||
randeff jump_boost("Boost", "Lets you move upwards during jump.", "Your feet feel magical!", [] (data &d) {
|
||||
m.next.boost_max += game_fps;
|
||||
});
|
||||
|
||||
randeff jump_floating_bubble("Floating Bubble", "Lets you create floating bubbles to reach higher places.", "You feel strange bubbles growing in your mouth!", [] (data &d) {
|
||||
if(d.mode == rev::start || (d.mode == rev::active && d.keystate == 1)) {
|
||||
int bubbles_found = 0;
|
||||
for(auto& e: current_room->entities) if(e->id == "FBUBBLE") {
|
||||
if(e->existing) bubbles_found++;
|
||||
e->existing = false;
|
||||
e->destroyed = true;
|
||||
}
|
||||
if(bubbles_found) return;
|
||||
// auto d = m.get_dat();
|
||||
auto mi = std::make_unique<floating_bubble_platform>();
|
||||
mi->id = "FBUBBLE";
|
||||
// mi->ctr = m.where + xy(m.facing * m.get_scale() * 1.5, 0);
|
||||
mi->hs(fountain_resetter);
|
||||
mi->where = m.where + xy(m.facing * m.get_scale() * m.siz().y * 0.45, 0);
|
||||
mi->vel = m.vel + xy(m.facing * d.modv, 0);
|
||||
current_room->entities.emplace_back(std::move(mi));
|
||||
}
|
||||
});
|
||||
|
||||
randeff jump_levitating_bubble("Levitating Bubble", "Lets you create levitating bubbles to reach higher places.", "You feel strange bubbles growing in your stomach!", [] (data &d) {
|
||||
|
||||
auto& re = *d.re;
|
||||
auto& bubble_available = re.a;
|
||||
|
||||
if(d.mode == rev::start) bubble_available = false;
|
||||
|
||||
if(m.on_floor) bubble_available = true;
|
||||
if(m.on_floor_platform && m.on_floor_platform->id == "LBUBBLE") bubble_available = false;
|
||||
|
||||
if(d.mode == rev::start || (d.mode == rev::active && d.keystate == 1)) {
|
||||
|
||||
int bubbles_found = 0;
|
||||
for(auto& e: current_room->entities) if(e->id == "LBUBBLE") {
|
||||
if(e->existing) bubbles_found++;
|
||||
e->existing = false;
|
||||
e->destroyed = true;
|
||||
}
|
||||
if(bubbles_found || !bubble_available) return;
|
||||
|
||||
bubble_available = false;
|
||||
auto mi = std::make_unique<levitating_bubble_platform>();
|
||||
mi->id = "LBUBBLE";
|
||||
mi->hs(fountain_resetter);
|
||||
mi->where = m.where + xy(0, m.facing * m.get_scale() * m.siz().y * 0.25);
|
||||
mi->vel = m.vel + xy(0, d.modv * 2);
|
||||
current_room->entities.emplace_back(std::move(mi));
|
||||
}
|
||||
});
|
||||
|
||||
randeff jump_light("Lightness", "Causes you to be less affected by gravity.", "You feel lighter!", [] (data &d) {
|
||||
m.next.gravity_value += 1;
|
||||
});
|
||||
|
||||
// trap powers
|
||||
randeff trap_detect("Detect traps", "Lets you see traps and secret passages in a circle around you.", "You see things you could not see before!", [] (data &d) {
|
||||
@@ -308,7 +369,7 @@ void assign_potion_powers() {
|
||||
find_power("health").randeffs = relist{ pick(&health_heal, &health_regen, &health_protect, &health_vampire, &health_bubbles, &health_protect), random_powers[0] };
|
||||
find_power("the thief").randeffs = relist{ pick(&trap_detect, &trap_snake, &trap_disarm, &trap_detect_cross), random_powers[1] };
|
||||
find_power("polymorph").randeffs = relist{ pick(&morph_cat, &morph_capy), random_powers[2] };
|
||||
find_power("reach").randeffs = relist{ pick(&jump_double, &jump_high, &jump_bubble, &jump_light), random_powers[3] };
|
||||
find_power("reach").randeffs = relist{ pick(&jump_double, &jump_high, &jump_light, &jump_boost, &jump_floating_bubble, &jump_levitating_bubble), random_powers[3] };
|
||||
find_power("fire").randeffs = relist{ pick(&fire_spit, &fire_weapon), random_powers[4] };
|
||||
find_power("mystery").randeffs = relist{ random_powers[5], random_powers[6], random_powers[7] };
|
||||
find_power("surprise").randeffs = relist{ random_powers[8] }; // need more random powers
|
||||
|
||||
@@ -314,6 +314,7 @@ void run() {
|
||||
if(m.current.dodge_value) print(ss, " DV ", m.current.dodge_value, "%");
|
||||
if(m.current.heavy_armor) print(ss, " PV ", m.current.heavy_armor, "%");
|
||||
if(m.current.spikes) print(ss, " SP ", m.current.spikes);
|
||||
if(m.current.boost_max) print(ss, " B ", m.boost_left, "/", m.current.boost_max);
|
||||
displayfr(vid.fsize, vid.fsize, 2, vid.fsize, ss.s, titlecolor, 0);
|
||||
if(current_target && current_target->existing)
|
||||
displayfr(vid.xres - vid.fsize, vid.fsize, 2, vid.fsize, "HP " + its(current_target->hp) + "/" + its(current_target->max_hp()) + " " + current_target->get_name(), titlecolor, 16);
|
||||
|
||||
Reference in New Issue
Block a user