git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6669 c06c8d41-db1a-0410-9941-cceddc491573
LUH6GAJODIQXNPBEHMSUTKH3KA3DYVRCKZ6GJJ4HHNHOIMMUEP6QC
FY7SUVHPQO6D6EXYPZAZCNSBP53AOE32EL7HQHPN2J2CM3GDZ26QC
LRSBPYUTFVUVZ3QLP6VGQSWNTJYFJQGY5VQOUYYUSNYAQMJZ5C2QC
C45PIBBXMIZKQPJYBJSOAAQZ2OESW27PYDMERYBSLML4SYX5DDZQC
LMRRQE4ZXQYZPXVGBTDZP7LEIM6OGSSOOQ5FAOWXJCDCNCECX5VAC
5XNQ3SSNBFXFNWA6DPM74W6FH65NX665P3DMH6YCWVFOPZTJSYCQC
R2DQBWKIW7YUJB5SOQ7J274JIYRVX4H3ISFRPAL5RG2RVVP4G2KAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
2O3C3MTT2ZBYIFGPJ4MF5R4AXBYUHOEN62KAUWFWF6JWHIIVLRNQC
GF5VGZLKKWIATLVLTUJR4LVEQZAKR7CWMLNFMJXA67WLHP7JNUUAC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
S34LKQDIQJLIWVIPASOJBBZ6ZCXDHP5KPS7TRBZJSCDRVNCLK6UAC
7KVPF74ACO6Q5FXS2YBBJTJT4Y4YN2M3ZNIPXFI3QSQNGNTHD7AAC
DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC
VCG3BRIYRTNNWYC3LOXD6KFGXOX37HAFW2HNV7WXVG2V7EUHLDZQC
4PGOIN7EO5PXZHDRHBIWFTT4UI6QTINSWVN333R7S6VHFMOYQYIAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
AUXVWXWIFSTWFA6VZXN2FMG7FQEKRZVV6MD32VQQ7J2RKCXHAVGAC
CHO4U5JC3RNTLXVIDXXJYZMOBZJ4VXW2GVJWDOTBRKK3AJ36LDLQC
FIYBXLWALQINNQTHG2KNDUUTAQAZRDDLXW2XOVSKDKBADJ3XCJ4AC
KOSAQXB3KF6VAYTG2TOTHGJBB3F7AL6O32EMCXPVZJ5WHQX6XR5AC
RQFQSU37Y3ZBFR634JWYHE77LIOOINGBRNL4KUHPPRA3ZR6W5QIAC
KATZLWENEIQMKKWIV4ZLXJ5HFUW6SU5K4ZU6NENBOL4XAAVTDUKAC
AREBCIU2RU2RNHBWD4GARWEBKSL7HDFGDLII22H56OJO2AQUOMLQC
UURAYLSSITZLQR56MCWFPIWMECU7F3USMA2UPJAO4IPIY5WVKP5QC
ZLQAAP55CJ77XIJN3DZVPT4GTTVLIBFJLIJJKI6L5UBSHX7VUK6AC
QKGDOYIYKE6B36ION5O2DRW65DWWPZMYNWJVH7LJJ7FPGGM2MYAQC
B62ICMDTN5V7R7RBL4JALFVKEMVOOVLRSJASRNYS6CGFWBEEF5JQC
UEI5JAVCMN7Y2SACTEZPZSNFJWOJTC55G24Q6LKQCT4XNDH5ZQIAC
TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC
CUB27EJDQG66FF2YCKOV4HU3LAJVJIHUJ5QYLURRDIEVGPK666DQC
PFEJ4LMDNEKLMGRCMWQ7EIRVU4JMYGICI4G7X4WVWOROVXQCBZ7QC
DMN63LCKBTJZN3X2XKYFV2XY3AEKDRJJTKBANH3TT6ZDPELAA3MQC
7YUGK5Q64KG5O7GJGTUBRRLHAHBCJ5YOE23YUPT6UBKUSB67CYAQC
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC
KKEPQAZMWQFWPQ4P4KT5PWG2YFPG7H4JHL5K7USVHQ3Y6L4NWURQC
B4X67DGLW77QLGPTMORE2EJ5K5VA3TWIU23HFUF4TZDODXQSFLRQC
CGYTZT5QWIEGYKUOLOK7MFXSLJKLYRZONER5ZCDZO5XYWSLG475QC
T5VE6Y4RGX5BK3BQYUVV3TX6VKLPZFSBWR227723UX4VMUZGJH7QC
ZNUMGZOGREVG6RNSM4RGHG2Y6NYL7O2U642V6F3HJAXMTC5JXJHAC
MJWFTUS66PTCNEYXEJA3CUJFXNWXIKDD6H3V24PW7HK64NSVOFSAC
Q7GGSLY6IUX2YPBQNRR7JL5HY7VEWLBQN3KCZGMS2WAA2LNXRI6QC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
OFTOEJSRSA2EZOAQOJCWWQNDX7IVVAR565JK3DZCBG54TBHHCIDQC
6GQU5BMORHTHJGGVYPGJZSEIHPOVXDAS23BE7OHU4X6WVDYRC2MAC
UFLQNWY753LLYGHIEO3REFZWKQ7WNVVIHBQPCKCEEX2KQGUFEPZAC
KX6HOBTF5OBZLH2VNEFHH6YAX66FSE6JGBY5I2WIAW5IEJUGNL6AC
5AZ6MLZVJXRGXNJYLWDQB5RS3A3GKIYS52RA4SOST3PR2FTFNNNQC
R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC
CSC3SNU2QMWV5MJL6L2DJIQ5W7V3XXMZM6VULPSENTOT7R4DFQKAC
EADWOF6DJ7WTY3ZAFRVJ2VHFWNLDGX6W3JXESBTXJ6K4PM2AJVDQC
OONYLF4DAPLIYLBNNRW74IVT5BBTWI4XHQBXSNSPVRX3FTKJBTRAC
RTB6BWX5OPHNXFSRXCQ34G5THZO4F6QZCW4GQBAL6JHVEMEMSPOAC
N5XD5IAOMEDF37AXEBALHFINB4H527T6YNTCHN5KKO6YHXAP5PNQC
23PFLB2E4QHL5SF3Q2YV5FXRH6MFHENEU2ACVC572ZCYDXCBZVQAC
ERTQJ5ZXDBRGKC5N3GZ6U4MFFK5HB6737FVLVD4GSMGTIFCSJJJQC
G4TVXOLIF5X2MWV7I4UPT3MSQHRMGME6QRIIFAQ64C45JGYK7SIAC
B7MSPF6X2RLGWN4M6ZZF3WSOPKGYPTTD7LIJVST7DXN27DG6JHNAC
4FQAKUKUO6PCAZ3N4HUR5XL6E4VA5UQUZ3AEDGRBLVY7W2LMWI7QC
C6E4OROPXFOSAVGLTJE2MYHOGC6QXP4JU275LGBHAYASP27KCY3AC
Q2XCGRT36NCRQKWNL53EAS3ADON5SJQ5GEMJMX5S3QAG553HFVFQC
AVSWNOP23Z2QCLQGXFDZV7TI4RC3XSXHIX2HDXFHXGKDEZSSIGJQC
FXVDNB6MAAOSEP37HP7CIPPXNS7FDECN3GCRMT5UFFCKLHIL6IVAC
//int spell_restriction(int which_spell, int which_restriction);
int apply_area_visible(int (*func) (int, int, int, int), int power,
typedef int cell_func(coord_def where, int pow, int aux);
int apply_area_visible(cell_func cf, int power,
int apply_random_around_square( int (*func) (int, int, int, int),
int targ_x, int targ_y, bool hole_in_middle,
int power, int max_targs );
int apply_random_around_square( cell_func cf, const coord_def& where,
bool hole_in_middle, int power, int max_targs );
//jmf: FIXME: randomly start from other quadrants, like raise_dead?
for (x = you.x_pos - 8; x <= you.x_pos + 8; x++)
{
for (y = you.y_pos - 8; y <= you.y_pos + 8; y++)
{
if ((pass_through_trans && see_grid(x, y))
|| (!pass_through_trans && see_grid_no_trans(x, y)))
rv += func(x, y, power, 0);
}
}
for (radius_iterator ri(you.pos(), LOS_RADIUS); ri; ++ri)
if ( pass_through_trans || see_grid_no_trans(*ri) )
rv += cf(*ri, power, 0);
for (x = targ_x - 1; x <= targ_x + 1; x++)
for (y = targ_y - 1; y <= targ_y + 1; y++)
{
if (x == targ_x && y == targ_y)
continue;
else
rv += func(x, y, power, 0);
}
for (adjacent_iterator ai(where, true); ai; ++ai)
rv += cf(*ai, power, 0);
int apply_random_around_square( int (*func) (int, int, int, int),
int targ_x, int targ_y,
bool hole_in_middle, int power, int max_targs )
int apply_random_around_square( cell_func cf, const coord_def& where,
bool exclude_center, int power, int max_targs )
for (int y = targ_y - 1; y <= targ_y + 1; y++)
{
if (hole_in_middle && (x == targ_x && y == targ_y))
continue;
if (mgrd[x][y] == NON_MONSTER
&& !(x == you.x_pos && y == you.y_pos))
{
continue;
}
if (mgrd(*ai) == NON_MONSTER && *ai != you.pos())
continue;
// Slight difference here over the basic algorithm...
//
// For cases where the number of choices <= max_targs it's
// obvious (all available choices will be selected).
//
// For choices > max_targs, here's a brief proof:
//
// Let m = max_targs, k = choices - max_targs, k > 0.
//
// Proof, by induction (over k):
//
// 1) Show n = m + 1 (k = 1) gives uniform distribution,
// P(new one not chosen) = 1 / (m + 1).
// m 1 1
// P(specific previous one replaced) = --- * --- = ---
// m+1 m m+1
//
// So the probablity is uniform (ie. any element has
// a 1/(m+1) chance of being in the unchosen slot).
//
// 2) Assume the distribution is uniform at n = m+k.
// (ie. the probablity that any of the found elements
// was chosen = m / (m+k) (the slots are symetric,
// so it's the sum of the probabilities of being in
// any of them)).
//
// 3) Show n = m + k + 1 gives a uniform distribution.
// P(new one chosen) = m / (m + k + 1)
// P(any specific previous choice remaining chosen)
// = [1 - P(swaped into m+k+1 position)] * P(prev. chosen)
// m 1 m
// = [ 1 - ----- * --- ] * ---
// m+k+1 m m+k
//
// m+k m m
// = ----- * --- = -----
// m+k+1 m+k m+k+1
//
// Therefore, it's uniform for n = m + k + 1. QED
//
// The important thing to note in calculating the last
// probability is that the chosen elements have already
// passed tests which verify that they *don't* belong
// in slots m+1...m+k, so the only positions an already
// chosen element can end up in are its original
// position (in one of the chosen slots), or in the
// new slot.
//
// The new item can, of course, be placed in any slot,
// swapping the value there into the new slot... we
// just don't care about the non-chosen slots enough
// to store them, so it might look like the item
// automatically takes the new slot when not chosen
// (although, by symetry all the non-chosen slots are
// the same... and similarly, by symetry, all chosen
// slots are the same).
//
// Yes, that's a long comment for a short piece of
// code, but I want people to have an understanding
// of why this works (or at least make them wary about
// changing it without proof and breaking this code). -- bwr
// Slight difference here over the basic algorithm...
//
// For cases where the number of choices <= max_targs it's
// obvious (all available choices will be selected).
//
// For choices > max_targs, here's a brief proof:
//
// Let m = max_targs, k = choices - max_targs, k > 0.
//
// Proof, by induction (over k):
//
// 1) Show n = m + 1 (k = 1) gives uniform distribution,
// P(new one not chosen) = 1 / (m + 1).
// m 1 1
// P(specific previous one replaced) = --- * --- = ---
// m+1 m m+1
//
// So the probablity is uniform (ie. any element has
// a 1/(m+1) chance of being in the unchosen slot).
//
// 2) Assume the distribution is uniform at n = m+k.
// (ie. the probablity that any of the found elements
// was chosen = m / (m+k) (the slots are symetric,
// so it's the sum of the probabilities of being in
// any of them)).
//
// 3) Show n = m + k + 1 gives a uniform distribution.
// P(new one chosen) = m / (m + k + 1)
// P(any specific previous choice remaining chosen)
// = [1 - P(swaped into m+k+1 position)] * P(prev. chosen)
// m 1 m
// = [ 1 - ----- * --- ] * ---
// m+k+1 m m+k
//
// m+k m m
// = ----- * --- = -----
// m+k+1 m+k m+k+1
//
// Therefore, it's uniform for n = m + k + 1. QED
//
// The important thing to note in calculating the last
// probability is that the chosen elements have already
// passed tests which verify that they *don't* belong
// in slots m+1...m+k, so the only positions an already
// chosen element can end up in are its original
// position (in one of the chosen slots), or in the
// new slot.
//
// The new item can, of course, be placed in any slot,
// swapping the value there into the new slot... we
// just don't care about the non-chosen slots enough
// to store them, so it might look like the item
// automatically takes the new slot when not chosen
// (although, by symetry all the non-chosen slots are
// the same... and similarly, by symetry, all chosen
// slots are the same).
//
// Yes, that's a long comment for a short piece of
// code, but I want people to have an understanding
// of why this works (or at least make them wary about
// changing it without proof and breaking this code). -- bwr
// Accept the first max_targs choices, then when
// new choices come up, replace one of the choices
// at random, max_targs/count of the time (the rest
// of the time it replaces an element in an unchosen
// slot -- but we don't care about them).
if (count <= max_targs)
{
targs[ count - 1 ].x = x;
targs[ count - 1 ].y = y;
}
else if (x_chance_in_y(max_targs, count))
{
const int pick = random2( max_targs );
targs[ pick ].x = x;
targs[ pick ].y = y;
}
// Accept the first max_targs choices, then when
// new choices come up, replace one of the choices
// at random, max_targs/count of the time (the rest
// of the time it replaces an element in an unchosen
// slot -- but we don't care about them).
if (count <= max_targs)
{
targs[ count - 1 ] = *ai;
}
else if (x_chance_in_y(max_targs, count))
{
const int pick = random2( max_targs );
targs[ pick ] = *ai;
static int _make_a_rot_cloud(int x, int y, int pow, cloud_type ctype);
static int _quadrant_blink(int x, int y, int pow, int garbage);
static int _make_a_rot_cloud(const coord_def& where, int pow, cloud_type ctype);
static int _quadrant_blink(coord_def where, int pow, int garbage);
apply_area_within_radius(_shatter_items, you.x_pos, you.y_pos,
pow, rad, 0);
apply_area_within_radius(_shatter_monsters, you.x_pos, you.y_pos,
pow, rad, 0);
int dest = apply_area_within_radius( _shatter_walls, you.x_pos, you.y_pos,
apply_area_within_radius(_shatter_items, you.pos(), pow, rad, 0);
apply_area_within_radius(_shatter_monsters, you.pos(), pow, rad, 0);
int dest = apply_area_within_radius( _shatter_walls, you.pos(),