summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-08 12:12:19 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-08 12:12:19 +0000
commit4f3558feb5639ff93e46a0795d94d638ef0c89fc (patch)
tree1b42eb5e474a7054dac54a5d50798914b3d99962 /crawl-ref/source
parent06b226a27e7c8f2a9ce8928311fcdfcb7c6a2f79 (diff)
downloadcrawl-ref-4f3558feb5639ff93e46a0795d94d638ef0c89fc.tar.gz
crawl-ref-4f3558feb5639ff93e46a0795d94d638ef0c89fc.zip
Added Water card. Might need some rebalancing.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4127 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/decks.cc105
-rw-r--r--crawl-ref/source/decks.h1
-rw-r--r--crawl-ref/source/dungeon.cc6
-rw-r--r--crawl-ref/source/dungeon.h1
-rw-r--r--crawl-ref/source/stuff.cc100
-rw-r--r--crawl-ref/source/stuff.h26
-rw-r--r--crawl-ref/source/traps.cc14
-rw-r--r--crawl-ref/source/traps.h18
-rw-r--r--crawl-ref/source/view.cc2
9 files changed, 252 insertions, 21 deletions
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc
index e2f8e50bc1..db0f42a7ca 100644
--- a/crawl-ref/source/decks.cc
+++ b/crawl-ref/source/decks.cc
@@ -146,6 +146,7 @@ const deck_archetype deck_of_wonders[] = {
};
const deck_archetype deck_of_dungeons[] = {
+ { CARD_WATER, {5, 5, 5} },
{ CARD_GLASS, {5, 5, 5} },
{ CARD_MAP, {5, 5, 5} },
{ CARD_DOWSING, {5, 5, 5} },
@@ -278,6 +279,7 @@ const char* card_name(card_type card)
case CARD_MINEFIELD: return "the Minefield";
case CARD_GENIE: return "the Genie";
case CARD_TOMB: return "the Tomb";
+ case CARD_WATER: return "Water";
case CARD_GLASS: return "Vitrification";
case CARD_MAP: return "the Map";
case CARD_BANSHEE: return "the Banshee";
@@ -2089,6 +2091,108 @@ static void _sage_card(int power, deck_rarity_type rarity)
}
}
+static void _create_pond(const coord_def& center, int radius, bool allow_deep)
+{
+ radius_iterator ri(center, radius, false);
+ for ( ; ri; ++ri )
+ {
+ const coord_def p = *ri;
+ if ( p != you.pos() && coinflip() )
+ {
+ destroy_trap(p);
+ if ( grd(p) == DNGN_FLOOR )
+ {
+ if ( allow_deep )
+ grd(p) = coinflip() ? DNGN_SHALLOW_WATER : DNGN_DEEP_WATER;
+ else
+ grd(p) = DNGN_SHALLOW_WATER;
+ }
+ }
+ }
+}
+
+static void _deepen_water(const coord_def& center, int radius)
+{
+ radius_iterator ri(center, radius, false);
+ for ( ; ri; ++ri )
+ {
+ // FIXME The iteration shouldn't affect the later squares in the
+ // same iteration, i.e., a newly-flooded square shouldn't count
+ // in the decision as to whether to make the next square flooded.
+ const coord_def p = *ri;
+ if ( grd(p) == DNGN_SHALLOW_WATER &&
+ p != you.pos() &&
+ random2(8) < 1 + count_neighbours(p.x, p.y, DNGN_DEEP_WATER) )
+ {
+ grd(p) = DNGN_DEEP_WATER;
+ }
+ if (grd(p) == DNGN_FLOOR &&
+ random2(3) < random2(count_neighbours(p.x,p.y,DNGN_DEEP_WATER) +
+ count_neighbours(p.x,p.y,DNGN_SHALLOW_WATER)))
+ {
+ grd(p) = DNGN_SHALLOW_WATER;
+ }
+ }
+}
+
+static void _pond_creature_effect( const coord_def& center, int radius )
+{
+ radius_iterator ri(center, radius, false);
+ bool you_affected = false;
+ for ( ; ri; ++ri )
+ {
+ const coord_def p = *ri;
+ if ( p == you.pos() )
+ you_affected = true;
+ else if ( mgrd(p) != NON_MONSTER )
+ mons_check_pool( &menv[mgrd(p)], KILL_YOU );
+ }
+ if ( you_affected )
+ move_player_to_grid( you.x_pos, you.y_pos, false, true, true );
+}
+
+static void _water_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ if ( power_level == 0 )
+ {
+ mpr("You create a pond!");
+ _create_pond(you.pos(), 4, false);
+ _pond_creature_effect(you.pos(), 4);
+ }
+ else if ( power_level == 1 )
+ {
+ mpr("You feel the tide rushing in!");
+ _create_pond(you.pos(), 6, true);
+ for ( int i = 0; i < 2; ++i )
+ _deepen_water(you.pos(), 6);
+ _pond_creature_effect(you.pos(), 5);
+ }
+ else
+ {
+ mpr("Water floods your area!");
+ // Flood all visible squares
+ radius_iterator ri( you.pos(), LOS_RADIUS, false );
+ for ( ; ri; ++ri )
+ {
+ coord_def p = *ri;
+ destroy_trap(p);
+ if ( grd(p) == DNGN_FLOOR )
+ {
+ dungeon_feature_type new_feature = DNGN_SHALLOW_WATER;
+ if ( p != you.pos() && coinflip() )
+ new_feature = DNGN_DEEP_WATER;
+ grd(p) = new_feature;
+ // In the future we might want to place all the water first,
+ // if monsters can scramble out.
+ if ( mgrd(p) != NON_MONSTER )
+ mons_check_pool( &menv[mgrd(p)], KILL_YOU );
+ }
+ }
+ move_player_to_grid( you.x_pos, you.y_pos, false, true, true );
+ }
+}
+
static void _glass_card(int power, deck_rarity_type rarity)
{
const int power_level = get_power_level(power, rarity);
@@ -2560,6 +2664,7 @@ bool card_effect(card_type which_card, deck_rarity_type rarity,
case CARD_EXPERIENCE: _experience_card(power, rarity); break;
case CARD_HELIX: _helix_card(power, rarity); break;
case CARD_SAGE: _sage_card(power, rarity); break;
+ case CARD_WATER: _water_card(power, rarity); break;
case CARD_GLASS: _glass_card(power, rarity); break;
case CARD_DOWSING: _dowsing_card(power, rarity); break;
case CARD_MINEFIELD: _minefield_card(power, rarity); break;
diff --git a/crawl-ref/source/decks.h b/crawl-ref/source/decks.h
index 2245a60d79..a080723d81 100644
--- a/crawl-ref/source/decks.h
+++ b/crawl-ref/source/decks.h
@@ -101,6 +101,7 @@ enum card_type
CARD_SAGE, // skill training
CARD_HELIX, // remove one *bad* mutation
+ CARD_WATER, // flood squares
CARD_GLASS, // make walls transparent
CARD_MAP, // magic mapping
CARD_DOWSING, // detect SD/traps/items/monsters
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 3e7668874f..ea4e30f654 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -1293,7 +1293,7 @@ static int _count_antifeature_in_box(int x0, int y0, int x1, int y1,
}
// count how many neighbours of grd[x][y] are the feature feat.
-static int _count_neighbours(int x, int y, dungeon_feature_type feat)
+int count_neighbours(int x, int y, dungeon_feature_type feat)
{
return _count_feature_in_box(x-1, y-1, x+2, y+2, feat);
}
@@ -1431,7 +1431,7 @@ static void _prepare_shoals(int level_number)
for ( int i = margin; i < GXM - margin; ++i)
for ( int j = margin; j < GYM - margin; ++j)
if (grd[i][j] == DNGN_DEEP_WATER
- && _count_neighbours(i, j, DNGN_FLOOR) > random2(random2(3)+1))
+ && count_neighbours(i, j, DNGN_FLOOR) > random2(random2(3)+1))
{
grd[i][j] = DNGN_SHALLOW_WATER;
}
@@ -1477,7 +1477,7 @@ static void _prepare_shoals(int level_number)
for ( int y = margin; y < GYM - margin; ++y )
if ( grd[x][y] == DNGN_DEEP_WATER )
{
- int badness = _count_neighbours(x, y, DNGN_WATER_STUCK);
+ int badness = count_neighbours(x, y, DNGN_WATER_STUCK);
if ( random2(badness) >= 2 && coinflip() )
grd[x][y] = DNGN_LAVA;
}
diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h
index 0ed5275ecc..7edc1acf49 100644
--- a/crawl-ref/source/dungeon.h
+++ b/crawl-ref/source/dungeon.h
@@ -321,6 +321,7 @@ void replace_area_wrapper(dungeon_feature_type old_feat,
bool unforbidden(const coord_def &c, unsigned mask);
coord_def dgn_find_nearby_stair(dungeon_feature_type stair_to_find,
coord_def base_pos, bool find_closest);
+int count_neighbours(int x, int y, dungeon_feature_type feat);
class mons_spec;
bool dgn_place_monster(mons_spec &mspec,
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index b43efaa035..49f5b4f214 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -75,6 +75,106 @@
#include "tutorial.h"
#include "view.h"
+radius_iterator::radius_iterator( const coord_def& _center, int _radius,
+ bool _roguelike_metric, bool _require_los,
+ bool _exclude_center )
+ : center(_center), radius(_radius), roguelike_metric(_roguelike_metric),
+ require_los(_require_los), exclude_center(_exclude_center),
+ iter_done(false)
+{
+ location.x = center.x - radius;
+ location.y = center.y - radius;
+
+ if ( !this->on_valid_square() )
+ ++(*this);
+}
+
+bool radius_iterator::done() const
+{
+ return iter_done;
+}
+
+coord_def radius_iterator::operator *() const
+{
+ return location;
+}
+
+void radius_iterator::step()
+{
+ const int minx = std::max(X_BOUND_1+1, center.x - radius);
+ const int maxx = std::min(X_BOUND_2-1, center.x + radius);
+ const int maxy = std::min(Y_BOUND_2-1, center.y + radius);
+
+ // Sweep L-R, U-D
+ location.x++;
+ if ( location.x > maxx )
+ {
+ location.x = minx;
+ location.y++;
+ if ( location.y > maxy )
+ iter_done = true;
+ }
+}
+
+void radius_iterator::step_back()
+{
+ const int minx = std::max(X_BOUND_1+1, center.x - radius);
+ const int maxx = std::min(X_BOUND_2-1, center.x + radius);
+ const int miny = std::max(Y_BOUND_1+1, center.y - radius);
+
+ location.x--;
+ if ( location.x < minx )
+ {
+ location.x = maxx;
+ location.y--;
+ if ( location.y < miny )
+ iter_done = true; // hmm
+ }
+}
+
+bool radius_iterator::on_valid_square() const
+{
+ if ( !in_bounds(location) )
+ return false;
+ if ( !roguelike_metric && (location - center).abs() > radius*radius )
+ return false;
+ if ( require_los && !see_grid(location) )
+ return false;
+ if ( exclude_center && location == center )
+ return false;
+ return true;
+}
+
+const radius_iterator& radius_iterator::operator++()
+{
+ do {
+ this->step();
+ } while ( !this->done() && !this->on_valid_square() );
+ return *this;
+}
+
+const radius_iterator& radius_iterator::operator--()
+{
+ do {
+ this->step_back();
+ } while ( !this->done() && !this->on_valid_square() );
+ return *this;
+}
+
+radius_iterator radius_iterator::operator++(int dummy)
+{
+ const radius_iterator copy = *this;
+ ++(*this);
+ return copy;
+}
+
+radius_iterator radius_iterator::operator--(int dummy)
+{
+ const radius_iterator copy = *this;
+ --(*this);
+ return copy;
+}
+
// Crude, but functional.
std::string make_time_string( time_t abs_time, bool terse )
{
diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h
index 42d0006c8b..d7b59c6cb4 100644
--- a/crawl-ref/source/stuff.h
+++ b/crawl-ref/source/stuff.h
@@ -48,6 +48,32 @@ int roll_dice( int num, int size );
int roll_dice( const struct dice_def &dice );
void scale_dice( dice_def &dice, int threshold = 24 );
+class radius_iterator : public std::iterator<std::bidirectional_iterator_tag,
+ coord_def>
+{
+public:
+ radius_iterator( const coord_def& center, int radius,
+ bool roguelike_metric = true,
+ bool require_los = true,
+ bool exclude_center = false );
+ bool done() const;
+ operator bool() const { return !done(); }
+ coord_def operator *() const;
+
+ const radius_iterator& operator ++ ();
+ const radius_iterator& operator -- ();
+ radius_iterator operator ++ (int);
+ radius_iterator operator -- (int);
+private:
+ void step();
+ void step_back();
+ bool on_valid_square() const;
+
+ coord_def location, center;
+ int radius;
+ bool roguelike_metric, require_los, exclude_center;
+ bool iter_done;
+};
int random2limit(int max, int limit);
int stepdown_value(int base_value, int stepping, int first_step,
diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc
index d2d2d30dbf..50473e468b 100644
--- a/crawl-ref/source/traps.cc
+++ b/crawl-ref/source/traps.cc
@@ -471,6 +471,20 @@ void handle_traps(trap_type trt, int i, bool trap_known)
exercise(SK_TRAPS_DOORS, ((coinflip()) ? 2 : 1));
} // end handle_traps()
+void destroy_trap( const coord_def& pos )
+{
+ for ( int i = 0; i < MAX_TRAPS; ++i )
+ {
+ if ( env.trap[i].x == pos.x && env.trap[i].y == pos.y &&
+ env.trap[i].type != TRAP_UNASSIGNED )
+ {
+ grd(pos) = DNGN_FLOOR;
+ env.trap[i].type = TRAP_UNASSIGNED;
+ return;
+ }
+ }
+}
+
void disarm_trap( struct dist &disa )
{
if (you.duration[DUR_BERSERKER])
diff --git a/crawl-ref/source/traps.h b/crawl-ref/source/traps.h
index 793789a935..935ad72629 100644
--- a/crawl-ref/source/traps.h
+++ b/crawl-ref/source/traps.h
@@ -42,25 +42,9 @@ void monster_caught_in_net(monsters *mon, bolt &pbolt);
void player_caught_in_net(void);
void clear_trapping_net(void);
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: misc - mstuff2
- * *********************************************************************** */
void itrap(struct bolt &pbolt, int trapped);
-
-// last updated 3jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc - mstuff2 - spells3
- * *********************************************************************** */
-int trap_at_xy(int which_x, int which_y);
-
-
-// last updated 3jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc - mstuff2 - spells2 - spells3
- * *********************************************************************** */
+void destroy_trap( const coord_def& pos );
dungeon_feature_type trap_category(trap_type type);
-
int trap_at_xy(int x, int y);
trap_type trap_type_at_xy(int x, int y);
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 81deece2d1..a638506992 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -2466,7 +2466,7 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety,
// Count the number of matching features between two points along
// a beam-like path; the path will pass through solid features.
-// By default, it exludes enpoints from the count.
+// By default, it excludes enpoints from the count.
int num_feats_between(int sourcex, int sourcey, int targetx, int targety,
dungeon_feature_type min_feat,
dungeon_feature_type max_feat,