diff --git a/celldrawer.cpp b/celldrawer.cpp index 7ba339ef..2345af20 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -67,6 +67,8 @@ struct celldrawer { void radar_grid(); void do_viewdist(); + + void draw_bowpath(); }; inline void drawcell(cell *c, const shiftmatrix& V) { @@ -2625,54 +2627,7 @@ void celldrawer::add_map_effects() { } } - if(1) { - for(auto& m: bow::last_bowpath) if(m.next.at == c) { - - hyperpoint h0 = C0, t0 = Hypc, h1 = C0, t1 = Hypc; - bool birth = m.first; - - if(!birth) { - ld d = cellgfxdist(c, m.prev.spin) / 2; - h0 = ddspin(c, m.prev.spin) * xpush0(d); - t0 = ddspin(c, m.prev.spin) * xpush(d) * xtangent(-d*2); - } - else birth = true; - - if(!m.last) { - ld d = cellgfxdist(c, m.next.spin) / 2; - h1 = ddspin(c, m.next.spin) * xpush0(d); - t1 = ddspin(c, m.next.spin) * xpush(d) * xtangent(-d*2); - } - - ld t = frac(ptick(PURE?500:250)); - - color_t arrow_color = getcs().swordcolor; - color_t arrow_color_trans = arrow_color & 0xFFFFFF00; - if(bow::fire_mode) arrow_color = gradient(arrow_color_trans, arrow_color, 0, 0.25, 1); - - if(birth) { - if(t > 0.8) { - hyperpoint h = h1 + t1 * (1-t); - hyperpoint tg = -t1; - - poly_outline = OUTLINE_TRANS; - queuepoly(V * rgpushxto0(h) * rspintox(gpushxto0(h) * tg), cgi.shTrapArrow, gradient(arrow_color_trans, arrow_color, 0.8, t, 1)); - poly_outline = OUTLINE_DEFAULT; - } - } - - else { - hyperpoint h = h0 * (1-t) * (1-t) * (1 + 2 * t) + t0 * (1-t) * (1-t) * t + h1 * t * t * (3 - 2 * t) + t1 * t * t * (1-t); - h = normalize(h); - - hyperpoint tg = (h1 - h0) * 6 * t * (1-t) + (3 * t*t - 4*t + 1) * t0 + (2*t-3*t*t) * t1; - - poly_outline = OUTLINE_TRANS; - queuepoly(V * rgpushxto0(h) * rspintox(gpushxto0(h) * tg), cgi.shTrapArrow, arrow_color); - poly_outline = OUTLINE_DEFAULT; - } - } - } + draw_bowpath(); if(c->land == laBlizzard) { if(vid.backeffects) { @@ -2739,6 +2694,57 @@ void celldrawer::add_map_effects() { draw_gravity_particles(); } +void celldrawer::draw_bowpath() { + auto v = at_or_null(bow::bowpath_map, c); + if(!v) return; + for(auto& m: *v) { + + hyperpoint h0 = C0, t0 = Hypc, h1 = C0, t1 = Hypc; + bool birth = m.first; + + if(!birth) { + ld d = cellgfxdist(c, m.prev.spin) / 2; + h0 = ddspin(c, m.prev.spin) * xpush0(d); + t0 = ddspin(c, m.prev.spin) * xpush(d) * xtangent(-d*2); + } + else birth = true; + + if(!m.last) { + ld d = cellgfxdist(c, m.next.spin) / 2; + h1 = ddspin(c, m.next.spin) * xpush0(d); + t1 = ddspin(c, m.next.spin) * xpush(d) * xtangent(-d*2); + } + + ld t = frac(ptick(PURE?500:250)); + + color_t arrow_color = getcs().swordcolor; + color_t arrow_color_trans = arrow_color & 0xFFFFFF00; + if(bow::fire_mode) arrow_color = gradient(arrow_color_trans, arrow_color, 0, 0.25, 1); + + if(birth) { + if(t > 0.8) { + hyperpoint h = h1 + t1 * (1-t); + hyperpoint tg = -t1; + + poly_outline = OUTLINE_TRANS; + queuepoly(V * rgpushxto0(h) * rspintox(gpushxto0(h) * tg), cgi.shTrapArrow, gradient(arrow_color_trans, arrow_color, 0.8, t, 1)); + poly_outline = OUTLINE_DEFAULT; + } + } + + else { + hyperpoint h = h0 * (1-t) * (1-t) * (1 + 2 * t) + t0 * (1-t) * (1-t) * t + h1 * t * t * (3 - 2 * t) + t1 * t * t * (1-t); + h = normalize(h); + + hyperpoint tg = (h1 - h0) * 6 * t * (1-t) + (3 * t*t - 4*t + 1) * t0 + (2*t-3*t*t) * t1; + + poly_outline = OUTLINE_TRANS; + queuepoly(V * rgpushxto0(h) * rspintox(gpushxto0(h) * tg), cgi.shTrapArrow, arrow_color); + poly_outline = OUTLINE_DEFAULT; + } + } + } + void celldrawer::draw_gravity_particles() { unsigned int u = (unsigned int)(size_t)(c); u = ((u * 137) + (u % 1000) * 51) % 1000; diff --git a/crossbow.cpp b/crossbow.cpp index 1824aa05..22ba1e62 100644 --- a/crossbow.cpp +++ b/crossbow.cpp @@ -54,7 +54,7 @@ struct bowscore { EX vector bowpath; -EX vector last_bowpath; +EX map> bowpath_map; EX map target_at; @@ -170,6 +170,15 @@ EX int create_path() { return best_score; } +EX void clear_bowpath() { + bowpath_map.clear(); + } + +EX void gen_bowpath_map() { + bowpath_map = {}; + for(auto& b: bowpath) bowpath_map[b.next.at].push_back(b); + } + EX bool auto_path() { target_at = {}; target_at[1] = cwt.cpeek(); @@ -184,13 +193,13 @@ EX void switch_fire_mode() { if(!fire_mode) { addMessage(XLAT("Double-click tile to fire.")); fire_mode = true; - last_bowpath = {}; + clear_bowpath(); targets = {}; } else if(fire_mode) { addMessage(XLAT("Firing cancelled.")); fire_mode = false; - last_bowpath = {}; + clear_bowpath(); } } @@ -198,7 +207,7 @@ EX void add_fire(cell *c) { bool emp = target_at.empty(); auto& t = target_at[c->cpdist]; if(t == c && !bow::bowpath.empty()) { - bow::last_bowpath.clear(); + clear_bowpath(); checked_move_issue = miVALID; pcmove pcm; pcm.checkonly = false; @@ -220,7 +229,7 @@ EX void add_fire(cell *c) { bow::bowpath = {}; } } - bow::last_bowpath = bow::bowpath; + gen_bowpath_map(); } } @@ -282,9 +291,10 @@ EX void shoot() { } } } - last_bowpath = bowpath; reverse(bowpath.begin(), bowpath.end()); + + gen_bowpath_map(); } EX void showMenu() { diff --git a/pcmove.cpp b/pcmove.cpp index 4fb10866..2372d3bd 100644 --- a/pcmove.cpp +++ b/pcmove.cpp @@ -325,8 +325,8 @@ bool pcmove::movepcto() { fmsActivate = forcedmovetype == fmSkip || forcedmovetype == fmActivate; changes.init(checkonly); - changes.value_keep(bow::last_bowpath); - bow::last_bowpath.clear(); + changes.value_keep(bow::bowpath_map); + bow::bowpath_map.clear(); bool b = (d >= 0) ? actual_move() : stay(); if(checkonly || !b) { changes.rollback(); @@ -334,7 +334,7 @@ bool pcmove::movepcto() { if(!b && items[itCrossbow] == 0 && bow::crossbow_mode() && !bow::fire_mode && d >= 0) { changes.init(checkonly); - changes.value_keep(bow::last_bowpath); + changes.value_keep(bow::bowpath_map); b = try_shooting(true); if(checkonly || !b) changes.rollback(); }