summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/xom.cc
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-03-31 07:05:53 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-03-31 07:05:53 +0000
commit20e25439cad6e0c97716e197bb2dceae731a9d24 (patch)
treed188c2b097b39976c6084a5619b5668dd823ada4 /crawl-ref/source/xom.cc
parent4f02417442109656263366ffcefd68231a0da7e9 (diff)
downloadcrawl-ref-20e25439cad6e0c97716e197bb2dceae731a9d24.tar.gz
crawl-ref-20e25439cad6e0c97716e197bb2dceae731a9d24.zip
Add some checks to Xom making you cast spells, so you don't attempt to
e.g. cast a branding spell, or a transformation that will fail for whatever reason. You may still occasionally get a "The spell fizzled" (or whatever) message but that should be rarer now. Apply the same fail chances for Detect Items as for Magic Mapping for fully explored levels, and for low severity make Summon Butterflies more likely to avoid endless attempts of casting Magic Mapping on fully explored levels. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9573 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/xom.cc')
-rw-r--r--crawl-ref/source/xom.cc110
1 files changed, 92 insertions, 18 deletions
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());
}
}