vampire successfully stabs one of those walking blood replenishers.
All in all, vampires will bite monsters that don't yield blood less often (1/3 chance), though their overall biting chance has been slightly increases, and much so when stabbing. Weapons of vampiricism are now a distinct case, so vampiric biting (that also is signified by SPWPN_VAMPIRICISM, occasionally) consistently doesn't check for life protection (though that might be added) and instead always respects the mons_has_blood checks.
Also, food messages ("You are very hungry.") are now displayed in green if your food level has increased.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3904 c06c8d41-db1a-0410-9941-cceddc491573
2WVP47RBNL5OVYMAZH7TKRYD7F2TGSZ5X74PWVGAYCQP26G3JUHQC
7Y4746DRUKCAEK6CNQJTFGAOOHJYLV54E4JZ2EKFFMCKWL2V2FZAC
NDP6NL6AXKUW5VSXHQB6ISY2EYNUHFGAC6ELP3TQI2HQYF6CLP4QC
QHAYBZTRPVJMK55WXT3F63CNRSAEVN3CQAAG42GCJTONLXQLNNNQC
44HAAL6PDZT33APN2YN4XKQLY6C7AZCIRTYWOLBYGO2Q66WYD4MQC
TBLVONZGCKVUXW7NEG4NSDMFIIO6UZOG4FHTJGT6MKSSO3B5J46AC
Q3XHNSHW6FI4JCXSEABATRFBJPMCF7PXNG2K6ZQTRRPVMIZFHUBQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
2B4AQJIATJ4E7RFN6OTQITZNDBAPQ2VWWXLBCVYSORAFG2GIIDNQC
TRCCLE5RJ4VJULBOWOI2WC3RJU7WTEGS7RRQTDQL6W5UU246LKTQC
3D6NWJ44UYHLZMD3BOQIWXJUEGITAVCHK6Z2WWDQONVQC4HSBRXQC
5S3CAGZSAQC3CYFPM5TQFPHW5IE2OZRVFJMICQZXHBZRGKFMNPRQC
6PNVX6Q45HH733TZDXYBA6BYPJKDMND5BA4N2MP6HA3QVNCEPN2QC
ARORC5GJNHLAPL2MJ3PUYIAR55ETDDAPXYSYH4OBMXHADNWSGYPAC
5TG5LXU4DX65KMWCZ7YJHOB3VAETQAVBUHEUSQTPMA327XV2HQWAC
P2ZCF3BBG523ZEOD6XQA4X5YEHBTWH3IM33YVHXP2SQ5POXZIH4QC
TFNFP2YQA4EOVE4VIXBEQSGACZSXHWIQ2T4TIPQ46R2MJW2C4B5AC
R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC
YX2LDGNQNB6AQRKAVXNYQ473X6EVPQEBT5AJKBIIWFIMS3U2BNQQC
NLQNXH3SVJ52CWXEV35FSSZP32VHC4QFGN3HINF4KO5GZHZMOBKQC
E77ASJLF52YJ4DQIZ4GLNN3PB3AOUPWS5UVETBEHANA3U7OG3OJAC
JXOE7KJIEAJHPLMZAJ6O4YHDTRB6BGNP6XT3ZSEFYGSIUMHR77KQC
DMRXDEKHHBQNY37NPGZFAGUQPALWFANGGK4CUWIOQUPSLM2JBNFQC
FZY4HSWWVXB4KNVLUVCBDKU4Z5IIP6V6WIJ3QVPQDWACNVH5DT6QC
IT3NSSLR756K7TZ7S7DOMS7DZUVGIFS5EAR22PEERAF5ZRBICV4AC
ILADK4YNPQVYLZYDMGGBYN2EBBCIPCDNUCWZH27DQTKOMVUDLVMAC
PVLLIAYFIAU4TQFBIP7B4ARIBUX2CVTSBQECEU6VTONJV4ANHVFAC
QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC
E5DMZFW6WCFAKTKKOQPYTQXZ2CGLWMVH64LRXDUI2UIG4VYUHIVQC
RSIUBEQUGNU4LO6KH4PKVROWQS33DAKSY4XFVGN7T3CEKSXABCSAC
}
static bool _vamp_wants_blood_from_monster(const monsters *mon)
{
if (you.species != SP_VAMPIRE)
return (false);
if (you.hunger_state >= HS_ENGORGED)
return (false);
if (!mons_has_blood(mon->type))
return (false);
const int chunk_type = mons_corpse_effect( mon->type );
// don't drink poisonous or mutagenic blood
return (chunk_type == CE_CLEAN || chunk_type == CE_CONTAMINATED
|| chunk_type == CE_POISONOUS && player_res_poison());
// Should life protection protect from this?
// Called when stabbing and for bite attacks.
// Returns true if blood was drawn.
static bool _player_vampire_draws_blood(const int mons, const int damage,
bool needs_bite_msg = false)
{
ASSERT(you.species == SP_VAMPIRE);
ASSERT(mons != -1);
const monsters *mon = &menv[mons];
if (!_vamp_wants_blood_from_monster(mon))
return (false);
const int chunk_type = mons_corpse_effect( mon->type );
// now print message, need biting unless already done (never for bat form!)
if (needs_bite_msg && you.attribute[ATTR_TRANSFORMATION] != TRAN_BAT)
{
mprf( "You bite %s, and draw %s blood!",
mon->name(DESC_NOCAP_THE, true).c_str(),
mon->pronoun(PRONOUN_NOCAP_POSSESSIVE).c_str());
}
else
mprf( "You draw %s's blood!", mon->name(DESC_NOCAP_THE, true).c_str() );
// regain hp
if (you.hp < you.hp_max)
{
int heal = 1 + random2(damage);
if (heal > you.experience_level)
heal = you.experience_level;
if (chunk_type == CE_CLEAN)
heal += 1 + random2(damage);
inc_hp(heal, false);
mprf("You feel %sbetter.", (you.hp == you.hp_max) ? "much " : "");
}
// gain nutrition
if (you.hunger_state < HS_ENGORGED)
{
int food_value = 0;
if (chunk_type == CE_CLEAN)
food_value = 30 + random2avg(59, 2);
else if (chunk_type == CE_CONTAMINATED
|| chunk_type == CE_POISONOUS)
{
food_value = 15 + random2avg(29, 2);
}
if (you.hunger_state > HS_HUNGRY && coinflip())
break;
if (you.hunger_state > HS_STARVING && coinflip())
break;
if (_vamp_wants_blood_from_monster(def))
{
// prob of vampiric bite:
// 1/4 when non-hungry, 1/2 when hungry, 100% when starving
if (you.hunger_state > HS_HUNGRY && coinflip())
break;
// normal vampiric biting attack
if (damage_brand == SPWPN_VAMPIRICISM
&& defender->holiness() == MH_NATURAL)
// normal vampiric biting attack, not if already got stabbing special
if (damage_brand == SPWPN_VAMPIRICISM && you.species == SP_VAMPIRE
&& (!stab_attempt || stab_bonus <= 0))
const int chunk_type = mons_corpse_effect( def->type );
// don't drink poisonous or mutagenic blood
if (chunk_type == CE_CLEAN || chunk_type == CE_CONTAMINATED)
{
mprf( "You draw %s's blood!",
def->name(DESC_NOCAP_THE, true).c_str() );
if (you.hp < you.hp_max)
{
int heal = 1 + random2(damage_done);
if (heal > you.experience_level)
heal = you.experience_level;
if (chunk_type == CE_CLEAN)
heal += 1 + random2(damage_done);
inc_hp(heal, false);
mpr("You feel better.");
}
if (you.hunger_state < HS_ENGORGED)
{
int food_value = 0;
if (chunk_type == CE_CLEAN)
food_value = 45 + random2avg(59, 2);
else if (chunk_type == CE_CONTAMINATED)
food_value = 22 + random2avg(29, 2);
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BAT)
food_value -= 5 + random2(16);
lessen_hunger(food_value, true);
}
did_god_conduct(DID_DRINK_BLOOD, 5 + random2(4));
}
_player_vampire_draws_blood(monster_index(def), damage_done);
// Vampiric effects for the killing blow.
if (mondied && damage_brand == SPWPN_VAMPIRICISM)
// thirsty vampires will try to use a stabbing situation to draw blood
if (you.species == SP_VAMPIRE && you.hunger_state <= HS_HUNGRY
&& mondied && stab_attempt && stab_bonus > 0
&& _player_vampire_draws_blood(monster_index(def), damage_done, true))
{
// no further effects
}
// Vampiric *weapon* effects for the killing blow.
else if (mondied && damage_brand == SPWPN_VAMPIRICISM
&& you.equip[EQ_WEAPON] != -1)
if (defender->holiness() != MH_NATURAL ||
defender->res_negative_energy() > 0 ||
damage_done < 1 || attacker->stat_hp() == attacker->stat_maxhp() ||
one_chance_in(5))
{
// vampire bat form, why the special handling?
if (attacker->atype() == ACT_PLAYER && you.species == SP_VAMPIRE
&& you.attribute[ATTR_TRANSFORMATION] == TRAN_BAT)
{
_player_vampire_draws_blood(monster_index(def), damage_done);
break;
}
if (defender->holiness() != MH_NATURAL || !weapon
|| defender->res_negative_energy() > 0
|| damage_done < 1 || attacker->stat_hp() == attacker->stat_maxhp()
|| one_chance_in(5))
// vampire bat form
if (you.species == SP_VAMPIRE && attacker->atype() == ACT_PLAYER
&& you.attribute[ATTR_TRANSFORMATION] == TRAN_BAT)
{
const int chunk_type = mons_corpse_effect( def->type );
// handle weapon effects
// We only get here if we've done base damage, so no
// worries on that score.
// don't drink poisonous or mutagenic blood
if (mons_has_blood(def->type)
&& (chunk_type == CE_CLEAN || chunk_type == CE_CONTAMINATED
|| chunk_type == CE_POISONOUS && player_res_poison() ))
if (attacker->atype() == ACT_PLAYER)
mpr("You feel better.");
else if (attacker_visible)
{
if (defender->atype() == ACT_PLAYER)
mprf( "You draw %s's blood!",
def->name(DESC_NOCAP_THE, true).c_str() );
if (you.hp < you.hp_max)
{
int heal = 1 + random2(damage_done);
if (heal > you.experience_level)
heal = you.experience_level;
if (chunk_type == CE_CLEAN)
heal += 1 + random2(damage_done);
inc_hp(heal, false);
mpr("You feel better.");
}
if (you.hunger_state < HS_ENGORGED)
{
int food_value = 0;
if (chunk_type == CE_CLEAN)
food_value = 30 + random2avg(59, 2);
else if (chunk_type == CE_CONTAMINATED)
food_value = 15 + random2avg(29, 2);
lessen_hunger(food_value, true);
}
did_god_conduct(DID_DRINK_BLOOD, 5 + random2(4));
mprf("%s draws strength from your injuries!",
attacker->name(DESC_CAP_THE).c_str());
if (attacker->atype() == ACT_PLAYER)
mpr("You feel better.");
else if (attacker_visible)
{
if (defender->atype() == ACT_PLAYER)
mprf("%s draws strength from your injuries!",
attacker->name(DESC_CAP_THE).c_str());
else
mprf("%s is healed.",
attacker->name(DESC_CAP_THE).c_str());
}
int hp_boost = 0;
int hp_boost = 0;
// thus is probably more valuable on larger weapons?
if (weapon && is_fixed_artefact( *weapon )
&& weapon->special == SPWPN_VAMPIRES_TOOTH)
{
hp_boost = damage_done;
}
else
{
hp_boost = 1 + random2(damage_done);
}
// thus is probably more valuable on larger weapons?
if (weapon && is_fixed_artefact( *weapon )
&& weapon->special == SPWPN_VAMPIRES_TOOTH)
{
hp_boost = damage_done;
}
else
{
hp_boost = 1 + random2(damage_done);
}
attacker->heal(hp_boost);
if (attacker->hunger_level() != HS_ENGORGED)
attacker->make_hungry(-random2avg(59, 2));
attacker->god_conduct( DID_NECROMANCY, 2 );
}
attacker->god_conduct( DID_NECROMANCY, 2 );