diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/command.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 12 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/transfor.cc | 41 | ||||
-rw-r--r-- | crawl-ref/source/transfor.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/xom.cc | 110 | ||||
-rw-r--r-- | crawl-ref/source/xom.h | 2 |
7 files changed, 128 insertions, 43 deletions
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 6014528aae..6bcb35072f 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -1371,6 +1371,7 @@ static bool _do_description(std::string key, std::string type, if (thing_created != NON_ITEM && (type == "item" || type == "spell")) { + char name[80]; strncpy(name, key.c_str(), sizeof(name)); if (get_item_by_name(&mitm[thing_created], name, OBJ_WEAPONS)) diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 4736162af4..1fd4cd306f 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -930,14 +930,11 @@ static void _rune_from_specs(const char* _specs, item_def &item) while (true) { - mpr( -"[a] iron [b] obsidian [c] icy [d] bone [e] slimy [f] silver", + mpr("[a] iron [b] obsidian [c] icy [d] bone [e] slimy [f] silver", MSGCH_PROMPT); - mpr( -"[g] serpentine [h] elven [i] golden [j] decaying [k] barnacle [l] demonic", + mpr("[g] serpentine [h] elven [i] golden [j] decaying [k] barnacle [l] demonic", MSGCH_PROMPT); - mpr( -"[m] abyssal [n] glowing [o] magical [p] fiery [q] dark [r] buggy", + mpr("[m] abyssal [n] glowing [o] magical [p] fiery [q] dark [r] buggy", MSGCH_PROMPT); mpr("Which rune (ESC to exit)? ", MSGCH_PROMPT); @@ -2424,7 +2421,6 @@ void wizard_gain_piety() } else if (you.religion == GOD_XOM) { - const std::string old_xom_favour = describe_xom_favour(); you.piety = random2(MAX_PIETY+1); // reroll mood if (one_chance_in(10)) you.gift_timeout = 0; @@ -2432,7 +2428,7 @@ void wizard_gain_piety() you.gift_timeout = random2(40) + random2(40); // reroll interest const std::string new_xom_favour = describe_xom_favour(); - const std::string msg = "Your title is now: " + new_xom_favour; + const std::string msg = "You are now " + new_xom_favour; god_speaks(you.religion, msg.c_str()); return; } diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 97f0281497..bc612b78fc 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -3102,7 +3102,7 @@ std::string describe_favour(god_type which_god) : "You should show more discipline."; } - return (which_god == GOD_XOM) ? describe_xom_favour() + return (which_god == GOD_XOM) ? describe_xom_favour(true) : _describe_favour_generic(which_god); } diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc index 7243beae21..6431e6477e 100644 --- a/crawl-ref/source/transfor.cc +++ b/crawl-ref/source/transfor.cc @@ -354,7 +354,7 @@ bool check_transformation_stat_loss(const std::set<equipment_type> &remove, return (true); } - // Check over all items to be removed. + // Check over all items to be removed or melded. std::set<equipment_type>::const_iterator iter; for (iter = remove.begin(); iter != remove.end(); ++iter) { @@ -364,15 +364,14 @@ bool check_transformation_stat_loss(const std::set<equipment_type> &remove, const item_def& item = you.inv[you.equip[e]]; - // Wielding a stat-boosting non-weapon/non-staff won't hinder - // transformations. + // There are no stat-boosting non-weapons/non-staves. if (e == EQ_WEAPON && item.base_type != OBJ_WEAPONS && item.base_type != OBJ_STAVES) { continue; } - // Currently, the only nonartefacts which have stat-changing + // Currently, the only non-artefacts which have stat-changing // effects are rings. if (item.base_type == OBJ_JEWELLERY) { @@ -448,8 +447,10 @@ static void _transformation_expiration_warning() } // Transforms you into the specified form. If quiet is true, fails silently -// (if it fails). -bool transform(int pow, transformation_type which_trans, bool quiet) +// (if it fails). If just_check is true the transformation doesn't actually +// happen, but the method returns whether it would be successful. +bool transform(int pow, transformation_type which_trans, bool quiet, + bool just_check) { if (you.species == SP_MERFOLK && player_is_swimming() && which_trans != TRAN_DRAGON && which_trans != TRAN_BAT) @@ -471,6 +472,9 @@ bool transform(int pow, transformation_type which_trans, bool quiet) { if (you.duration[DUR_TRANSFORMATION] < 100) { + if (just_check) + return (true); + mpr("You extend your transformation's duration."); you.duration[DUR_TRANSFORMATION] += random2(pow); @@ -487,7 +491,7 @@ bool transform(int pow, transformation_type which_trans, bool quiet) } } - if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE) + if (!just_check && you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE) untransform(); // Catch some conditions which prevent transformation. @@ -568,7 +572,7 @@ bool transform(int pow, transformation_type which_trans, bool quiet) if (you.species == SP_MERFOLK && player_is_swimming()) { msg = "You fly out of the water as you turn into " - "a fearsome dragon!"; + "a fearsome dragon!"; } else msg = "You turn into a fearsome dragon!"; @@ -602,15 +606,19 @@ bool transform(int pow, transformation_type which_trans, bool quiet) } if (check_transformation_stat_loss(rem_stuff, quiet, - std::max(-str, 0), std::max(-dex,0))) + std::max(-str, 0), std::max(-dex, 0))) { return (false); } + // If we're just pretending return now. + if (just_check) + return (true); + // All checks done, transformation will take place now. - you.redraw_evasion = true; + you.redraw_evasion = true; you.redraw_armour_class = true; - you.wield_change = true; + you.wield_change = true; // Most transformations conflict with stone skin. if (which_trans != TRAN_NONE @@ -692,6 +700,11 @@ bool transform(int pow, transformation_type which_trans, bool quiet) break; } + // This only has an effect if the transformation happens passively, + // for example if Xom decides to transform you while you're busy + // running around or butchering corpses. + stop_delay(); + if (you.species != SP_VAMPIRE || which_trans != TRAN_BAT) _transformation_expiration_warning(); @@ -707,9 +720,9 @@ void untransform(void) { const flight_type old_flight = you.flight_mode(); - you.redraw_evasion = true; + you.redraw_evasion = true; you.redraw_armour_class = true; - you.wield_change = true; + you.wield_change = true; you.symbol = '@'; you.colour = LIGHTGREY; @@ -722,7 +735,7 @@ void untransform(void) std::set<equipment_type> melded = _init_equipment_removal(old_form); you.attribute[ATTR_TRANSFORMATION] = TRAN_NONE; - you.duration[DUR_TRANSFORMATION] = 0; + you.duration[DUR_TRANSFORMATION] = 0; int hp_downscale = 10; diff --git a/crawl-ref/source/transfor.h b/crawl-ref/source/transfor.h index 072b92a4f9..d9cc16f1bc 100644 --- a/crawl-ref/source/transfor.h +++ b/crawl-ref/source/transfor.h @@ -38,7 +38,8 @@ bool check_transformation_stat_loss(const std::set<equipment_type> &remove, int dex_loss = 0, int int_loss = 0); size_type transform_size(int psize = PSIZE_BODY); -bool transform(int pow, transformation_type which_trans, bool quiet = false); +bool transform(int pow, transformation_type which_trans, bool quiet = false, + bool just_check = false); void remove_one_equip(equipment_type eq, bool meld = true); void unmeld_one_equip(equipment_type eq); diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index 0626b35b5f..82abc823f1 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -58,14 +58,18 @@ REVISION("$Rev$"); // Which spells? First I copied all spells from your_spells(), and then // I filtered some out, especially conjurations. Then I sorted them in // roughly ascending order of power. + +// Spells to be cast at tension 0 (no or only low-level monsters around), +// mostly flavour. static const spell_type _xom_nontension_spells[] = { - SPELL_MAGIC_MAPPING, SPELL_DETECT_ITEMS, SPELL_DETECT_CREATURES, - SPELL_OLGREBS_TOXIC_RADIANCE, SPELL_SUMMON_BUTTERFLIES, - SPELL_FLY, SPELL_SPIDER_FORM, SPELL_STATUE_FORM, SPELL_ICE_FORM, + SPELL_MAGIC_MAPPING, SPELL_DETECT_ITEMS, SPELL_SUMMON_BUTTERFLIES, + SPELL_DETECT_CREATURES, SPELL_FLY, SPELL_SPIDER_FORM, + SPELL_OLGREBS_TOXIC_RADIANCE, SPELL_STATUE_FORM, SPELL_ICE_FORM, SPELL_DRAGON_FORM, SPELL_NECROMUTATION }; +// Spells to be cast at tension > 0, i.e. usually in battle situations. static const spell_type _xom_tension_spells[] = { SPELL_BLINK, SPELL_CONFUSING_TOUCH, SPELL_CAUSE_FEAR, @@ -106,22 +110,28 @@ static const char *_xom_message_arrays[NUM_XOM_MESSAGE_TYPES][6] = } }; -const char *describe_xom_favour() +const char *describe_xom_favour(bool upper) { + std::string favour; if (you.religion != GOD_XOM) - return ("A very buggy toy of Xom."); + favour = "a very buggy toy of Xom."; else if (you.gift_timeout < 1) - return "A BORING thing."; + favour = "a BORING thing."; else { - return (you.piety > 180) ? "Xom's teddy bear." : - (you.piety > 150) ? "A beloved toy of Xom." : - (you.piety > 120) ? "A favourite toy of Xom." : - (you.piety > 80) ? "A toy of Xom." : - (you.piety > 50) ? "A plaything of Xom." : - (you.piety > 20) ? "A special plaything of Xom." - : "A very special plaything of Xom."; + favour = (you.piety > 180) ? "Xom's teddy bear." : + (you.piety > 150) ? "a beloved toy of Xom." : + (you.piety > 120) ? "a favourite toy of Xom." : + (you.piety > 80) ? "a toy of Xom." : + (you.piety > 50) ? "a plaything of Xom." : + (you.piety > 20) ? "a special plaything of Xom." + : "a very special plaything of Xom."; } + + if (upper) + favour = uppercase_first(favour); + + return (favour.c_str()); } static std::string _get_xom_speech(const std::string key) @@ -248,7 +258,7 @@ void xom_tick() new_xom_favour = describe_xom_favour(); if (old_xom_favour != new_xom_favour) { - const std::string msg = "Your title is now: " + new_xom_favour; + const std::string msg = "You are now " + new_xom_favour; god_speaks(you.religion, msg.c_str()); } @@ -351,9 +361,60 @@ static int _exploration_estimate(bool seen_only = false) return (seen); } +static bool _spell_requires_weapon(const spell_type spell) +{ + switch (spell) + { + case SPELL_TUKIMAS_VORPAL_BLADE: + case SPELL_MAXWELLS_SILVER_HAMMER: + case SPELL_FIRE_BRAND: + case SPELL_FREEZING_AURA: + case SPELL_POISON_WEAPON: + case SPELL_LETHAL_INFUSION: + case SPELL_EXCRUCIATING_WOUNDS: + case SPELL_WARP_BRAND: + case SPELL_TUKIMAS_DANCE: + return (true); + default: + return (false); + } +} + +static bool _transformation_check(const spell_type spell) +{ + transformation_type tran = TRAN_NONE; + switch (spell) + { + case SPELL_SPIDER_FORM: + tran = TRAN_SPIDER; + break; + case SPELL_STATUE_FORM: + tran = TRAN_STATUE; + break; + case SPELL_ICE_FORM: + tran = TRAN_ICE_BEAST; + break; + case SPELL_DRAGON_FORM: + tran = TRAN_DRAGON; + break; + case SPELL_NECROMUTATION: + tran = TRAN_LICH; + break; + default: + break; + } + + if (tran == TRAN_NONE) + return (true); + + // Check whether existing enchantments/transformations, cursed equipment, + // or potential stat loss interfere with this transformation. + return transform(0, tran, true, true); +} + static bool _xom_makes_you_cast_random_spell(int sever, int tension) { - int spellenum = sever; + int spellenum = std::max(1, sever); god_acting gdact(GOD_XOM); @@ -363,14 +424,20 @@ static bool _xom_makes_you_cast_random_spell(int sever, int tension) const int nxomspells = ARRAYSZ(_xom_tension_spells); spellenum = std::min(nxomspells, spellenum); spell = _xom_tension_spells[random2(spellenum)]; + + // Don't attempt to cast spells that are guaranteed to fail. + // You may still get results such as "The spell fizzles" or + // "Nothing appears to happen", but those should be rarer now. + if (_spell_requires_weapon(spell) && !player_weapon_wielded()) + return (false); } else { const int nxomspells = ARRAYSZ(_xom_nontension_spells); - spellenum = std::min(nxomspells, spellenum); + spellenum = std::min(nxomspells, std::max(3 + coinflip(), spellenum)); spell = _xom_nontension_spells[random2(spellenum)]; - if (spell == SPELL_MAGIC_MAPPING) + if (spell == SPELL_MAGIC_MAPPING || spell == SPELL_DETECT_ITEMS) { // If the level is already mostly explored, there's // a chance we might try something else. @@ -383,6 +450,10 @@ static bool _xom_makes_you_cast_random_spell(int sever, int tension) if (you_cannot_memorise(spell)) return (false); + // Don't attempt to transform the player if the transformation will fail. + if (!_transformation_check(spell)) + return (false); + god_speaks(GOD_XOM, _get_xom_speech("spell effect").c_str()); #if defined(DEBUG_DIAGNOSTICS) || defined(DEBUG_RELIGION) || defined(DEBUG_XOM) @@ -2135,6 +2206,9 @@ static bool _xom_is_bad(int sever, int tension) mprf(MSGCH_DIAGNOSTICS, "badness: %d, new interest: %d", badness, you.gift_timeout); #endif + const std::string new_xom_favour = describe_xom_favour(); + const std::string msg = "You are now " + new_xom_favour; + god_speaks(you.religion, msg.c_str()); } return (done); } @@ -2367,7 +2441,7 @@ void xom_acts(bool niceness, int sever, int tension) const std::string new_xom_favour = describe_xom_favour(); if (old_xom_favour != new_xom_favour) { - const std::string msg = "Your title is now: " + new_xom_favour; + const std::string msg = "You are now " + new_xom_favour; god_speaks(you.religion, msg.c_str()); } } diff --git a/crawl-ref/source/xom.h b/crawl-ref/source/xom.h index cda54827fd..cd1c0a67bb 100644 --- a/crawl-ref/source/xom.h +++ b/crawl-ref/source/xom.h @@ -28,7 +28,7 @@ void xom_is_stimulated(int maxinterestingness, const std::string& message, bool force_message = false); bool xom_is_nice(); void xom_acts(bool niceness, int sever, int tension = -1); -const char *describe_xom_favour(); +const char *describe_xom_favour(bool upper = false); inline void xom_acts(int sever, int tension = -1) { |