git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5892 c06c8d41-db1a-0410-9941-cceddc491573
3RNRFLMD2X4RUFTDVITLXAP377YB6F6YMQLL3DAXSUZDZBTWSLRQC
542UIZKI65UDRNEMGFFDBWYD5XC7AYLTZ3JZQRR2GHYJALD3YY6QC
BW2JVFBXXFVN5PWDH2KZY5NP4AVH7W755SH5SMRQSAR7F2WFZWNAC
VQD5BW56OTUNPILMCASXZ6YZ3OQGXKQ7CSNDMNZUX72AQZXKOE3QC
IBCGW7GAP7MBB4EQ5Q6B6GAOUIYG3O7NLU2LCK37E7ZSDMTAAYZQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
VOR2QOT3R3BC3H74GMW4PUBY77QBJXE5QGQNBIINBE3MPSH6CXWQC
NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC
IEWZIPFXN6HYTAD2XKL3LQ6GYQZQKLX7VDWVB3YE42ODZLSOTB4AC
X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
WQIEW3O4MANA2KKYRUWEZP44KHVJ4RRHEZTDXSF4EDELX66LO26QC
L254F6ZIU2HWGLFFGPIORTN4C3TDQ3E5JZ7Z7GQA5AEDIKL6PKDAC
3GSAVTNKEG45AT2U734R5STSRP22WJZL3H6KUFRUWCIA6A4CZE5QC
C67GX7W5HBCDPQJRSHWMLM4DUJ3ELFSHH42SVICFJVCJW25T5Z3AC
KBNY5FWKTEAKABFCLPC3QFKFSVZKAGXINPCIFV6WDSWFO4VCKNTAC
LFBNFE3PZBXTR2ROPKYPARUWLJAYWAKGTS7VBWADZWVVSJ5CLX6AC
RQR4PTMGQLTRWLYRU3KXIIDGND7FBORESJWMWFVD3WYU5SISZXAAC
OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC
TVC7W7C2XKBQSD2IJFMWFVGXZAOD4EUOW43NAQTOF5KFMAUOJABQC
LTX72QGIPNUGWQN5ULPOMFCOPZTK7472DQY4AYX5WM3WHSUVXI5QC
Y3P2I7OBISB7VGCDWDDVTXPVKY3KA7KXMD7F2RAGZ5KG4IQMKH7QC
RGY2525RQH7SSGM6ZVI7CZL4WMNFZK2WRABOSIWRKQYYOU2RWN4QC
4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC
GPEJOT73KMACP33IPAKFR5ROGHCOIP22VXZMQNYTGLEA2OSZUM2AC
C5U3HSOOQ7BKXKXIDS7MLVXUKDTHAWJ5NXNX6YDXTM3GWY5UWX4QC
WUTE7R6SROKLIWR3QASJSH2IZDJNPAIMWJRUSISQTN4YMKNFTODQC
KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC
OBGOBCWABXEGCPYXEY45DRPXL4AVGPATUQ4NFLJGMAF7XLEGOOBAC
Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC
RKFHYYANUZQHOWOE6YHVFFJNCZU7X67FWUQPQFF6KJKMNIKXFWEAC
74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC
CLIEHAE2PP7ZIGLLIMYCWM4FC54KBOAN5AILOLAZJ5S26GTJM4RQC
6X4LO6MAQLVRJBTYVGBJUI6RGAAFM6DMXW3KFNWC23R5TX7Q2OLQC
JFD3VO3PPQSANNT7KROO45RJ3LQKAYMQCJ72EX6TGFDIQBDUBVGQC
T7CUIVICB74342RA32BR37T36FOX4RBSQIB5PNOHTGTGUYGDKSTQC
DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC
QS3ZRS3E6KL3YJHPKYEWCWJYRBJSXD5OOYF6Y25HZVECGPJRDB5QC
OP6CTAKWCAU64JXQ3USQYR5E5IFHQHNCACII5UMVRXUTZXJQOAZAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
if (monster->behaviour == BEH_SLEEP)
return (false);
else if (monster->inv[MSLOT_POTION] == NON_ITEM)
return (false);
else if (!one_chance_in(3))
return (false);
else
if (mons_is_sleeping(monster)
|| monster->inv[MSLOT_POTION] == NON_ITEM
|| !one_chance_in(3))
const int potion_type = mitm[monster->inv[MSLOT_POTION]].sub_type;
switch (potion_type)
{
case POT_HEALING:
case POT_HEAL_WOUNDS:
if (monster->hit_points <= monster->max_hit_points / 2
&& mons_holiness(monster) != MH_UNDEAD
&& mons_holiness(monster) != MH_NONLIVING
&& mons_holiness(monster) != MH_PLANT)
{
simple_monster_message(monster, " drinks a potion.");
if (heal_monster(monster, 5 + random2(7), false))
{
simple_monster_message(monster, " is healed!");
ident = ID_MON_TRIED_TYPE;
}
if (mitm[monster->inv[MSLOT_POTION]].sub_type
== POT_HEAL_WOUNDS)
{
heal_monster(monster, 10 + random2avg(28, 3), false);
}
bool imbibed = false;
item_type_id_state_type ident = ID_UNKNOWN_TYPE;
bool was_visible =
mons_near(monster) && player_monster_visible(monster);
if (potion_type == POT_HEALING)
{
monster->del_ench(ENCH_POISON);
monster->del_ench(ENCH_SICK);
if (monster->del_ench(ENCH_CONFUSION))
ident = ID_KNOWN_TYPE;
if (monster->del_ench(ENCH_ROT))
ident = ID_KNOWN_TYPE;
}
const int potion_type = mitm[monster->inv[MSLOT_POTION]].sub_type;
switch (potion_type)
{
case POT_HEALING:
case POT_HEAL_WOUNDS:
if (monster->hit_points <= monster->max_hit_points / 2
&& mons_holiness(monster) != MH_UNDEAD
&& mons_holiness(monster) != MH_NONLIVING
&& mons_holiness(monster) != MH_PLANT)
{
simple_monster_message(monster, " drinks a potion.");
case POT_SPEED:
// Notice that these are the same odd colours used in
// mons_ench_f2() {dlb}
if (monster->has_ench(ENCH_HASTE))
break;
case POT_BLOOD:
case POT_BLOOD_COAGULATED:
if (mons_species(monster->type) == MONS_VAMPIRE
&& monster->hit_points <= monster->max_hit_points / 2)
{
simple_monster_message(monster, " drinks a potion.");
beem.flavour = BEAM_HASTE;
// intentional fall through
case POT_INVISIBILITY:
if (mitm[monster->inv[MSLOT_POTION]].sub_type == POT_INVISIBILITY)
if (heal_monster(monster, 10 + random2avg(28, 3), false))
if (monster->has_ench(ENCH_INVIS))
break;
beem.flavour = BEAM_INVISIBILITY;
// Friendly monsters won't go invisible if the player
// can't see invisible. We're being nice.
if (mons_friendly(monster) && !player_see_invis(false))
break;
simple_monster_message(monster, " is healed!");
ident = ID_MON_TRIED_TYPE;
if (dec_mitm_item_quantity( monster->inv[MSLOT_POTION], 1 ))
monster->inv[MSLOT_POTION] = NON_ITEM;
else if (is_blood_potion(mitm[monster->inv[MSLOT_POTION]]))
remove_oldest_blood_potion(mitm[monster->inv[MSLOT_POTION]]);
if (ident != ID_UNKNOWN_TYPE && was_visible)
set_ident_type(OBJ_POTIONS, potion_type, ident);
if (monster->has_ench(ENCH_INVIS))
break;
} // end handle_potion()
if (imbibed)
{
if (dec_mitm_item_quantity( monster->inv[MSLOT_POTION], 1 ))
monster->inv[MSLOT_POTION] = NON_ITEM;
else if (is_blood_potion(mitm[monster->inv[MSLOT_POTION]]))
remove_oldest_blood_potion(mitm[monster->inv[MSLOT_POTION]]);
if (ident != ID_UNKNOWN_TYPE && was_visible)
set_ident_type(OBJ_POTIONS, potion_type, ident);
monster->lose_energy(EUT_ITEM);
}
return (imbibed);
}
if (monster->has_ench(ENCH_CONFUSION)
|| monster->behaviour == BEH_SLEEP
|| monster->has_ench(ENCH_SUBMERGED))
if (mons_is_sleeping(monster)
|| monster->has_ench(ENCH_CONFUSION)
|| monster->has_ench(ENCH_SUBMERGED)
|| monster->inv[MSLOT_SCROLL] == NON_ITEM
|| !one_chance_in(3))
else if (monster->inv[MSLOT_SCROLL] == NON_ITEM)
return (false);
else if (!one_chance_in(3))
return (false);
else
{
bool read = false;
item_type_id_state_type ident = ID_UNKNOWN_TYPE;
bool was_visible =
mons_near(monster) && player_monster_visible(monster);
bool read = false;
item_type_id_state_type ident = ID_UNKNOWN_TYPE;
bool was_visible =
mons_near(monster) && player_monster_visible(monster);
// Notice how few cases are actually accounted for here {dlb}:
const int scroll_type = mitm[monster->inv[MSLOT_SCROLL]].sub_type;
switch (scroll_type)
// Notice how few cases are actually accounted for here {dlb}:
const int scroll_type = mitm[monster->inv[MSLOT_SCROLL]].sub_type;
switch (scroll_type)
{
case SCR_TELEPORTATION:
if (!monster->has_ench(ENCH_TP))
case SCR_TELEPORTATION:
if (!monster->has_ench(ENCH_TP))
{
if (mons_is_fleeing(monster) || mons_is_caught(monster))
{
simple_monster_message(monster, " reads a scroll.");
monster_teleport(monster, false);
read = true;
ident = ID_KNOWN_TYPE;
}
}
break;
case SCR_BLINKING:
if (mons_near(monster))
{
simple_monster_message(monster, " reads a scroll.");
simple_monster_message(monster, " blinks!");
monster_blink(monster);
read = true;
ident = ID_KNOWN_TYPE;
}
simple_monster_message(monster, " reads a scroll.");
monster_teleport(monster, false);
read = true;
ident = ID_KNOWN_TYPE;
if (dec_mitm_item_quantity( monster->inv[MSLOT_SCROLL], 1 ))
monster->inv[MSLOT_SCROLL] = NON_ITEM;
simple_monster_message(monster, " reads a scroll.");
create_monster(
mgen_data(MONS_ABOMINATION_SMALL, SAME_ATTITUDE(monster),
2, monster->pos(), monster->foe) );
read = true;
ident = ID_KNOWN_TYPE;
}
break;
}
monster->lose_energy(EUT_ITEM);
}
if (ident != ID_UNKNOWN_TYPE && was_visible)
set_ident_type(OBJ_SCROLLS, scroll_type, ident);
if (monster->behaviour == BEH_SLEEP)
return (false);
else if (!mons_near(monster))
return (false);
else if (monster->has_ench(ENCH_SUBMERGED))
return (false);
else if (monster->inv[MSLOT_WAND] == NON_ITEM
|| mitm[monster->inv[MSLOT_WAND]].plus <= 0)
if (!mons_near(monster)
|| mons_is_sleeping(monster)
|| monster->has_ench(ENCH_SUBMERGED)
|| monster->inv[MSLOT_WAND] == NON_ITEM
|| mitm[monster->inv[MSLOT_WAND]].plus <= 0
|| coinflip())
// map wand type to monster spell type
const spell_type mzap = _map_wand_to_mspell(wand.sub_type);
if (mzap == SPELL_NO_SPELL)
return (false);
item_def &wand(mitm[monster->inv[MSLOT_WAND]]);
// map wand type to monster spell type
const spell_type mzap = _map_wand_to_mspell(wand.sub_type);
if (mzap == SPELL_NO_SPELL)
return (false);
beem.name = theBeam.name;
beem.beam_source = monster_index(monster);
beem.source_x = monster->x;
beem.source_y = monster->y;
beem.colour = theBeam.colour;
beem.range = theBeam.range;
beem.rangeMax = theBeam.rangeMax;
beem.damage = theBeam.damage;
beem.ench_power = theBeam.ench_power;
beem.hit = theBeam.hit;
beem.type = theBeam.type;
beem.flavour = theBeam.flavour;
beem.thrower = theBeam.thrower;
beem.is_beam = theBeam.is_beam;
beem.is_explosion = theBeam.is_explosion;
beem.name = theBeam.name;
beem.beam_source = monster_index(monster);
beem.source_x = monster->x;
beem.source_y = monster->y;
beem.colour = theBeam.colour;
beem.range = theBeam.range;
beem.rangeMax = theBeam.rangeMax;
beem.damage = theBeam.damage;
beem.ench_power = theBeam.ench_power;
beem.hit = theBeam.hit;
beem.type = theBeam.type;
beem.flavour = theBeam.flavour;
beem.thrower = theBeam.thrower;
beem.is_beam = theBeam.is_beam;
beem.is_explosion = theBeam.is_explosion;
const int wand_type = wand.sub_type;
switch (wand_type)
const int wand_type = wand.sub_type;
switch (wand_type)
{
case WAND_DISINTEGRATION:
// Dial down damage from wands of disintegration, since
// disintegration beams can do large amounts of damage.
beem.damage.size = beem.damage.size * 2 / 3;
break;
case WAND_ENSLAVEMENT:
case WAND_DIGGING:
case WAND_RANDOM_EFFECTS:
// These have been deemed "too tricky" at this time {dlb}:
return (false);
case WAND_POLYMORPH_OTHER:
// Monsters can be very trigger happy with wands, reduce this
// for polymorph.
if (!one_chance_in(5))
return false;
break;
// These are wands that monsters will aim at themselves {dlb}:
case WAND_HASTING:
if (!monster->has_ench(ENCH_HASTE))
case WAND_DISINTEGRATION:
// Dial down damage from wands of disintegration, since
// disintegration beams can do large amounts of damage.
beem.damage.size = beem.damage.size * 2 / 3;
beem.target_x = monster->x;
beem.target_y = monster->y;
niceWand = true;
// These have been deemed "too tricky" at this time {dlb}:
case WAND_ENSLAVEMENT:
case WAND_DIGGING:
case WAND_RANDOM_EFFECTS:
return (false);
case WAND_HEALING:
if (monster->hit_points <= monster->max_hit_points / 2)
{
beem.target_x = monster->x;
beem.target_y = monster->y;
// These are wands that monsters will aim at themselves {dlb}:
case WAND_HASTING:
if (!monster->has_ench(ENCH_HASTE))
{
beem.target_x = monster->x;
beem.target_y = monster->y;
case WAND_INVISIBILITY:
if (!monster->has_ench(ENCH_INVIS)
&& !monster->has_ench(ENCH_SUBMERGED)
&& (!mons_friendly(monster) || player_see_invis(false)))
{
beem.target_x = monster->x;
beem.target_y = monster->y;
case WAND_INVISIBILITY:
if (!monster->has_ench(ENCH_INVIS)
&& !monster->has_ench(ENCH_SUBMERGED)
&& (!mons_friendly(monster) || player_see_invis(false)))
{
beem.target_x = monster->x;
beem.target_y = monster->y;
// Fire tracer, if necessary.
if (!niceWand)
{
fire_tracer( monster, beem );
case WAND_TELEPORTATION:
if (monster->hit_points <= monster->max_hit_points / 2
|| mons_is_caught(monster))
{
if (!monster->has_ench(ENCH_TP)
&& !one_chance_in(20))
{
beem.target_x = monster->x;
beem.target_y = monster->y;
if (niceWand || zap)
{
if (!simple_monster_message(monster, " zaps a wand."))
{
if (!silenced(you.x_pos, you.y_pos))
mpr("You hear a zap.", MSGCH_SOUND);
}
niceWand = true;
break;
}
// This break causes the wand to be tried on the player.
break;
}
return (false);
}
// charge expenditure {dlb}
wand.plus--;
beem.is_tracer = false;
fire_beam(beem);
if (niceWand || zap)
{
if (!simple_monster_message(monster, " zaps a wand."))
{
if (!silenced(you.x_pos, you.y_pos))
mpr("You hear a zap.", MSGCH_SOUND);
}
// charge expenditure {dlb}
wand.plus--;
beem.is_tracer = false;
fire_beam( beem );
monster->lose_energy(EUT_ITEM);
if (was_visible)
{
if (niceWand || beem.name != "0" || beem.obvious_effect)
set_ident_type(OBJ_WANDS, wand_type, ID_KNOWN_TYPE);
else
set_ident_type(OBJ_WANDS, wand_type, ID_MON_TRIED_TYPE);
// Increment zap count.
if (wand.plus2 >= 0)
wand.plus2++;
}
monster->lose_energy(EUT_ITEM);
return (true);
}
return (true);