From 78c738241ffd14b14ea6f7579bb827a617c2187e Mon Sep 17 00:00:00 2001 From: haranp Date: Sat, 27 Jan 2007 15:07:07 +0000 Subject: Beam-cycling in direction(). You can use SPACE to cycle between beams, ':' to hide the beam. Will probably need a future rewrite...getting this in for testing. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@893 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 14 ++++++-- crawl-ref/source/direct.cc | 83 ++++++++++++++++++++++++++++++++------------- crawl-ref/source/effects.cc | 17 +++------- crawl-ref/source/enum.h | 2 ++ crawl-ref/source/externs.h | 44 +++++++++++++----------- crawl-ref/source/view.cc | 40 +++++++++++++++++++--- crawl-ref/source/view.h | 2 +- 7 files changed, 138 insertions(+), 64 deletions(-) diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 38a2000978..00f8aaea03 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1263,8 +1263,11 @@ void fire_beam( struct bolt &pbolt, item_def *item ) ray_def ray; - find_ray( pbolt.source_x, pbolt.source_y, pbolt.target_x, pbolt.target_y, - true, ray); + if ( pbolt.chose_ray ) + ray = pbolt.ray; + else + find_ray( pbolt.source_x, pbolt.source_y, + pbolt.target_x, pbolt.target_y, true, ray); if ( !pbolt.aimed_at_feet ) ray.advance(); @@ -4398,7 +4401,8 @@ bolt::bolt() : range(0), rangeMax(0), type(SYM_ZAP), colour(BLACK), fr_power(0), foe_power(0), is_tracer(false), aimed_at_feet(false), msg_generated(false), in_explosion_phase(false), smart_monster(false), - can_see_invis(false), is_friendly(false), foe_ratio(0) + can_see_invis(false), is_friendly(false), foe_ratio(0), + chose_ray(false) { } void bolt::set_target(const dist &d) @@ -4409,6 +4413,10 @@ void bolt::set_target(const dist &d) target_x = d.tx; target_y = d.ty; + chose_ray = d.choseRay; + if ( d.choseRay ) + ray = d.ray; + if (d.isEndpoint) aimed_at_spot = true; } diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index bcc7a34cef..ae94aad4d4 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -108,7 +108,9 @@ static command_type read_direction_key() case ESCAPE: return CMD_TARGET_CANCEL; case '?': return CMD_TARGET_DESCRIBE; - case ' ': case '.': return CMD_TARGET_SELECT; + case ' ': return CMD_TARGET_CYCLE_BEAM; + case ':': return CMD_TARGET_HIDE_BEAM; + case '.': return CMD_TARGET_SELECT; case '!': return CMD_TARGET_SELECT_ENDPOINT; case '\\': case '\t': return CMD_TARGET_FIND_PORTAL; @@ -230,6 +232,8 @@ static int targeting_cmd_to_feature( command_type command ) // isValid a valid target or direction was chosen // isCancel player hit 'escape' // isTarget targetting was used +// choseRay player wants a specific ray +// ray ...this one // isEndpoint player wants the ray to stop on the dime // tx,ty target x,y // dx,dy direction delta for DIR_DIR @@ -247,6 +251,8 @@ void direction(struct dist& moves, targeting_type restricts, } int dir = 0; + bool show_beam = false; + ray_def ray; FixedVector < char, 2 > objfind_pos; FixedVector < char, 2 > monsfind_pos; @@ -257,14 +263,13 @@ void direction(struct dist& moves, targeting_type restricts, moves.isMe = false; moves.isCancel = false; moves.isEndpoint = false; + moves.choseRay = false; moves.dx = moves.dy = 0; // XXX change this for default target moves.tx = you.x_pos; moves.ty = you.y_pos; - // XXX Add: ability to cycle between appropriate rays! - mpr(aim_prompt, MSGCH_PROMPT); while (1) @@ -274,7 +279,7 @@ void direction(struct dist& moves, targeting_type restricts, command_type key_command = read_direction_key(); - bool need_redraw = true; + bool need_beam_redraw = false; bool loop_done = false; const int old_tx = moves.tx; @@ -329,6 +334,17 @@ void direction(struct dist& moves, targeting_type restricts, } break; + case CMD_TARGET_CYCLE_BEAM: + show_beam = find_ray(you.x_pos, you.y_pos, moves.tx, moves.ty, + true, ray, (show_beam ? 1 : 0)); + need_beam_redraw = true; + break; + + case CMD_TARGET_HIDE_BEAM: + show_beam = false; + need_beam_redraw = true; + break; + case CMD_TARGET_FIND_YOU: moves.tx = you.x_pos; moves.ty = you.y_pos; @@ -354,7 +370,6 @@ void direction(struct dist& moves, targeting_type restricts, else { flush_input_buffer(FLUSH_ON_FAILURE); - need_redraw = false; } break; @@ -364,7 +379,6 @@ void direction(struct dist& moves, targeting_type restricts, (mode == TARG_ANY) ? "any" : (mode == TARG_ENEMY) ? "enemies" : "friends" ); - need_redraw = false; break; case CMD_TARGET_PREV_TARGET: @@ -372,7 +386,6 @@ void direction(struct dist& moves, targeting_type restricts, if (you.prev_targ == MHITNOT || you.prev_targ == MHITYOU) { mpr("You haven't got a previous target."); - need_redraw = false; break; } @@ -384,7 +397,6 @@ void direction(struct dist& moves, targeting_type restricts, !player_monster_visible( montarget )) { mpr("You can't see that creature any more."); - need_redraw = false; } else { @@ -428,7 +440,6 @@ void direction(struct dist& moves, targeting_type restricts, else { flush_input_buffer(FLUSH_ON_FAILURE); - need_redraw = false; } break; @@ -444,7 +455,6 @@ void direction(struct dist& moves, targeting_type restricts, else { flush_input_buffer(FLUSH_ON_FAILURE); - need_redraw = false; } break; @@ -458,26 +468,18 @@ void direction(struct dist& moves, targeting_type restricts, if (!in_bounds(moves.tx, moves.ty)) break; mid = mgrd[moves.tx][moves.ty]; - if (mid == NON_MONSTER) - { - // XXX we can put in code for describing terrain here - need_redraw = false; + if (mid == NON_MONSTER) // can put in terrain description here break; - } #if (!DEBUG_DIAGNOSTICS) if (!player_monster_visible( &menv[mid] )) - { - need_redraw = false; break; - } #endif describe_monsters(menv[mid].type, mid); redraw_screen(); mesclr(true); break; default: - need_redraw = false; break; } @@ -489,12 +491,13 @@ void direction(struct dist& moves, targeting_type restricts, if ( moves.isTarget && !see_grid(moves.tx, moves.ty) ) { mpr("Sorry, you can't target what you can't see."); - need_redraw = false; } // Ask for confirmation if we're quitting for some odd reason else if ( moves.isValid || moves.isCancel || yesno("Are you sure you want to fizzle?") ) { + moves.choseRay = show_beam; + moves.ray = ray; break; } } @@ -504,12 +507,22 @@ void direction(struct dist& moves, targeting_type restricts, { moves.tx = old_tx; moves.ty = old_ty; - need_redraw = true; // not sure this is necessary + } + + bool have_moved = false; + + if ( old_tx != moves.tx || old_ty != moves.ty ) + { + have_moved = true; + show_beam = show_beam && + find_ray(you.x_pos, you.y_pos, moves.tx, moves.ty, true, ray); } - if ( need_redraw ) + if ( have_moved ) { - // XXX : put in beam redrawing code here + if ( show_beam ) + need_beam_redraw = true; + mesclr(true); if ( !in_vlos(grid2viewX(moves.tx), grid2viewY(moves.ty)) ) describe_oos_square(moves.tx, moves.ty); @@ -517,6 +530,30 @@ void direction(struct dist& moves, targeting_type restricts, describe_cell(moves.tx, moves.ty); } + if ( need_beam_redraw ) + { + viewwindow(true, false); + if ( show_beam && + in_vlos(grid2viewX(moves.tx), grid2viewY(moves.ty)) ) + { + // Draw the new ray + ray_def raycopy = ray; + textcolor(MAGENTA); + while ( raycopy.x() != moves.tx || raycopy.y() != moves.ty ) + { + if ( raycopy.x() != you.x_pos || raycopy.y() != you.y_pos ) + { + if ( !in_los(raycopy.x(), raycopy.y()) ) + break; + gotoxy( grid2viewX(raycopy.x() + 1), + grid2viewY(raycopy.y())); + cprintf("*"); + } + raycopy.advance(); + } + textcolor(LIGHTGREY); + } + } moves.isEndpoint = false; // only relevant at the last step } diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index ea4230b60a..1f304faa06 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -597,20 +597,13 @@ bool acquirement(unsigned char force_class, int agent) continue; // Adding a small constant allows for the occasional - // weapon in an untrained skill. Since the game - // doesn't allow for much in the way of good launchers, - // we'll lower their weight. + // weapon in an untrained skill. - int weight = 0; + const int weight = you.skills[i] + 1; + count += weight; - weight = you.skills[i] + 1; - if (weight) - { - count += weight; - - if (random2(count) < weight) - skill = i; - } + if (random2(count) < weight) + skill = i; } if (skill == SK_STAVES) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 88fdd169b1..607e75ed5c 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -700,6 +700,8 @@ enum command_type CMD_TARGET_OBJ_CYCLE_FORWARD, CMD_TARGET_CYCLE_FORWARD, CMD_TARGET_CYCLE_BACK, + CMD_TARGET_CYCLE_BEAM, + CMD_TARGET_HIDE_BEAM, CMD_TARGET_CENTER, CMD_TARGET_CANCEL, CMD_TARGET_OLD_SPACE, diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 5817437c33..7f8a74d87e 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -167,6 +167,25 @@ struct dice_def dice_def( int n = 0, int s = 0 ) : num(n), size(s) {} }; +struct ray_def +{ + double accx; + double accy; + double slope; + // Quadrant 1: down-right + // Quadrant 2: down-left + // Quadrant 3: up-left + // Quadrant 4: up-right + int quadrant; + int fullray_idx; // for cycling: where did we come from? + + int x() const { return (int)(accx); } + int y() const { return (int)(accy); } + int advance(); // returns the direction taken (0,1,2) + void advance_and_bounce(); + void regress(); +}; + // output from direction() function: struct dist { @@ -176,14 +195,15 @@ struct dist // ty == you.y_pos) bool isEndpoint; // Does the player want the attack to stop at (tx,ty)? bool isCancel; // user cancelled (usually key) + bool choseRay; // user wants a specific beam int tx,ty; // target x,y or logical extension of beam to map edge int dx,dy; // delta x and y if direction - always -1,0,1 + ray_def ray; // ray chosen if necessary // internal use - ignore int prev_target; // previous target }; - struct bolt { // INPUT parameters set by caller @@ -200,7 +220,7 @@ struct bolt char ex_size; // explosion radius (0==none) int beam_source; // NON_MONSTER or monster index # std::string name; - bool is_beam; // beams? (can hits multiple targets?) + bool is_beam; // beams? (can hits multiple targets?) bool is_explosion; bool is_big_cloud; // expands into big_cloud at endpoint bool is_enchant; // no block/dodge, but mag resist @@ -225,6 +245,8 @@ struct bolt bool can_see_invis; // tracer firer can see invisible? bool is_friendly; // tracer firer is enslaved or pet int foe_ratio; // 100* foe ratio (see mons_should_fire()) + bool chose_ray; // do we want a specific ray? + ray_def ray; // shoot on this specific ray public: // A constructor to try and fix some of the bugs that occur because @@ -235,24 +257,6 @@ public: void set_target(const dist &); }; -struct ray_def -{ - double accx; - double accy; - double slope; - // Quadrant 1: down-right - // Quadrant 2: down-left - // Quadrant 3: up-left - // Quadrant 4: up-right - int quadrant; - - int x() const { return (int)(accx); } - int y() const { return (int)(accy); } - int advance(); // returns the direction taken (0,1,2) - void advance_and_bounce(); - void regress(); -}; - struct run_check_dir { unsigned char grid; diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 9802222118..b9d8916114 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1434,14 +1434,34 @@ static void set_ray_quadrant( ray_def& ray, int sx, int sy, int tx, int ty ) mpr("Bad ray quadrant!", MSGCH_DIAGNOSTICS); } +static int cyclic_offset( unsigned int ui, int cycle_dir, int startpoint, + int maxvalue ) +{ + const int i = (int)ui; + if ( startpoint < 0 ) + return i; + switch ( cycle_dir ) + { + case 1: + return (i + startpoint + 1) % maxvalue; + case -1: + return (i - 1 - startpoint + maxvalue) % maxvalue; + case 0: + default: + return i; + } +} // Find a nonblocked ray from sx, sy to tx, ty. Return false if no // such ray could be found, otherwise return true and fill ray // appropriately. // If allow_fallback is true, fall back to a center-to-center ray // if range is too great or all rays are blocked. +// If cycle_dir is 0, find the first fitting ray. If it is 1 or -1, +// assume that ray is appropriately filled in, and look for the next +// ray in that cycle direction. bool find_ray( int sourcex, int sourcey, int targetx, int targety, - bool allow_fallback, ray_def& ray ) + bool allow_fallback, ray_def& ray, int cycle_dir ) { int cellray, inray; @@ -1450,17 +1470,25 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety, const int absx = signx * (targetx - sourcex); const int absy = signy * (targety - sourcey); int cur_offset = 0; - for ( unsigned int fullray = 0; fullray < fullrays.size(); - cur_offset += raylengths[fullray++] ) { + for ( unsigned int fray = 0; fray < fullrays.size(); ++fray ) + { + const int fullray = cyclic_offset( fray, cycle_dir, ray.fullray_idx, + fullrays.size() ); + // yeah, yeah, this is O(n^2). I know. + cur_offset = 0; + for ( int i = 0; i < fullray; ++i ) + cur_offset += raylengths[i]; for ( cellray = 0; cellray < raylengths[fullray]; ++cellray ) { if ( ray_coord_x[cellray + cur_offset] == absx && - ray_coord_y[cellray + cur_offset] == absy ) { + ray_coord_y[cellray + cur_offset] == absy ) + { // check if we're blocked so far bool blocked = false; - for ( inray = 0; inray < cellray; ++inray ) { + for ( inray = 0; inray < cellray; ++inray ) + { if (grid_is_solid(grd[sourcex + signx * ray_coord_x[inray + cur_offset]][sourcey + signy * ray_coord_y[inray + cur_offset]])) { blocked = true; @@ -1472,6 +1500,7 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety, { // success! ray = fullrays[fullray]; + ray.fullray_idx = fullray; if ( sourcex > targetx ) ray.accx = 1.0 - ray.accx; if ( sourcey > targety ) @@ -1496,6 +1525,7 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety, ray.slope = -ray.slope; } set_ray_quadrant(ray, sourcex, sourcey, targetx, targety); + ray.fullray_idx = -1; return true; } return false; diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h index a4eba7d894..f655bb1ce9 100644 --- a/crawl-ref/source/view.h +++ b/crawl-ref/source/view.h @@ -147,7 +147,7 @@ unsigned char get_magicmap_char(int feature); void viewwindow(bool draw_it, bool do_updates); bool find_ray( int sourcex, int sourcey, int targetx, int targety, - bool allow_fallback, ray_def& ray ); + bool allow_fallback, ray_def& ray, int cycle_dir = 0 ); dungeon_char_type dchar_by_name(const std::string &name); -- cgit v1.2.3-54-g00ecf