summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-01-27 15:07:07 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-01-27 15:07:07 +0000
commit78c738241ffd14b14ea6f7579bb827a617c2187e (patch)
treea7db588a67d6462fa302a71e2f96206c5e4e75a8
parentc6e44918d2d662a753265e7852a3cb538b034300 (diff)
downloadcrawl-ref-78c738241ffd14b14ea6f7579bb827a617c2187e.tar.gz
crawl-ref-78c738241ffd14b14ea6f7579bb827a617c2187e.zip
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
-rw-r--r--crawl-ref/source/beam.cc14
-rw-r--r--crawl-ref/source/direct.cc83
-rw-r--r--crawl-ref/source/effects.cc17
-rw-r--r--crawl-ref/source/enum.h2
-rw-r--r--crawl-ref/source/externs.h44
-rw-r--r--crawl-ref/source/view.cc40
-rw-r--r--crawl-ref/source/view.h2
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 <ESC> 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);