git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9600 c06c8d41-db1a-0410-9941-cceddc491573
IFYZSFWJRTV6JM46H6U4CMTQX46VT562EAM64Y6UYU3F6RDWRRYQC E5QW4MGLHCPXY3SLW5RWJGOSSVELCQZOFE336BXUM7IRYDJ6PGWAC PVIRCYXVGCHO4J2Q7P5S6PIYAGUE3D74FNB5PXMEDYUAJEW2YRHAC FL5OQVX5UXHYHPKC2YZ3PSD4QQ6OHRYXBIVSSKR4RIPUJNC3TORAC R6YKWD4UXOQ3ULO6VISUMJURT3XHOHYQILKKSASLWEBL7MQP2UCQC CDEJUVHMOT2SRPKWBB5IUPAXPGX6TUTGRBFLSPTR4XNZABDLSNUQC 5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC TYAUNNAVB4GEKXYSR447JXRDKRJJZHAVV7XLWGU7RXEP5JMJCQKAC GYOKKBVTZ6HRW2NYC3EMGSB6ULBX24L5DLDZNEP2F6UTA4KPU3CAC KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC QF5LILALY55UNUHCZE22D6FGPJOJJKNJQFLBMRACMBWJBSO7PMCQC 542WW2UJM6XF22442ZD5NFMTS6HTDM74JKJ7GQHBLQ3D6C6T4C3AC HGVNTG4FUR6CXYG6NFUGEC7LYGHUTJZBVLYOYNDNYKGXDYEIQVEAC 7GCM5WFIKX5N2PQ5UCVNMFJEKTZTBCUVZH5RZ7CPDL3Z6GB26KAQC PUY2VWZJ3G7HNCLIHZP5VGT2DAGHI436ETDJQTPEBFPRSEHOM2NQC 43XCHFXZ34FDVT2QG23RZ65V6NRBY6PE3ENQEEDXFYKRR7IRFHCAC TPJYUAKSEZMCCCJANJ5EQ7F67QVTPFEOWBD7WYK33NLRN657Y5VQC TRBDS4IKHBASW2CTAQ2YHMBMBMRB6QEBQ4ZE7GRSR3U2VJXA7TJQC FYSQ7HXDIKXZXDGYVKZMODW7HYQQLRZO52Q2HVM3PYBD37UT5B4AC HCVH2CWL32UD66O6Z7ZYDUASWN3RF5TW6FSWURGMD7MELKB772FAC 2NVJIPJ5NMHUI2J4WOR6KE4XZOCJIVWHQK4M2M6KG7PL24PGBDGAC ERS7DYNAVCC7QUVG5FXJJRONYESLZU22CQGKCA5HLLLG6DMXYRLQC XYQFJLTMLSU7LC7VODUJVN5F2P47STH2KVSP7Q3BSCUUDRHROW7QC 6DNNPEMZGBQDMA7YG4LCTQUVZ7LYPC3R4A2XBYT5SDQ65GYOLJVAC PTJJ6D52LDVJN7WA7NMYV2WHH3WJMWWLRGF3D7ZSBUNLAACFRJHAC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC GSQRBVGYRLPXA34WXHXF5HNKDC4YEJ3XGKPVO4T3LKNEZHRGXQIAC SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC 7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC QSRRV725GCNDOMIDS36NYAA65MOLDMAZSENVSZ3PNOLBFSGHH7BQC JR2RAQ523LOWNDYJNK6AZVKI6WVMI622PIV72XWOVZYPXPUKSQWAC DKRSOHZXL6EPSLKOKHF7GJXSZEJVY7CXGACSHWLM5B5FTRETWWCAC VBZ7XKM6PIJA6CGSHSE7E3Q5GFJ2DUWYGWIOBYJXTPI5NCY7FNAAC LXVO45D6K6HCT2LOHMCQIT76VFKX6OFQOQSUAEHR3U32G43TPEBQC 4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC 3RNRFLMD2X4RUFTDVITLXAP377YB6F6YMQLL3DAXSUZDZBTWSLRQC JWJGOMVBPZRSP2VSHLFFFDIF2CS6UPBA6AHL7DAJWGBCHAV3PJDQC ZEFGFQHN6J2S6EIPX7EPDG22C5YXTI6DMKQHHRCLWN5MQC44KY3AC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC OO5PVQJ7B3HMIV46B5BIEKJNBZHQSXL3DJOGINRLLSTGSM67KYZAC VEPHAIXR3GSPHBLOW5DWFFU4ULEMVWRQG4G5PKSKRA2I6RHYROUAC CB7U6IEEN2Z74672EYQQHWTB4GXVNNMAYDRQYAGY6K3QSDYYEHYAC MDAJYB6STTZPNHRQ2X66MMMSONMKXTESLHJSFPGN7H3D3TOVBAVAC QLEBDRVUQ3BMCT7LV4EBPG7T5X4KMQJAVLMLHHB7DRCNNGDQBRNQC 5FBOE2QNRLKUNOP54CZD6LFAMM7LX6NNLHJRJHRDDIUTQ7J723DQC VEHHZZFWDG5M4IXTCXXMKH3S2FSXTZ4CD23J6AYVFEPY7PBZ7GWQC 3ZWALZFSTSIVYXY4BAY6ANGINTDACZC6RSSJTEMQSTSUIE66YOBQC NQIXUYGUIQTKZUB2IQDII7BBDMZ4VN4NUUTGT2ARQBZTDJUMPKRQC E3D6MYCPSZJ64PQY4QLRJ2XCMKHHF3AOXM6I7JUEI5T2HMXCI7HQC 4HLF6Q3OBOOHCCJ76L2BXVIYI6EMJ2G7O4XXZPFTLFP6BQGSUZNAC PHBACPMH3F34GODHVDKNCMXWU373RJQGVTDLBFCCDLLWDXVYOLTAC AZ2RCXNVULJUSCBDBK3VARTUCTPEJXHTA7ALP73S4EXLJB6YYB5QC 2YM5FZ7I6XD6P3VUL4ALJKNEHHX2VIRONLRDX2QPXZOLCP3FNBTQC YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC RQ24Y25QDO2GY65XESEVBCP6VXCB7BDTWXO42IPPI6UPRJQ5XYDAC HIRKGUMNJPWKSVTR6TVBPD3MWNA63CEHCLCIPWEMGDFHVB3NPLDQC ENOQQ6DEA6ECRNTBGYYNK7G3DFEILMKQBNKP4SUQIZW2L6HWVR7QC TO43FWKHNIA5MVDOFXYHQODTLBQYEZKX5UIUGID57436UF7G2EXQC TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC HB27XKFYVYIEQZGBCEZ6LKPUBMXLIPDAAS636GJ5TULIQ7KND5KQC 7DHFQM7MCCELAZL3YR53E263WMSQHQECCI5D7MCPQEF7B56IB2EAC GP7RUHLNB4KISSZAENEYVNY3MB5YRCFRWRWYAROBZIQ5MR4DXB7QC NMZFCCM6O3KO2GJWKOSULN27B3QIZKWPBOB62PAILXMRQD4JMIMAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC DINIHMHQWCV7UKXHNIA2TLT2ZOO5IYJJE7GMI3XUAWYIR37AKD2QC RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC CRQ3WJCOA5X7MWZYVUDQMO4N5BU6NSCMPFTO3ENLNRCT5U3ONBPAC QK7YLIH7SWBSL3OEBQJYVFNTW4XT5FF6U3GPKW7PEGHBLPV3TVQAC return (you.gift_timeout > 0 && you.piety >= random2(MAX_PIETY+1));
if (you.gift_timeout == 0)return (false);// At high tension Xom is more likely to be nice.int tension_bonus = (tension <= 0 ? 0 : random2(tension));// Whether Xom is nice depends largely on his mood (== piety).return (x_chance_in_y(you.piety + tension_bonus, MAX_PIETY + 1));
// Make sure there's at least one enemy within the lightning radius.bool found_hostile = false;for (radius_iterator ri(you.pos(), 2, true, true, true); ri; ++ri){if (monsters* mon = monster_at(*ri)){if (!mons_wont_attack(mon)){found_hostile = true;break;}}}// No hostiles within radius.if (!found_hostile)return (false);bool protection = false;
take_note(Note(NOTE_MESSAGE, 0, 0, "XOM: divine lightning"), true);
static char lightning_buf[80];snprintf(lightning_buf, sizeof(lightning_buf),"XOM: divine lightning%s", protection ? " (protected)" : "");take_note(Note(NOTE_MESSAGE, 0, 0, lightning_buf), true);
static bool _move_stair(coord_def stair_pos, bool away){dungeon_feature_type feat = grd(stair_pos);ASSERT(grid_stair_direction(feat) != CMD_NO_CMD);coord_def begin, towards;bool stairs_moved = false;if (away){// If the staircase starts out under the player first shove it onto// a neighbouring grid.if (stair_pos == you.pos()){coord_def new_pos(stair_pos);int adj_count = 0;for (adjacent_iterator ai(stair_pos); ai; ++ai)if (grid_stair_direction(grd(*ai)) == CMD_NO_CMD&& one_chance_in(++adj_count)){new_pos = *ai;}if (new_pos == stair_pos)return (false);if (!slide_feature_over(stair_pos, new_pos))return (false);
stair_pos = new_pos;stairs_moved = true;}begin = you.pos();towards = stair_pos;}else{// Can't move towards player if it's already adjacent.if (adjacent(you.pos(), stair_pos))return (false);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 (stairs_moved);}// 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 (stairs_moved);}if (away && !found_stairs){if (grid_is_solid(ray.pos())){// Transparent wall between stair and player.return (stairs_moved);}mpr("Ray didn't cross stairs.", MSGCH_ERROR);}if (away && past_stairs <= 0){// Stairs already at edge, can't move further away.return (stairs_moved);}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 (stairs_moved);}}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.name = "STAIR BEAM";beam.draw_delay = 50; // Make beam animation slower than normal.beam.aimed_at_spot = true;beam.fire();// 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());return (stairs_moved);}return (true);}static bool _repel_stairs(){// Repeating the effect while it's still active is boring.if (you.duration[DUR_REPEL_STAIRS_MOVE]|| you.duration[DUR_REPEL_STAIRS_CLIMB]){return (false);}std::vector<coord_def> stairs_avail;for (radius_iterator ri(you.pos(), LOS_RADIUS, false, true); 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);}}// Should only happen if there are stairs in view.if (stairs_avail.empty()){mpr("No stairs found!");return (false);}god_speaks(GOD_XOM,_get_xom_speech("repel stairs").c_str());you.duration[DUR_REPEL_STAIRS_MOVE] = 1000;if (one_chance_in(5)|| grid_stair_direction(grd(you.pos())) != CMD_NO_CMD&& grd(you.pos()) != DNGN_ENTER_SHOP){you.duration[DUR_REPEL_STAIRS_CLIMB] = 500;}std::random_shuffle(stairs_avail.begin(), stairs_avail.end());int count_moved = 0;for (unsigned int i = 0; i < stairs_avail.size(); i++)if (_move_stair(stairs_avail[i], true))count_moved++;if (!count_moved){if (one_chance_in(8))mpr("Nothing appears to happen... Ominous!");elsecanned_msg(MSG_NOTHING_HAPPENS);}#ifdef NOTE_DEBUG_XOMtake_note(Note(NOTE_MESSAGE, 0, 0, "XOM: repel stairs"), true);#endifreturn (true);}
if (niceness && !one_chance_in(20))
#ifdef DEBUG_XOMstatic char xom_buf[100];snprintf(xom_buf, sizeof(xom_buf), "xom_acts(%s, %d, %d), mood: %d",(niceness ? "true" : "false"), sever, tension, you.piety);take_note(Note(NOTE_MESSAGE, 0, 0, xom_buf), true);#endifif (niceness && !one_chance_in(15))
if (you.religion != GOD_NO_GOD)
if (you.religion == GOD_XOM){snprintf(god_colour_tag, sizeof god_colour_tag, "<%s>",colour_to_str(god_colour(you.religion)).c_str());if (you.gift_timeout == 0)godpowers += " - BORED";else if (you.gift_timeout == 1)godpowers += " - getting BORED";}else if (you.religion != GOD_NO_GOD)
if (!quiet){mprf("Your %s glows black for a moment.",item.name(DESC_PLAIN).c_str());// If we get the message, we know the item is cursed now.item.flags |= ISFLAG_KNOW_CURSE;}item.flags |= ISFLAG_CURSED;
if (wpn.base_type != OBJ_WEAPONS && wpn.base_type != OBJ_MISSILES|| !is_cursed&& !is_enchantable_weapon(wpn, true, true)&& !is_enchantable_weapon(wpn, true, false)){canned_msg(MSG_NOTHING_HAPPENS);id_the_scroll = false;break;}// It's a weapon or stack of missiles that is not an artefact// and not fully enchanted, or at least needs to be uncursed.
_handle_enchant_weapon(ENCHANT_TO_HIT, true);if (coinflip())_handle_enchant_weapon(ENCHANT_TO_HIT, true);if (is_cursed)do_uncurse_item(wpn);
}else{canned_msg(MSG_NOTHING_HAPPENS);id_the_scroll = false;
mprf("%s slides away from you right after you %s through it!",stair_str.c_str(), verb.c_str());
if (coinflip()&& slide_feature_over(you.pos(), coord_def(-1, -1), false)){mprf("%s slides away from you right after you %s through ""it!", stair_str.c_str(), verb.c_str());}if (coinflip()){// Stairs stop fleeing from you now you actually caught one.mprf("%s settles down.", stair_str.c_str(), verb.c_str());you.duration[DUR_REPEL_STAIRS_MOVE] = 0;you.duration[DUR_REPEL_STAIRS_CLIMB] = 0;}