git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4127 c06c8d41-db1a-0410-9941-cceddc491573
VJDLV4PF2ZJ46NERO4LZUX5JE2CD5XBOBQCYYPTFWTHLUEYDUOYAC B7MSPF6X2RLGWN4M6ZZF3WSOPKGYPTTD7LIJVST7DXN27DG6JHNAC AUXVWXWIFSTWFA6VZXN2FMG7FQEKRZVV6MD32VQQ7J2RKCXHAVGAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC 475LL4U4ND6PTNV4XKC7WQAOJC7RF2VCCVX3DRILP2PKIBFYWE6QC MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC BTO5WE4OEK64DZQVNYLOESM74KKQNE7KSNMQVF5UDB26OBKP7ORQC 45EMD3KLQPMERNMIKU5G76H6556XOMIW352TSBP7VLWJX2YYGS7AC YYHCM4CUN6G5PFWPGOYMDYX4P3SGNYUT5SZK5AUWUL2G7RULQJDAC EGV2HM7SD7UQSWJGLR65NQJTUBAJ7WHLM67FMH4UFP7JRSFKREPAC VUP5G3CB6L5I5TPVWMM4KAMF6N4X6UPO4HQZKTSO2ETXZEFBMOMAC CJWCTWT75S4P3OSCMUZ2W6UTWI6GOQMUSBUN6KEN4TVFEG4HHHGQC // 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 );
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;
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-Dlocation.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;}
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;elsegrd(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 squaresradius_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 );}}