summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/decks.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-19 05:12:15 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-19 05:12:15 +0000
commit30824b7084af3c2dce35d2eae4d4600f67ab4e06 (patch)
tree852963a375c0c492fd9202bfa2d1d64842b4f285 /crawl-ref/source/decks.cc
parent10391ff4e676a29fbc2836d1494ed2aae4b112a7 (diff)
downloadcrawl-ref-30824b7084af3c2dce35d2eae4d4600f67ab4e06.tar.gz
crawl-ref-30824b7084af3c2dce35d2eae4d4600f67ab4e06.zip
Added "The Stairs" card (not yet in any deck), eventually to be the card which
re-arranges all stairs on the level, but now is just used to test the code used to move stairs in LOS away or towards the player. Added beam flavour BEAM_VISUAL for animating someting moving in a line which doesn't have any effects on its own, and removed BEAM_LINE_OF_SIGHT, which was no longer being used. Added bolt structure field "delay", which can be used to change the delay between animating each square in a beam from the default of 15 msec. For eventual use as a Xom effect added the stairs-are-avoiding-you durations DUR_REPEL_STAIRS_MOVE and DUR_REPEL_STAIRS_CLIMB. If DUR_REPEL_STAIRS_MOVE alone is set then stepping onto a stairs/portal/etc has a 50% chance of making it move away in a random direction. If DUR_REPEL_STAIRS_CLIMB alone is set then attempting to climb a stairs/etc has a 50% chance of making it move away before you can get through it (and ending your turn in the process). If both are set then moving onto it and attempting to climb each have a 29% chance of making it move, for a combined chance of 49.59% of a move-and-climb making the stairs move away. Once a stair is successfully taken there's a 50% chance of the stair on the other end moving away from the player, and then both durations are reset to 0. These can be tested by drawing The Stairs card ("&c stair"), which will set DUR_REPEL_STAIRS_CLIMB if you're on top of a stair or DUR_REPEL_STAIRS_MOVE if your'e not. Added a few wizard targetting command placeholders. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7865 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/decks.cc')
-rw-r--r--crawl-ref/source/decks.cc157
1 files changed, 157 insertions, 0 deletions
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc
index 2bba3b68af..025f7a283d 100644
--- a/crawl-ref/source/decks.cc
+++ b/crawl-ref/source/decks.cc
@@ -276,6 +276,7 @@ const char* card_name(card_type card)
case CARD_DOWSING: return "Dowsing";
case CARD_TROWEL: return "the Trowel";
case CARD_MINEFIELD: return "the Minefield";
+ case CARD_STAIRS: return "the Stairs";
case CARD_GENIE: return "the Genie";
case CARD_TOMB: return "the Tomb";
case CARD_WATER: return "Water";
@@ -1550,6 +1551,161 @@ static void _minefield_card(int power, deck_rarity_type rarity)
}
}
+static int stair_draw_count = 0;
+
+static void _move_stair(coord_def stair_pos, bool away)
+{
+ ASSERT(stair_pos != you.pos());
+
+ dungeon_feature_type feat = grd(stair_pos);
+ ASSERT(grid_stair_direction(feat) != CMD_NO_CMD);
+
+ coord_def begin, towards;
+
+ if (away)
+ {
+ begin = you.pos();
+ towards = stair_pos;
+ }
+ else
+ {
+ // Can't move towards player if it's already adjacent.
+ if (adjacent(you.pos(), stair_pos))
+ return;
+
+ begin = stair_pos;
+ towards = you.pos();
+ }
+
+ ray_def ray;
+ if (!find_ray(begin, towards, true, ray, 0, true))
+ {
+ mpr("Couldn't find ray between player and stairs.", MSGCH_ERROR);
+ return;
+ }
+
+ // Don't start off under the player.
+ if (away)
+ ray.advance();
+
+ bool found_stairs = false;
+ int past_stairs = 0;
+ while ( in_bounds(ray.pos()) && see_grid(ray.pos())
+ && !grid_is_solid(ray.pos()) && ray.pos() != you.pos() )
+ {
+ if (ray.pos() == stair_pos)
+ found_stairs = true;
+ if (found_stairs)
+ past_stairs++;
+ ray.advance();
+ }
+ past_stairs--;
+
+ if (!away && grid_is_solid(ray.pos()))
+ // Transparent wall between stair and player.
+ return;
+
+ if (away && !found_stairs)
+ {
+ if (grid_is_solid(ray.pos()))
+ // Transparent wall between stair and player.
+ return;
+
+ mpr("Ray didn't cross stairs.", MSGCH_ERROR);
+ }
+
+ if (away && past_stairs <= 0)
+ // Stairs already at edge, can't move further away.
+ return;
+
+ if ( !in_bounds(ray.pos()) || ray.pos() == you.pos() )
+ ray.regress();
+
+ while (!see_grid(ray.pos()) || grd(ray.pos()) != DNGN_FLOOR)
+ {
+ ray.regress();
+ if (!in_bounds(ray.pos()) || ray.pos() == you.pos()
+ || ray.pos() == stair_pos)
+ {
+ // No squares in path are a plain floor.
+ return;
+ }
+ }
+
+ ASSERT(stair_pos != ray.pos());
+
+ std::string stair_str =
+ feature_description(stair_pos, false, DESC_CAP_THE, false);
+
+ mprf("%s slides %s you!", stair_str.c_str(),
+ away ? "away from" : "towards");
+
+ // Animate stair moving.
+ const feature_def &feat_def = get_feature_def(feat);
+
+ bolt beam;
+
+ beam.range = INFINITE_DISTANCE;
+ beam.flavour = BEAM_VISUAL;
+ beam.type = feat_def.symbol;
+ beam.colour = feat_def.colour;
+ beam.source = stair_pos;
+ beam.target = ray.pos();
+ beam.delay = 50; // Make beam animation slower than normal.
+ beam.name = "STAIR BEAM";
+
+ beam.aimed_at_spot = true;
+
+ fire_beam(beam);
+
+ // Clear out "missile trails"
+ viewwindow(true, false);
+
+ if (!swap_features(stair_pos, ray.pos(), false, false))
+ mprf(MSGCH_ERROR, "_move_stair(): failed to move %s",
+ stair_str.c_str());
+}
+
+static void _stairs_card(int power, deck_rarity_type rarity)
+{
+ UNUSED(power);
+ UNUSED(rarity);
+
+ you.duration[DUR_REPEL_STAIRS_MOVE] = 0;
+ you.duration[DUR_REPEL_STAIRS_CLIMB] = 0;
+
+ if (grid_stair_direction(grd(you.pos())) == CMD_NO_CMD)
+ you.duration[DUR_REPEL_STAIRS_MOVE] = 1000;
+ else
+ you.duration[DUR_REPEL_STAIRS_CLIMB] = 1000;
+
+ std::vector<coord_def> stairs_avail;
+
+ radius_iterator ri(you.pos(), LOS_RADIUS, false, true, true);
+ for (; ri; ++ri)
+ {
+ dungeon_feature_type feat = grd(*ri);
+ if (grid_stair_direction(feat) != CMD_NO_CMD
+ && feat != DNGN_ENTER_SHOP)
+ {
+ stairs_avail.push_back(*ri);
+ }
+ }
+
+ if (stairs_avail.size() == 0)
+ {
+ mpr("No stairs available to move.");
+ return;
+ }
+
+ std::random_shuffle(stairs_avail.begin(), stairs_avail.end());
+
+ for (unsigned int i = 0; i < stairs_avail.size(); i++)
+ _move_stair(stairs_avail[i], stair_draw_count % 2);
+
+ stair_draw_count++;
+}
+
static int _drain_monsters(coord_def where, int pow, int garbage)
{
UNUSED( garbage );
@@ -2794,6 +2950,7 @@ bool card_effect(card_type which_card, deck_rarity_type rarity,
case CARD_GLASS: _glass_card(power, rarity); break;
case CARD_DOWSING: _dowsing_card(power, rarity); break;
case CARD_MINEFIELD: _minefield_card(power, rarity); break;
+ case CARD_STAIRS: _stairs_card(power, rarity); break;
case CARD_GENIE: _genie_card(power, rarity); break;
case CARD_CURSE: _curse_card(power, rarity); break;
case CARD_WARPWRIGHT: _warpwright_card(power, rarity); break;