A mermaid stops beholding if it polymorphs into something else.
If new walls are created, then Crawl stops the beholdment of any mermaid that gets hidden by the new walls.
Do paranoid sanity checking on beholders before each command with check_beholders() and try to restore sanity if any bugs are found (and give a diagnostics message if DEBUG is set).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2465 c06c8d41-db1a-0410-9941-cceddc491573
C3OUSRCHDUOJ6ELVDX6YWMQQVXDJLNEXTXWCDDAYWTKNPFPNSONAC
FJQ2RENS2ATHQZUNEE5ZTSTHZ5VI6B36TQPAG3IUVBTULGVCCQ7AC
LJK4ZQATLSB4MKZG3ARZX5V6RFGTN3NLCN6GTCUGJQKU26SOXMUAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
GSS3OCYMI4MYKACCGNLFA267VDH2U7G4QVVDLMOVAUHZTYQ3QJDAC
IQGGFC563RBS7GDOACKCLXK752EE5RC3T6G5L6H446SXTMSA7T2AC
AVCMVFA3MKCXHO6H44UK5KJNIHTGQV7UA7GYXM26VI6TXXU5ZN6QC
CPGSHENA5WYRZBW6NBZ2MQKNXE4RJS4SR3Q2H5NL5D3DDDRHHVVQC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
for (int i = you.beheld_by.size() - 1; i >= 0; i--)
{
const monsters* mon = &menv[you.beheld_by[i]];
const coord_def pos = mon->pos();
int walls = num_feats_between(you.x_pos, you.y_pos,
pos.x, pos.y, DNGN_UNSEEN,
DNGN_MAXWALL);
if (walls > 0)
{
update_beholders(mon, true);
if (you.beheld_by.empty())
{
you.duration[DUR_BEHELD] = 0;
break;
}
continue;
}
}
}
void check_beholders()
{
for (int i = you.beheld_by.size() - 1; i >= 0; i--)
{
const monsters* mon = &menv[you.beheld_by[i]];
if (!mon->alive() || mon->type != MONS_MERMAID)
{
#if DEBUG
if (!mon->alive())
mpr("Dead mermaid still beholding?", MSGCH_DIAGNOSTICS);
else if (mon->type != MONS_MERMAID)
mprf(MSGCH_DIAGNOSTICS, "Non-mermaid '%s' beholding?",
mon->name(DESC_PLAIN, true).c_str());
#endif
you.beheld_by.erase(you.beheld_by.begin() + i);
if (you.beheld_by.empty())
{
mpr("You are no longer entranced.", MSGCH_RECOVERY);
you.duration[DUR_BEHELD] = 0;
break;
}
continue;
}
const coord_def pos = mon->pos();
int walls = num_feats_between(you.x_pos, you.y_pos,
pos.x, pos.y, DNGN_UNSEEN,
DNGN_MAXWALL);
if (walls > 0)
{
#if DEBUG
mprf(MSGCH_DIAGNOSTICS, "%d walls between beholding '%s' "
"and player", walls, mon->name(DESC_PLAIN, true).c_str());
#endif
you.beheld_by.erase(you.beheld_by.begin() + i);
if (you.beheld_by.empty())
{
mpr("You are no longer entranced.", MSGCH_RECOVERY);
you.duration[DUR_BEHELD] = 0;
break;
}
continue;
}
}
if (you.duration[DUR_BEHELD] > 0 && you.beheld_by.empty())
{
#if DEBUG
mpr("Beheld with no mermaids left?", MSGCH_DIAGNOSTICS);
#endif
mpr("You are no longer entranced.", MSGCH_RECOVERY);
you.duration[DUR_BEHELD] = 0;
}
}
// Even if the monster transforms from one type that can behold the
// player into a different type which can also behold the player,
// the polymoprh disrupts the beholding process. Do this before
// changing monster->type, since unbeholding can only happen while
// monster is still a mermaid.
update_beholders(monster, true);