diff options
-rw-r--r-- | crawl-ref/source/mon-util.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/mutation.cc | 110 | ||||
-rw-r--r-- | crawl-ref/source/mutation.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/output.cc | 432 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 24 |
5 files changed, 234 insertions, 341 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 76718e6c67..69105af2e7 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3350,6 +3350,13 @@ bool monsters::pickup_missile(item_def &item, int near, bool force) if (mons_has_ranged_spell(this)) return (false); + // Monsters in a fight will only pick up missiles if doing so is worthwhile. + if (behaviour != BEH_WANDER + && (item.quantity < 5 || miss && miss->quantity >= 3)) + { + return (false); + } + if (miss && items_stack(*miss, item)) return (pickup(item, MSLOT_MISSILE, near)); diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc index de7afd5ffb..ded5f3f8d7 100644 --- a/crawl-ref/source/mutation.cc +++ b/crawl-ref/source/mutation.cc @@ -1015,22 +1015,31 @@ void fixup_mutations() mutation_defs[MUT_BIG_WINGS].rarity = 1; } -bool mutation_is_active(mutation_type mut) +bool mutation_is_fully_active(mutation_type mut) { // for all species except vampires their mutations always apply if (you.species != SP_VAMPIRE) - return true; + return (true); // innate mutations are always active if (you.demon_pow[mut]) - return true; + return (true); - // ... as do mutations for non-thirsty vampires - if (you.hunger_state >= HS_SATIATED) - return true; + // ... as are physical mutations + if (mutation_defs[mut].physical) + return (true); + + // ... as well as all mutations for vampires at Alive + if (you.hunger_state == HS_ENGORGED) + return (true); - // for thirsty (or worse) vampires, only physical mutations are active - return (mutation_defs[mut].physical); + return (false); +} + +static bool _mutation_is_fully_inactive(mutation_type mut) +{ + return (you.species == SP_VAMPIRE && you.hunger_state < HS_SATIATED + && !you.demon_pow[mut] && !mutation_defs[mut].physical); } formatted_string describe_mutations() @@ -1284,17 +1293,31 @@ formatted_string describe_mutations() if (you.species == SP_CENTAUR && i == MUT_DEFORMED) continue; + const bool fully_active + = mutation_is_fully_active((mutation_type) i); + bool fully_inactive = false; + if (!fully_active) + fully_inactive = _mutation_is_fully_inactive((mutation_type) i); + const char* colourname = ""; if ( you.species == SP_DEMONSPAWN ) { - if ( you.demon_pow[i] < you.mutation[i] ) + if (fully_inactive) + colourname = "darkgray"; + else if (!fully_active) + colourname = "yellow"; + else if ( you.demon_pow[i] < you.mutation[i] ) colourname = "lightred"; else colourname = "red"; } else // innate ability { - if ( you.demon_pow[i] < you.mutation[i] ) + if (fully_inactive) + colourname = "darkgray"; + else if (!fully_active) + colourname = "blue"; + else if ( you.demon_pow[i] < you.mutation[i] ) colourname = "cyan"; else colourname = "lightblue"; @@ -1303,9 +1326,13 @@ formatted_string describe_mutations() result += '<'; result += colourname; result += '>'; + if (fully_inactive) + result += "("; result += mutation_name(static_cast<mutation_type>(i)); + if (fully_inactive) + result += ")"; result += "</"; result += colourname; result += '>'; @@ -1334,15 +1361,26 @@ formatted_string describe_mutations() have_any = true; // not currently active? - const bool is_greyed_out = !mutation_is_active((mutation_type) i); - - if (is_greyed_out) - result += "<darkgrey>("; + const bool need_grey = !mutation_is_fully_active((mutation_type) i); + bool inactive = false; + if (need_grey) + { + result += "<darkgrey>"; + if (_mutation_is_fully_inactive((mutation_type) i)) + { + inactive = true; + result += "("; + } + } result += mutation_name(static_cast<mutation_type>(i)); - if (is_greyed_out) - result += ")</darkgrey>"; + if (need_grey) + { + if (inactive) + result += ")"; + result += "</darkgrey>"; + } result += EOL; } } @@ -1528,8 +1566,37 @@ bool mutate(mutation_type which_mutation, bool failMsg, bool force_mutation, force_mutation = true; bool rotting = you.is_undead; - if (you.species == SP_VAMPIRE && you.hunger_state >= HS_SATIATED) - rotting = false; + if (you.species == SP_VAMPIRE) + { + // The stat gain mutation always come through at Satiated or higher + // (mostly for convenience), and for consistency also their + // negative counterparts. + if (which_mutation == MUT_STRONG || which_mutation == MUT_CLEVER + || which_mutation == MUT_AGILE || which_mutation == MUT_WEAK + || which_mutation == MUT_DOPEY || which_mutation == MUT_CLUMSY) + { + if (you.hunger_state >= HS_FULL) + rotting = false; + } + else + { + // Else, chances depend on hunger state. + switch (you.hunger_state) + { + case HS_SATIATED: + rotting = !one_chance_in(3); + break; + case HS_FULL: + rotting = coinflip(); + break; + case HS_VERY_FULL: + rotting = one_chance_in(3); + break; + case HS_ENGORGED: + rotting = false; + } + } + } // Undead bodies don't mutate, they fall apart. -- bwr // except for demonspawn (or other permamutations) in lichform -- haranp @@ -2237,7 +2304,12 @@ const char *mutation_name(mutation_type which_mutat, int level) // level == -1 means default action of current level if (level == -1) - level = you.mutation[ which_mutat ]; + { + if (!_mutation_is_fully_inactive(which_mutat)) + level = player_mutation_level(which_mutat); + else // give description of fully active mutation + level = you.mutation[ which_mutat ]; + } if (which_mutat == MUT_STRONG || which_mutat == MUT_CLEVER || which_mutat == MUT_AGILE || which_mutat == MUT_WEAK diff --git a/crawl-ref/source/mutation.h b/crawl-ref/source/mutation.h index 12aaee7d80..066073c1b1 100644 --- a/crawl-ref/source/mutation.h +++ b/crawl-ref/source/mutation.h @@ -45,7 +45,7 @@ bool mutate(mutation_type which_mutation, bool failMsg = true, * *********************************************************************** */ void display_mutations(); -bool mutation_is_active(mutation_type mut); +bool mutation_is_fully_active(mutation_type mut); formatted_string describe_mutations(); diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index 2d7f249a61..e99a9ea3c4 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -16,6 +16,10 @@ #include <stdlib.h> #include <sstream> +//#include <cstdlib> +//#include <string.h> +//#include <stdio.h> +//#include <algorithm> #ifdef DOS #include <conio.h> @@ -2217,39 +2221,37 @@ std::string _status_mut_abilities() //---------------------------- text += "\n<w>A:</w> "; - bool have_any = false; - int AC_change = 0; - int EV_change = 0; + int AC_change = 0; + int EV_change = 0; int Str_change = 0; int Int_change = 0; int Dex_change = 0; + std::vector<std::string> mutations; + switch (you.species) //mv: following code shows innate abilities - if any { case SP_MERFOLK: - text += "change form in water"; - have_any = true; + mutations.push_back("change form in water"); break; case SP_NAGA: // breathe poison replaces spit poison: if (!player_mutation_level(MUT_BREATHE_POISON)) - text += "spit poison"; + mutations.push_back("spit poison"); else - text += "breathe poison"; - - have_any = true; + mutations.push_back("breathe poison"); break; case SP_KENKU: - text += "cannot wear helmets"; + mutations.push_back("cannot wear helmets"); if (you.experience_level > 4) { - text += ", able to fly"; + std::string help = "able to fly"; if (you.experience_level > 14) - text += " continuously"; + help += " continuously"; + mutations.push_back(help); } - have_any = true; break; case SP_VAMPIRE: @@ -2257,82 +2259,55 @@ std::string _status_mut_abilities() break; // else fall-through case SP_MUMMY: - text += "in touch with death"; - - have_any = true; + mutations.push_back("in touch with death"); break; case SP_GREY_DRACONIAN: if (you.experience_level > 6) - { - text += "spiky tail"; - have_any = true; - } + mutations.push_back("spiky tail"); break; case SP_GREEN_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe poison"; - have_any = true; - } + mutations.push_back("breathe poison"); break; case SP_RED_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe fire"; - have_any = true; - } + mutations.push_back("breathe fire"); break; case SP_WHITE_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe frost"; - have_any = true; - } + mutations.push_back("breathe frost"); break; case SP_BLACK_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe lightning"; - have_any = true; - } + mutations.push_back("breathe lightning"); break; case SP_GOLDEN_DRACONIAN: if (you.experience_level > 6) { - text += "spit acid"; - text += ", acid resistance"; - have_any = true; + mutations.push_back("spit acid"); + mutations.push_back("acid resistance"); } break; case SP_PURPLE_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe power"; - have_any = true; - } + mutations.push_back("breathe power"); break; case SP_MOTTLED_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe sticky flames"; - have_any = true; - } + mutations.push_back("breathe sticky flames"); break; case SP_PALE_DRACONIAN: if (you.experience_level > 6) - { - text += "breathe steam"; - have_any = true; - } + mutations.push_back("breathe steam"); break; default: @@ -2340,31 +2315,25 @@ std::string _status_mut_abilities() } //end switch - innate abilities // a bit more stuff - if ( (you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE) || - player_genus(GENPC_DRACONIAN) || - you.species == SP_SPRIGGAN ) + if ( you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE + || player_genus(GENPC_DRACONIAN) || you.species == SP_SPRIGGAN ) { - if (have_any) - text += ", "; - text += "unfitting armour"; - have_any = true; + mutations.push_back("unfitting armour"); } if ( beogh_water_walk() ) - { - if (have_any) - text += ", "; - text += "water walking"; - have_any = true; - } + mutations.push_back("water walking"); + std::string current; for (unsigned i = 0; i < NUM_MUTATIONS; i++) { int level = player_mutation_level((mutation_type) i); if (!level) continue; - switch(i) + current = ""; + bool lowered = (level < you.mutation[i]); + switch (i) { case MUT_TOUGH_SKIN: AC_change += level; @@ -2395,80 +2364,45 @@ std::string _status_mut_abilities() case MUT_REPULSION_FIELD: EV_change += 2*level-1; if (level == 3) - { - if (have_any) - text += ", "; - text += "repel missiles"; - have_any = true; - } + current = "repel missiles"; break; case MUT_POISON_RESISTANCE: - if (have_any) - text += ", "; - text += "poison resistance"; - have_any = true; + current = "poison resistance"; break; case MUT_SAPROVOROUS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "saprovore %d", level); - text += info; - have_any = true; + current = info; break; case MUT_CARNIVOROUS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "carnivore %d", level); - text += info; - have_any = true; + current = info; break; case MUT_HERBIVOROUS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "herbivore %d", level); - text += info; - have_any = true; + current = info; break; case MUT_HEAT_RESISTANCE: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "fire resistance %d", level); - text += info; - have_any = true; + current = info; break; case MUT_COLD_RESISTANCE: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "cold resistance %d", level); - text += info; - have_any = true; + current = info; break; case MUT_SHOCK_RESISTANCE: - if (have_any) - text += ", "; - text += "electricity resistance"; - have_any = true; + current = "electricity resistance"; break; case MUT_REGENERATION: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "regeneration %d", level); - text += info; - have_any = true; + current = info; break; case MUT_FAST_METABOLISM: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "fast metabolism %d", level); - text += info; - have_any = true; + current = info; break; case MUT_SLOW_METABOLISM: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "slow metabolism %d", level); - text += info; - have_any = true; + current = info; break; case MUT_WEAK: Str_change -= level; @@ -2480,84 +2414,48 @@ std::string _status_mut_abilities() Dex_change -= level; break; case MUT_TELEPORT_CONTROL: - if (have_any) - text += ", "; - text += "teleport control"; - have_any = true; + current = "teleport control"; break; case MUT_TELEPORT: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "teleportitis %d", level); - text += info; - have_any = true; + current = info; break; case MUT_MAGIC_RESISTANCE: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "magic resistance %d", level); - text += info; - have_any = true; + current = info; break; case MUT_FAST: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "speed %d", level); - text += info; - have_any = true; + current = info; break; case MUT_ACUTE_VISION: - if (have_any) - text += ", "; - text += "see invisible"; - have_any = true; + current = "see invisible"; break; case MUT_DEFORMED: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "deformed body %d", level); - text += info; - have_any = true; + current = info; break; case MUT_TELEPORT_AT_WILL: snprintf(info, INFO_SIZE, "teleport at will %d", level); - if (have_any) - text += ", "; - text += info; - have_any = true; + current = info; break; case MUT_SPIT_POISON: - if (have_any) - text += ", "; - text += "spit poison"; - have_any = true; + current = "spit poison"; break; case MUT_MAPPING: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "sense surroundings %d", level); - text += info; - have_any = true; + current = info; break; case MUT_BREATHE_FLAMES: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "breathe flames %d", level); - text += info; - have_any = true; + current = info; break; case MUT_BLINK: - if (have_any) - text += ", "; - text += "blink"; - have_any = true; + current = "blink"; break; case MUT_HORNS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "horns %d", level); - text += info; - have_any = true; + current = info; break; case MUT_STRONG_STIFF: Str_change += level; @@ -2568,227 +2466,126 @@ std::string _status_mut_abilities() Dex_change += level; break; case MUT_SCREAM: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "screaming %d", level); - text += info; - have_any = true; + current = info; break; case MUT_CLARITY: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "clarity %d", level); - text += info; - have_any = true; + current = info; break; case MUT_BERSERK: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "berserk %d", level); - text += info; - have_any = true; + current = info; break; case MUT_DETERIORATION: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "deterioration %d", level); - text += info; - have_any = true; + current = info; break; case MUT_BLURRY_VISION: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "blurry vision %d", level); - text += info; - have_any = true; + current = info; break; case MUT_MUTATION_RESISTANCE: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "mutation resistance %d", level); - text += info; - have_any = true; + current = info; break; case MUT_FRAIL: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "-%d%% hp", level*10); - text += info; - have_any = true; + current = info; break; case MUT_ROBUST: - if (have_any) - text += ", "; - snprintf(info, INFO_SIZE, "+%d hp%%", level*10); - text += info; - have_any = true; + snprintf(info, INFO_SIZE, "+%d%% hp", level*10); + current = info; break; case MUT_LOW_MAGIC: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "-%d%% mp", level*10); - text += info; - have_any = true; + current = info; break; case MUT_HIGH_MAGIC: - if (have_any) - text += ", "; - snprintf(info, INFO_SIZE, "+%d mp%%", level*10); - text += info; - have_any = true; + snprintf(info, INFO_SIZE, "+%d%% mp", level*10); + current = info; break; /* demonspawn mutations */ case MUT_TORMENT_RESISTANCE: - if (have_any) - text += ", "; - text += "torment resistance"; - have_any = true; + current = "torment resistance"; break; case MUT_NEGATIVE_ENERGY_RESISTANCE: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "life protection %d", level); - text += info; - have_any = true; + current = info; break; case MUT_SUMMON_MINOR_DEMONS: - if (have_any) - text += ", "; - text += "summon minor demons"; - have_any = true; + current = "summon minor demons"; break; case MUT_SUMMON_DEMONS: - if (have_any) - text += ", "; - text += "summon demons"; - have_any = true; + current = "summon demons"; break; case MUT_HURL_HELLFIRE: - if (have_any) - text += ", "; - text += "hurl hellfire"; - have_any = true; + current = "hurl hellfire"; break; case MUT_CALL_TORMENT: - if (have_any) - text += ", "; - text += "call torment"; - have_any = true; + current = "call torment"; break; case MUT_RAISE_DEAD: - if (have_any) - text += ", "; - text += "raise dead"; - have_any = true; + current = "raise dead"; break; case MUT_CONTROL_DEMONS: - if (have_any) - text += ", "; - text += "control demons"; - have_any = true; + current = "control demons"; break; case MUT_PANDEMONIUM: - if (have_any) - text += ", "; - text += "portal to Pandemonium"; - have_any = true; + current = "portal to Pandemonium"; break; case MUT_DEATH_STRENGTH: - if (have_any) - text += ", "; - text += "draw strength from death and destruction"; - have_any = true; + current = "draw strength from death and destruction"; break; case MUT_CHANNEL_HELL: - if (have_any) - text += ", "; - text += "channel magical energy from Hell"; - have_any = true; + current = "channel magical energy from Hell"; break; case MUT_DRAIN_LIFE: - if (have_any) - text += ", "; - text += "drain life"; - have_any = true; + current = "drain life"; break; case MUT_THROW_FLAMES: - if (have_any) - text += ", "; - text += "throw flames of Gehenna"; - have_any = true; + current = "throw flames of Gehenna"; break; case MUT_THROW_FROST: - if (have_any) - text += ", "; - text += "throw frost of Cocytus"; - have_any = true; + current = "throw frost of Cocytus"; break; case MUT_SMITE: - if (have_any) - text += ", "; - text += "invoke powers of Tartarus"; - have_any = true; + current = "invoke powers of Tartarus"; break; /* end of demonspawn mutations */ + case MUT_CLAWS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "claws %d", level); - text += info; - have_any = true; + current = info; break; case MUT_FANGS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "sharp teeth %d", level); - text += info; - have_any = true; + current = info; break; case MUT_HOOVES: - if (have_any) - text += ", "; - text += "hooves"; - have_any = true; + current = "hooves"; break; case MUT_TALONS: - if (have_any) - text += ", "; - text += "talons"; - have_any = true; + current = "talons"; break; case MUT_BREATHE_POISON: - if (have_any) - text += ", "; - text += "breathe poison"; - have_any = true; + current = "breathe poison"; break; case MUT_STINGER: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "stinger %d", level); - text += info; - have_any = true; + current = info; break; case MUT_BIG_WINGS: - if (have_any) - text += ", "; - text += "large and strong wings"; - have_any = true; + current = "large and strong wings"; break; case MUT_BLUE_MARKS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "blue evil mark %d", level); - text += info; - have_any = true; + current = info; break; case MUT_GREEN_MARKS: - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "green evil mark %d", level); - text += info; - have_any = true; + current = info; break; // scales etc. -> calculate sum of AC bonus @@ -2860,54 +2657,53 @@ std::string _status_mut_abilities() break; case MUT_SHAGGY_FUR: AC_change += level; + if (level == 3) + current = "shaggy fur"; break; default: break; } + + if (!current.empty()) + { + if (lowered) + current = "<darkgrey>" + current + "</darkgrey>"; + mutations.push_back(current); + } } if (AC_change) { - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "AC %s%d", (AC_change > 0 ? "+" : ""), AC_change); - text += info; - have_any = true; + mutations.push_back(info); } if (EV_change) { - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "EV +%d", EV_change); - text += info; - have_any = true; + mutations.push_back(info); } if (Str_change) { - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "Str %s%d", (Str_change > 0 ? "+" : ""), Str_change); - text += info; - have_any = true; + mutations.push_back(info); } if (Int_change) { - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "Int %s%d", (Int_change > 0 ? "+" : ""), Int_change); - text += info; - have_any = true; + mutations.push_back(info); } if (Dex_change) { - if (have_any) - text += ", "; snprintf(info, INFO_SIZE, "Dex %s%d", (Dex_change > 0 ? "+" : ""), Dex_change); - text += info; - have_any = true; + mutations.push_back(info); } - if (!have_any) + if (mutations.empty()) text += "no striking features"; + else + { + text += comma_separated_line(mutations.begin(), mutations.end(), + ", ", ", "); + } //---------------------------- // print ability information diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index d268662df3..c06ff1a2d9 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6111,12 +6111,30 @@ mon_holy_type player::holiness() const return (MH_NATURAL); } +// Output active level of player mutation. +// Might be lower than real mutation for non-"Alive" Vampires. int player_mutation_level(mutation_type mut) { - if (!mutation_is_active(mut)) - return 0; + const int mlevel = you.mutation[mut]; + + if (mutation_is_fully_active(mut)) + return (mlevel); + + // For now, dynamic mutation only apply to vampires. + ASSERT(you.species == SP_VAMPIRE); - return (you.mutation[mut]); + // Assumption: stat mutations are physical, and thus always fully active. + switch (you.hunger_state) + { + case HS_ENGORGED: + return (mlevel); + case HS_VERY_FULL: + case HS_FULL: + return (std::min(mlevel, 2)); + case HS_SATIATED: + return (std::min(mlevel, 1)); + } + return (0); } int player::res_fire() const |