Attached Files |
0001-Clean-merged-full-recite-patch.patch [^] (22,935 bytes) 2014-05-09 03:14 [Show Content] [Hide Content]From 93481f97497766315c8bbdb2cd05d7b0bb8d27f5 Mon Sep 17 00:00:00 2001
From: Keanan Smith <keanan.smith@gmail.com>
Date: Thu, 8 May 2014 19:13:26 -0600
Subject: [PATCH] Clean merged recite patch
---
crawl-ref/source/ability.cc | 11 +-
crawl-ref/source/enum.h | 4 +-
crawl-ref/source/godabil.cc | 450 ++++++++++++++++----------------------
crawl-ref/source/godabil.h | 5 +-
crawl-ref/source/player-reacts.cc | 2 +-
crawl-ref/source/spl-summoning.cc | 2 +-
crawl-ref/source/spl-summoning.h | 2 +-
7 files changed, 198 insertions(+), 278 deletions(-)
diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index 6c803bb..f4cc71a 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -1514,7 +1514,7 @@ static bool _check_ability_possible(const ability_def& abil,
if (!zin_check_able_to_recite(quiet))
return false;
- const int result = zin_check_recite_to_monsters(0);
+ const int result = zin_check_recite_to_monsters();
if (result == -1)
{
if (!quiet)
@@ -2392,16 +2392,13 @@ static bool _do_ability(const ability_def& abil)
// INVOCATIONS:
case ABIL_ZIN_RECITE:
{
- recite_type prayertype;
- if (zin_check_recite_to_monsters(&prayertype))
+ if (zin_check_recite_to_monsters())
{
- you.attribute[ATTR_RECITE_TYPE] = prayertype;
+ you.attribute[ATTR_RECITE_TYPE] = (recite_type) random2(NUM_RECITE_TYPES); // This is now just flavor
you.attribute[ATTR_RECITE_SEED] = random2(2187); // 3^7
you.attribute[ATTR_RECITE_HP] = you.hp;
you.duration[DUR_RECITE] = 3 * BASELINE_DELAY;
- mprf("You clear your throat and prepare to recite %s.",
- zin_recite_text(you.attribute[ATTR_RECITE_SEED],
- prayertype, -1).c_str());
+ mprf("You clear your throat and prepare to recite.");
}
else
{
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 1d17ef2..46eb540 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -3484,11 +3484,11 @@ enum orb_type
};
enum recite_type
-{
+{ // In case of ties higher supersedes lower
RECITE_CHAOTIC,
RECITE_IMPURE,
- RECITE_HERETIC,
RECITE_UNHOLY,
+ RECITE_HERETIC,
NUM_RECITE_TYPES
};
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index 5dea389..6607fc9 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -53,6 +53,7 @@
#include "player-stats.h"
#include "potion.h"
#include "random.h"
+#include "random-weight.h"
#include "religion.h"
#include "skill_menu.h"
#include "shopping.h"
@@ -544,11 +545,6 @@ static int _zin_check_recite_to_single_monster(const monster *mon,
eligibility[RECITE_IMPURE] = 0;
}
- // Don't allow against enemies that are already affected by an
- // earlier recite type.
- if (eligibility[RECITE_CHAOTIC] > 0)
- eligibility[RECITE_IMPURE] = 0;
-
// Anti-unholy prayer
// Hits demons and incorporeal undead.
@@ -558,13 +554,6 @@ static int _zin_check_recite_to_single_monster(const monster *mon,
eligibility[RECITE_UNHOLY]++;
}
- // Don't allow against enemies that are already affected by an
- // earlier recite type.
- if (eligibility[RECITE_CHAOTIC] > 0
- || eligibility[RECITE_IMPURE] > 0)
- {
- eligibility[RECITE_UNHOLY] = 0;
- }
// Anti-heretic prayer
@@ -592,14 +581,6 @@ static int _zin_check_recite_to_single_monster(const monster *mon,
// (The above mean that worshipers will be treated as
// priests for reciting, even if they aren't actually.)
- // Don't allow against enemies that are already affected by an
- // earlier recite type.
- if (eligibility[RECITE_CHAOTIC] > 0
- || eligibility[RECITE_IMPURE] > 0
- || eligibility[RECITE_UNHOLY] > 0)
- {
- eligibility[RECITE_HERETIC] = 0;
- }
// Sanity check: monsters that won't attack you, and aren't
// priests/evil, don't get recited against.
@@ -674,7 +655,7 @@ static const char* zin_book_desc[NUM_RECITE_TYPES] =
* monsters, and at least one returned -1 from
* _zin_check_recite_to_single_monster().
*/
-int zin_check_recite_to_monsters(recite_type *prayertype)
+int zin_check_recite_to_monsters()
{
bool found_ineligible = false;
bool found_eligible = false;
@@ -717,84 +698,11 @@ int zin_check_recite_to_monsters(recite_type *prayertype)
return -1;
}
- if (!prayertype)
- return 1;
-
int eligible_types = 0;
for (int i = 0; i < NUM_RECITE_TYPES; i++)
if (count[i] > 0)
eligible_types++;
-
- // If there's only one eligible recitation, and we're actually reciting, then perform it.
- if (eligible_types == 1)
- {
- for (int i = 0; i < NUM_RECITE_TYPES; i++)
- if (count[i] > 0)
- *prayertype = (recite_type)i;
-
- return 1;
- }
-
- // But often, you'll have multiple options...
- mesclr();
-
- mprf(MSGCH_PROMPT, "Recite against which type of sinner?");
-
- int menu_cnt = 0;
- recite_type letters[NUM_RECITE_TYPES];
-
- for (int i = 0; i < NUM_RECITE_TYPES; i++)
- {
- if (count[i] > 0)
- {
- string affected_str = make_stringf("%s (%d: ",
- zin_book_desc[i], count[i]);
-
- // TODO: merge with _desc_mons_type_map from view.cc? But we
- // probably don't want genus factoring here.
- // TODO: sort these by something other than name-with-article.
- for (map<string, int>::iterator it = affected_by_type[i].begin();
- it != affected_by_type[i].end(); it++)
- {
- if (it != affected_by_type[i].begin())
- affected_str += ", ";
-
- affected_str += it->first;
- if (it->second > 1)
- affected_str += make_stringf(" x%d", it->second);
- }
- affected_str += ")";
-
- int linect = 0;
- while (!affected_str.empty())
- {
- // -8 for " [a] - "
- const string line = wordwrap_line(affected_str,
- msgwin_line_length() - 8);
- if (linect++ == 0)
- mprf_nojoin(" [%c] - %s", 'a' + menu_cnt, line.c_str());
- else
- mprf("%8s%s", "", line.c_str());
- }
- letters[menu_cnt++] = (recite_type)i;
- }
- }
- flush_prev_message();
-
- while (true)
- {
- int keyn = toalower(getch_ck());
-
- if (keyn >= 'a' && keyn < 'a' + menu_cnt)
- {
- *prayertype = letters[keyn - 'a'];
- break;
- }
- else
- return 0;
- }
-
- return 1;
+ return 1; // We now just recite against everything.
}
enum zin_eff
@@ -815,11 +723,171 @@ enum zin_eff
ZIN_SALTIFY,
ZIN_ROT,
ZIN_HOLY_WORD,
+ ZIN_ABJURE,
+ ZIN_SLOW
};
+static int zin_str2wt(int str,int pow)
+{
+ int chance;
+ if(abs(str-pow) >= 20)
+ return 0;
+ chance = (20-abs(str-pow))/2;
+ return chance*chance; // Weights very heavily towards things which match power to strength
+ // str == power, weight 100,
+ // str == power +/-1, weight 81
+ // str == power +/-2, weight 64
+ // ...
+ // str == power +/-7, weight 9
+ // str == power +/-8, weight 4
+ // str == power +/-9, weight 1
+}
+static void zin_eff_push(zin_eff effect,int str,int pow,vector<pair<zin_eff, int> > &weightlist)
+{
+ int wt;
+ wt = zin_str2wt(str,pow);
+ if(wt)
+ {
+ (weightlist).push_back(make_pair(effect, wt));
+ }
+}
+static zin_eff zin_choose_effect(recite_type prayertype,int power, int eff, monster* mon)
+{
+ // We have a different weighted list of effects for each prayertype.
+ // The weights of effects are such that the closer we are to the power level
+ // The more likely the effect, Effects more than 5 away from the power level will very rarely be chosen (<1%).
+ // Some other things which can influence the weight of each effect are succeptibility,
+ // and how affected the target would be by this type of effect.
+ vector<pair<zin_eff, int> > eff_weights;
+ switch(prayertype)
+ {
+ case RECITE_HERETIC:
+ {
+ //HERETIC actually has two different lists depending on whether they are just 'intelligent' or actively 'evil'
+ if(eff == 1)
+ {
+ zin_eff_push(ZIN_DAZE,4,power,eff_weights);
+ zin_eff_push(ZIN_SLOW,7,power,eff_weights);
+ zin_eff_push(ZIN_CONFUSE,9,power,eff_weights);
+ zin_eff_push(ZIN_PARALYSE,12,power,eff_weights);
+ }
+ else
+ {
+ zin_eff_push(ZIN_BLEED,4,power,eff_weights);
+ zin_eff_push(ZIN_SMITE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_BLIND,9,power,eff_weights);
+ zin_eff_push(ZIN_PARALYSE,12,power,eff_weights);
+ zin_eff_push(ZIN_MUTE,13,power,eff_weights);
+ zin_eff_push(ZIN_MAD,17,power,eff_weights);
+ zin_eff_push(ZIN_DUMB,18,power,eff_weights);
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ // Antimagic always has a good chance of happening when creature is succeptible,
+ // once you have enough power.
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ }
+ break;
+ }
+ case RECITE_CHAOTIC:
+ {
+ if(mon->can_bleed())
+ {
+ zin_eff_push(ZIN_BLEED,4,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SMITE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_IGNITE_CHAOS,12,power,eff_weights);
+ zin_eff_push(ZIN_SALTIFY,18,power,eff_weights);
-bool zin_recite_to_single_monster(const coord_def& where,
- recite_type prayertype)
+ // Antimagic and Anjuration always have decent odds of happening when creature is succeptible,
+ // once you have enough power.
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ if((power>7) && mon->is_summoned())
+ {
+ zin_eff_push(ZIN_ABJURE,power-1,power,eff_weights);
+ }
+ break;
+ }
+ case RECITE_IMPURE:
+ {
+ if(mon->can_bleed())
+ {
+ zin_eff_push(ZIN_BLEED,4,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SMITE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_ROT,9,power,eff_weights);
+ zin_eff_push(ZIN_SLOW,13,power,eff_weights);
+ if(mon->undead_or_demonic())
+ {
+ zin_eff_push(ZIN_HOLY_WORD,12,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SALTIFY,18,power,eff_weights);
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ if((power>7) && mon->is_summoned())
+ {
+ zin_eff_push(ZIN_ABJURE,power-1,power,eff_weights);
+ }
+ break;
+ }
+ case RECITE_UNHOLY:
+ {
+ if(mons_intel(mon) > I_INSECT)
+ {
+ zin_eff_push(ZIN_DAZE,4,power,eff_weights);
+ }
+ zin_eff_push(ZIN_CONFUSE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_SLOW,13,power,eff_weights);
+ if(mon->undead_or_demonic())
+ {
+ zin_eff_push(ZIN_HOLY_WORD,12,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SALTIFY,18,power,eff_weights);
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ if((power>7) && mon->is_summoned())
+ {
+ zin_eff_push(ZIN_ABJURE,power-1,power,eff_weights);
+ }
+ break;
+ }
+ default:
+ return ZIN_NOTHING;
+ }
+ if(eff_weights.size() > 0)
+ return *random_choose_weighted(eff_weights);
+ else
+ return ZIN_NOTHING;
+}
+bool zin_recite_to_single_monster(const coord_def& where)
{
+ recite_type prayertype;
// That's a pretty good sanity check, I guess.
if (!you_worship(GOD_ZIN))
return false;
@@ -835,11 +903,15 @@ bool zin_recite_to_single_monster(const coord_def& where,
if (_zin_check_recite_to_single_monster(mon, eligibility) < 1)
return false;
-
- // First check: are they even eligible for this kind of recitation?
- // (Monsters that have been hurt by recitation aren't eligible.)
- if (eligibility[prayertype] < 1)
- return false;
+ // Find the prayer we are *most* eligable to be hit by
+ prayertype = RECITE_CHAOTIC;
+ for(int i=RECITE_CHAOTIC;i != NUM_RECITE_TYPES;i++)
+ {
+ if(eligibility[i] > eligibility[prayertype])
+ {
+ prayertype = static_cast<recite_type>(i);
+ }
+ }
// Second check: because this affects the whole screen over several turns,
// its effects are staggered. There's a 50% chance per monster, per turn,
@@ -872,173 +944,25 @@ bool zin_recite_to_single_monster(const coord_def& where,
const int spellpower = power * 2 + degree * 20;
zin_eff effect = ZIN_NOTHING;
- switch (prayertype)
- {
- case RECITE_HERETIC:
- if (degree == 1)
- {
- if (mon->asleep())
- break;
- // This is the path for 'conversion' effects.
- // Their degree is only 1 if they weren't a priest,
- // a worshiper of an evil or chaotic god, etc.
-
- // Right now, it only has the 'failed conversion' effects, though.
- // This branch can't hit sleeping monsters - until they wake up.
-
- if (check < 5)
- effect = ZIN_DAZE;
- else if (check < 10)
- {
- if (coinflip())
- effect = ZIN_CONFUSE;
- else
- effect = ZIN_DAZE;
- }
- else if (check < 15)
- effect = ZIN_CONFUSE;
- else
- {
- if (one_chance_in(3))
- effect = ZIN_PARALYSE;
- else
- effect = ZIN_CONFUSE;
- }
- }
- else
- {
- // This is the path for 'smiting' effects.
- // Their degree is only greater than 1 if
- // they're unable to be redeemed.
- if (check < 5)
- {
- if (coinflip())
- effect = ZIN_BLEED;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 10)
- {
- if (one_chance_in(3))
- effect = ZIN_BLIND;
- else if (mons_antimagic_affected(mon))
- effect = ZIN_ANTIMAGIC;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else if (check < 15)
- {
- if (one_chance_in(3))
- effect = ZIN_BLIND;
- else if (coinflip())
- effect = ZIN_PARALYSE;
- else
- effect = ZIN_MUTE;
- }
- else
- {
- if (coinflip())
- effect = ZIN_MAD;
- else
- effect = ZIN_DUMB;
- }
- }
- break;
-
- case RECITE_CHAOTIC:
- if (check < 5)
- {
- // nastier -- fallthrough if immune
- if (coinflip() && mon->can_bleed())
- effect = ZIN_BLEED;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 10)
- {
- if (coinflip())
- effect = ZIN_SILVER_CORONA;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 15)
- {
- if (coinflip())
- effect = ZIN_IGNITE_CHAOS;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else
- effect = ZIN_SALTIFY;
- break;
-
- case RECITE_IMPURE:
- // Many creatures normally resistant to rotting are still affected,
- // because this is divine punishment. Those with no real flesh are
- // immune, of course.
- if (check < 5)
- {
- if (coinflip() && mon->can_bleed())
- effect = ZIN_BLEED;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 10)
- {
- if (coinflip() && mon->res_rotting() <= 1)
- effect = ZIN_ROT;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else if (check < 15)
+ effect = zin_choose_effect(prayertype,check,degree,mon);
+ // And the actual effects...
+ switch (effect)
{
- if (mon->undead_or_demonic() && coinflip())
- effect = ZIN_HOLY_WORD;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else
- effect = ZIN_SALTIFY;
+ case ZIN_NOTHING:
break;
-
- case RECITE_UNHOLY:
- if (check < 5)
- {
- if (mons_intel(mon) > I_INSECT && coinflip())
- effect = ZIN_DAZE;
- else
- effect = ZIN_CONFUSE;
- }
- else if (check < 10)
- {
- if (coinflip())
- effect = ZIN_CONFUSE;
- else
- effect = ZIN_SILVER_CORONA;
- }
- // Half of the time, the anti-unholy prayer will be capped at this
- // level of effect.
- else if (check < 15 || coinflip())
+ case ZIN_SLOW:
+ if (mon->add_ench(mon_enchant(ENCH_SLOW, degree, &you,
+ (degree + random2(spellpower)) * BASELINE_DELAY)))
{
- if (coinflip())
- effect = ZIN_HOLY_WORD;
- else
- effect = ZIN_SILVER_CORONA;
+ simple_monster_message(mon, " seems to move more slowly.");
+ affected = true;
}
- else
- effect = ZIN_SALTIFY;
break;
-
- case NUM_RECITE_TYPES:
- die("invalid recite type");
- }
-
- // And the actual effects...
- switch (effect)
- {
- case ZIN_NOTHING:
+ case ZIN_ABJURE:
+ simple_monster_message(mon, " is cast back to whence it came.");
+ _abjuration(spellpower,mon);
+ affected = true;
break;
-
case ZIN_DAZE:
if (mon->add_ench(mon_enchant(ENCH_DAZED, degree, &you,
(degree + random2(spellpower)) * BASELINE_DELAY)))
diff --git a/crawl-ref/source/godabil.h b/crawl-ref/source/godabil.h
index e913716..c991b9c 100644
--- a/crawl-ref/source/godabil.h
+++ b/crawl-ref/source/godabil.h
@@ -14,9 +14,8 @@ class stack_iterator;
string zin_recite_text(const int seed, const int prayertype, int step);
bool zin_check_able_to_recite(bool quiet = false);
-int zin_check_recite_to_monsters(recite_type *prayertype);
-bool zin_recite_to_single_monster(const coord_def& where,
- recite_type prayertype);
+int zin_check_recite_to_monsters();
+bool zin_recite_to_single_monster(const coord_def& where);
void zin_recite_interrupt();
bool zin_vitalisation();
void zin_remove_divine_stamina();
diff --git a/crawl-ref/source/player-reacts.cc b/crawl-ref/source/player-reacts.cc
index a1fa4d9..4137c1b 100644
--- a/crawl-ref/source/player-reacts.cc
+++ b/crawl-ref/source/player-reacts.cc
@@ -356,7 +356,7 @@ static bool _check_recite()
static int _zin_recite_to_monsters(coord_def where, int prayertype, int, actor *)
{
ASSERT_RANGE(prayertype, 0, NUM_RECITE_TYPES);
- return zin_recite_to_single_monster(where, (recite_type)prayertype);
+ return zin_recite_to_single_monster(where);
}
diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc
index eb04dd1..1f5a10c 100644
--- a/crawl-ref/source/spl-summoning.cc
+++ b/crawl-ref/source/spl-summoning.cc
@@ -2469,7 +2469,7 @@ spret_type cast_spellforged_servitor(int pow, god_type god, bool fail)
return SPRET_SUCCESS;
}
-static int _abjuration(int pow, monster *mon)
+int _abjuration(int pow, monster *mon)
{
// Scale power into something comparable to summon lifetime.
const int abjdur = pow * 12;
diff --git a/crawl-ref/source/spl-summoning.h b/crawl-ref/source/spl-summoning.h
index dedc626..0637bcc 100644
--- a/crawl-ref/source/spl-summoning.h
+++ b/crawl-ref/source/spl-summoning.h
@@ -95,7 +95,7 @@ bool twisted_resurrection(actor *caster, int pow, beh_type beha,
unsigned short foe, god_type god, bool actual = true);
spret_type cast_haunt(int pow, const coord_def& where, god_type god, bool fail);
-
+int _abjuration(int pow, monster *mon);
spret_type cast_abjuration(int pow, const coord_def& where, bool fail = false);
spret_type cast_aura_of_abjuration(int pow, bool fail = false);
void do_aura_of_abjuration(int delay);
--
1.8.1.2
0001-Clean-recite-merge-with-no-new-effects.patch [^] (21,800 bytes) 2014-05-09 03:19 [Show Content] [Hide Content]From d1500fbb56325cd645afa258cd81212ac25deda1 Mon Sep 17 00:00:00 2001
From: Keanan Smith <keanan.smith@gmail.com>
Date: Thu, 8 May 2014 19:19:43 -0600
Subject: [PATCH] Clean recite merge with no new effects
---
crawl-ref/source/ability.cc | 11 +-
crawl-ref/source/enum.h | 4 +-
crawl-ref/source/godabil.cc | 424 ++++++++++++++------------------------
crawl-ref/source/godabil.h | 5 +-
crawl-ref/source/player-reacts.cc | 2 +-
crawl-ref/source/spl-summoning.cc | 2 +-
crawl-ref/source/spl-summoning.h | 2 +-
7 files changed, 170 insertions(+), 280 deletions(-)
diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index 6c803bb..f4cc71a 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -1514,7 +1514,7 @@ static bool _check_ability_possible(const ability_def& abil,
if (!zin_check_able_to_recite(quiet))
return false;
- const int result = zin_check_recite_to_monsters(0);
+ const int result = zin_check_recite_to_monsters();
if (result == -1)
{
if (!quiet)
@@ -2392,16 +2392,13 @@ static bool _do_ability(const ability_def& abil)
// INVOCATIONS:
case ABIL_ZIN_RECITE:
{
- recite_type prayertype;
- if (zin_check_recite_to_monsters(&prayertype))
+ if (zin_check_recite_to_monsters())
{
- you.attribute[ATTR_RECITE_TYPE] = prayertype;
+ you.attribute[ATTR_RECITE_TYPE] = (recite_type) random2(NUM_RECITE_TYPES); // This is now just flavor
you.attribute[ATTR_RECITE_SEED] = random2(2187); // 3^7
you.attribute[ATTR_RECITE_HP] = you.hp;
you.duration[DUR_RECITE] = 3 * BASELINE_DELAY;
- mprf("You clear your throat and prepare to recite %s.",
- zin_recite_text(you.attribute[ATTR_RECITE_SEED],
- prayertype, -1).c_str());
+ mprf("You clear your throat and prepare to recite.");
}
else
{
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 1d17ef2..46eb540 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -3484,11 +3484,11 @@ enum orb_type
};
enum recite_type
-{
+{ // In case of ties higher supersedes lower
RECITE_CHAOTIC,
RECITE_IMPURE,
- RECITE_HERETIC,
RECITE_UNHOLY,
+ RECITE_HERETIC,
NUM_RECITE_TYPES
};
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index 5dea389..18bd104 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -53,6 +53,7 @@
#include "player-stats.h"
#include "potion.h"
#include "random.h"
+#include "random-weight.h"
#include "religion.h"
#include "skill_menu.h"
#include "shopping.h"
@@ -544,11 +545,6 @@ static int _zin_check_recite_to_single_monster(const monster *mon,
eligibility[RECITE_IMPURE] = 0;
}
- // Don't allow against enemies that are already affected by an
- // earlier recite type.
- if (eligibility[RECITE_CHAOTIC] > 0)
- eligibility[RECITE_IMPURE] = 0;
-
// Anti-unholy prayer
// Hits demons and incorporeal undead.
@@ -558,13 +554,6 @@ static int _zin_check_recite_to_single_monster(const monster *mon,
eligibility[RECITE_UNHOLY]++;
}
- // Don't allow against enemies that are already affected by an
- // earlier recite type.
- if (eligibility[RECITE_CHAOTIC] > 0
- || eligibility[RECITE_IMPURE] > 0)
- {
- eligibility[RECITE_UNHOLY] = 0;
- }
// Anti-heretic prayer
@@ -592,14 +581,6 @@ static int _zin_check_recite_to_single_monster(const monster *mon,
// (The above mean that worshipers will be treated as
// priests for reciting, even if they aren't actually.)
- // Don't allow against enemies that are already affected by an
- // earlier recite type.
- if (eligibility[RECITE_CHAOTIC] > 0
- || eligibility[RECITE_IMPURE] > 0
- || eligibility[RECITE_UNHOLY] > 0)
- {
- eligibility[RECITE_HERETIC] = 0;
- }
// Sanity check: monsters that won't attack you, and aren't
// priests/evil, don't get recited against.
@@ -674,7 +655,7 @@ static const char* zin_book_desc[NUM_RECITE_TYPES] =
* monsters, and at least one returned -1 from
* _zin_check_recite_to_single_monster().
*/
-int zin_check_recite_to_monsters(recite_type *prayertype)
+int zin_check_recite_to_monsters()
{
bool found_ineligible = false;
bool found_eligible = false;
@@ -717,84 +698,11 @@ int zin_check_recite_to_monsters(recite_type *prayertype)
return -1;
}
- if (!prayertype)
- return 1;
-
int eligible_types = 0;
for (int i = 0; i < NUM_RECITE_TYPES; i++)
if (count[i] > 0)
eligible_types++;
-
- // If there's only one eligible recitation, and we're actually reciting, then perform it.
- if (eligible_types == 1)
- {
- for (int i = 0; i < NUM_RECITE_TYPES; i++)
- if (count[i] > 0)
- *prayertype = (recite_type)i;
-
- return 1;
- }
-
- // But often, you'll have multiple options...
- mesclr();
-
- mprf(MSGCH_PROMPT, "Recite against which type of sinner?");
-
- int menu_cnt = 0;
- recite_type letters[NUM_RECITE_TYPES];
-
- for (int i = 0; i < NUM_RECITE_TYPES; i++)
- {
- if (count[i] > 0)
- {
- string affected_str = make_stringf("%s (%d: ",
- zin_book_desc[i], count[i]);
-
- // TODO: merge with _desc_mons_type_map from view.cc? But we
- // probably don't want genus factoring here.
- // TODO: sort these by something other than name-with-article.
- for (map<string, int>::iterator it = affected_by_type[i].begin();
- it != affected_by_type[i].end(); it++)
- {
- if (it != affected_by_type[i].begin())
- affected_str += ", ";
-
- affected_str += it->first;
- if (it->second > 1)
- affected_str += make_stringf(" x%d", it->second);
- }
- affected_str += ")";
-
- int linect = 0;
- while (!affected_str.empty())
- {
- // -8 for " [a] - "
- const string line = wordwrap_line(affected_str,
- msgwin_line_length() - 8);
- if (linect++ == 0)
- mprf_nojoin(" [%c] - %s", 'a' + menu_cnt, line.c_str());
- else
- mprf("%8s%s", "", line.c_str());
- }
- letters[menu_cnt++] = (recite_type)i;
- }
- }
- flush_prev_message();
-
- while (true)
- {
- int keyn = toalower(getch_ck());
-
- if (keyn >= 'a' && keyn < 'a' + menu_cnt)
- {
- *prayertype = letters[keyn - 'a'];
- break;
- }
- else
- return 0;
- }
-
- return 1;
+ return 1; // We now just recite against everything.
}
enum zin_eff
@@ -816,10 +724,153 @@ enum zin_eff
ZIN_ROT,
ZIN_HOLY_WORD,
};
+static int zin_str2wt(int str,int pow)
+{
+ int chance;
+ if(abs(str-pow) >= 20)
+ return 0;
+ chance = (20-abs(str-pow))/2;
+ return chance*chance; // Weights very heavily towards things which match power to strength
+ // str == power, weight 100,
+ // str == power +/-1, weight 81
+ // str == power +/-2, weight 64
+ // ...
+ // str == power +/-7, weight 9
+ // str == power +/-8, weight 4
+ // str == power +/-9, weight 1
+}
+static void zin_eff_push(zin_eff effect,int str,int pow,vector<pair<zin_eff, int> > &weightlist)
+{
+ int wt;
+ wt = zin_str2wt(str,pow);
+ if(wt)
+ {
+ (weightlist).push_back(make_pair(effect, wt));
+ }
+}
+static zin_eff zin_choose_effect(recite_type prayertype,int power, int eff, monster* mon)
+{
+ // We have a different weighted list of effects for each prayertype.
+ // The weights of effects are such that the closer we are to the power level
+ // The more likely the effect, Effects more than 5 away from the power level will very rarely be chosen (<1%).
+ // Some other things which can influence the weight of each effect are succeptibility,
+ // and how affected the target would be by this type of effect.
+ vector<pair<zin_eff, int> > eff_weights;
+ switch(prayertype)
+ {
+ case RECITE_HERETIC:
+ {
+ //HERETIC actually has two different lists depending on whether they are just 'intelligent' or actively 'evil'
+ if(eff == 1)
+ {
+ zin_eff_push(ZIN_DAZE,4,power,eff_weights);
+ zin_eff_push(ZIN_CONFUSE,9,power,eff_weights);
+ zin_eff_push(ZIN_PARALYSE,12,power,eff_weights);
+ }
+ else
+ {
+ zin_eff_push(ZIN_BLEED,4,power,eff_weights);
+ zin_eff_push(ZIN_SMITE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_BLIND,9,power,eff_weights);
+ zin_eff_push(ZIN_PARALYSE,12,power,eff_weights);
+ zin_eff_push(ZIN_MUTE,13,power,eff_weights);
+ zin_eff_push(ZIN_MAD,17,power,eff_weights);
+ zin_eff_push(ZIN_DUMB,18,power,eff_weights);
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ // Antimagic always has a good chance of happening when creature is succeptible,
+ // once you have enough power.
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ }
+ break;
+ }
+ case RECITE_CHAOTIC:
+ {
+ if(mon->can_bleed())
+ {
+ zin_eff_push(ZIN_BLEED,4,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SMITE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_IGNITE_CHAOS,12,power,eff_weights);
+ zin_eff_push(ZIN_SALTIFY,18,power,eff_weights);
-bool zin_recite_to_single_monster(const coord_def& where,
- recite_type prayertype)
+ // Antimagic and Anjuration always have decent odds of happening when creature is succeptible,
+ // once you have enough power.
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ break;
+ }
+ case RECITE_IMPURE:
+ {
+ if(mon->can_bleed())
+ {
+ zin_eff_push(ZIN_BLEED,4,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SMITE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ zin_eff_push(ZIN_ROT,9,power,eff_weights);
+ if(mon->undead_or_demonic())
+ {
+ zin_eff_push(ZIN_HOLY_WORD,12,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SALTIFY,18,power,eff_weights);
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ break;
+ }
+ case RECITE_UNHOLY:
+ {
+ if(mons_intel(mon) > I_INSECT)
+ {
+ zin_eff_push(ZIN_DAZE,4,power,eff_weights);
+ }
+ zin_eff_push(ZIN_CONFUSE,6,power,eff_weights);
+ if(mon->invisible()) // Double the chance of doing corona if the critter is invis
+ {
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SILVER_CORONA,7,power,eff_weights);
+ if(mon->undead_or_demonic())
+ {
+ zin_eff_push(ZIN_HOLY_WORD,12,power,eff_weights);
+ }
+ zin_eff_push(ZIN_SALTIFY,18,power,eff_weights);
+ if((power>7)&&mons_antimagic_affected(mon))
+ {
+ zin_eff_push(ZIN_ANTIMAGIC,power-1,power,eff_weights);
+ }
+ break;
+ }
+ default:
+ return ZIN_NOTHING;
+ }
+ if(eff_weights.size() > 0)
+ return *random_choose_weighted(eff_weights);
+ else
+ return ZIN_NOTHING;
+}
+bool zin_recite_to_single_monster(const coord_def& where)
{
+ recite_type prayertype;
// That's a pretty good sanity check, I guess.
if (!you_worship(GOD_ZIN))
return false;
@@ -835,11 +886,15 @@ bool zin_recite_to_single_monster(const coord_def& where,
if (_zin_check_recite_to_single_monster(mon, eligibility) < 1)
return false;
-
- // First check: are they even eligible for this kind of recitation?
- // (Monsters that have been hurt by recitation aren't eligible.)
- if (eligibility[prayertype] < 1)
- return false;
+ // Find the prayer we are *most* eligable to be hit by
+ prayertype = RECITE_CHAOTIC;
+ for(int i=RECITE_CHAOTIC;i != NUM_RECITE_TYPES;i++)
+ {
+ if(eligibility[i] > eligibility[prayertype])
+ {
+ prayertype = static_cast<recite_type>(i);
+ }
+ }
// Second check: because this affects the whole screen over several turns,
// its effects are staggered. There's a 50% chance per monster, per turn,
@@ -872,173 +927,12 @@ bool zin_recite_to_single_monster(const coord_def& where,
const int spellpower = power * 2 + degree * 20;
zin_eff effect = ZIN_NOTHING;
- switch (prayertype)
- {
- case RECITE_HERETIC:
- if (degree == 1)
- {
- if (mon->asleep())
- break;
- // This is the path for 'conversion' effects.
- // Their degree is only 1 if they weren't a priest,
- // a worshiper of an evil or chaotic god, etc.
-
- // Right now, it only has the 'failed conversion' effects, though.
- // This branch can't hit sleeping monsters - until they wake up.
-
- if (check < 5)
- effect = ZIN_DAZE;
- else if (check < 10)
- {
- if (coinflip())
- effect = ZIN_CONFUSE;
- else
- effect = ZIN_DAZE;
- }
- else if (check < 15)
- effect = ZIN_CONFUSE;
- else
- {
- if (one_chance_in(3))
- effect = ZIN_PARALYSE;
- else
- effect = ZIN_CONFUSE;
- }
- }
- else
- {
- // This is the path for 'smiting' effects.
- // Their degree is only greater than 1 if
- // they're unable to be redeemed.
- if (check < 5)
- {
- if (coinflip())
- effect = ZIN_BLEED;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 10)
- {
- if (one_chance_in(3))
- effect = ZIN_BLIND;
- else if (mons_antimagic_affected(mon))
- effect = ZIN_ANTIMAGIC;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else if (check < 15)
- {
- if (one_chance_in(3))
- effect = ZIN_BLIND;
- else if (coinflip())
- effect = ZIN_PARALYSE;
- else
- effect = ZIN_MUTE;
- }
- else
- {
- if (coinflip())
- effect = ZIN_MAD;
- else
- effect = ZIN_DUMB;
- }
- }
- break;
-
- case RECITE_CHAOTIC:
- if (check < 5)
- {
- // nastier -- fallthrough if immune
- if (coinflip() && mon->can_bleed())
- effect = ZIN_BLEED;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 10)
- {
- if (coinflip())
- effect = ZIN_SILVER_CORONA;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 15)
- {
- if (coinflip())
- effect = ZIN_IGNITE_CHAOS;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else
- effect = ZIN_SALTIFY;
- break;
-
- case RECITE_IMPURE:
- // Many creatures normally resistant to rotting are still affected,
- // because this is divine punishment. Those with no real flesh are
- // immune, of course.
- if (check < 5)
- {
- if (coinflip() && mon->can_bleed())
- effect = ZIN_BLEED;
- else
- effect = ZIN_SMITE;
- }
- else if (check < 10)
- {
- if (coinflip() && mon->res_rotting() <= 1)
- effect = ZIN_ROT;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else if (check < 15)
- {
- if (mon->undead_or_demonic() && coinflip())
- effect = ZIN_HOLY_WORD;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else
- effect = ZIN_SALTIFY;
- break;
-
- case RECITE_UNHOLY:
- if (check < 5)
- {
- if (mons_intel(mon) > I_INSECT && coinflip())
- effect = ZIN_DAZE;
- else
- effect = ZIN_CONFUSE;
- }
- else if (check < 10)
- {
- if (coinflip())
- effect = ZIN_CONFUSE;
- else
- effect = ZIN_SILVER_CORONA;
- }
- // Half of the time, the anti-unholy prayer will be capped at this
- // level of effect.
- else if (check < 15 || coinflip())
- {
- if (coinflip())
- effect = ZIN_HOLY_WORD;
- else
- effect = ZIN_SILVER_CORONA;
- }
- else
- effect = ZIN_SALTIFY;
- break;
-
- case NUM_RECITE_TYPES:
- die("invalid recite type");
- }
-
+ effect = zin_choose_effect(prayertype,check,degree,mon);
// And the actual effects...
switch (effect)
- {
+ {
case ZIN_NOTHING:
break;
-
case ZIN_DAZE:
if (mon->add_ench(mon_enchant(ENCH_DAZED, degree, &you,
(degree + random2(spellpower)) * BASELINE_DELAY)))
diff --git a/crawl-ref/source/godabil.h b/crawl-ref/source/godabil.h
index e913716..c991b9c 100644
--- a/crawl-ref/source/godabil.h
+++ b/crawl-ref/source/godabil.h
@@ -14,9 +14,8 @@ class stack_iterator;
string zin_recite_text(const int seed, const int prayertype, int step);
bool zin_check_able_to_recite(bool quiet = false);
-int zin_check_recite_to_monsters(recite_type *prayertype);
-bool zin_recite_to_single_monster(const coord_def& where,
- recite_type prayertype);
+int zin_check_recite_to_monsters();
+bool zin_recite_to_single_monster(const coord_def& where);
void zin_recite_interrupt();
bool zin_vitalisation();
void zin_remove_divine_stamina();
diff --git a/crawl-ref/source/player-reacts.cc b/crawl-ref/source/player-reacts.cc
index a1fa4d9..4137c1b 100644
--- a/crawl-ref/source/player-reacts.cc
+++ b/crawl-ref/source/player-reacts.cc
@@ -356,7 +356,7 @@ static bool _check_recite()
static int _zin_recite_to_monsters(coord_def where, int prayertype, int, actor *)
{
ASSERT_RANGE(prayertype, 0, NUM_RECITE_TYPES);
- return zin_recite_to_single_monster(where, (recite_type)prayertype);
+ return zin_recite_to_single_monster(where);
}
diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc
index eb04dd1..1f5a10c 100644
--- a/crawl-ref/source/spl-summoning.cc
+++ b/crawl-ref/source/spl-summoning.cc
@@ -2469,7 +2469,7 @@ spret_type cast_spellforged_servitor(int pow, god_type god, bool fail)
return SPRET_SUCCESS;
}
-static int _abjuration(int pow, monster *mon)
+int _abjuration(int pow, monster *mon)
{
// Scale power into something comparable to summon lifetime.
const int abjdur = pow * 12;
diff --git a/crawl-ref/source/spl-summoning.h b/crawl-ref/source/spl-summoning.h
index dedc626..0637bcc 100644
--- a/crawl-ref/source/spl-summoning.h
+++ b/crawl-ref/source/spl-summoning.h
@@ -95,7 +95,7 @@ bool twisted_resurrection(actor *caster, int pow, beh_type beha,
unsigned short foe, god_type god, bool actual = true);
spret_type cast_haunt(int pow, const coord_def& where, god_type god, bool fail);
-
+int _abjuration(int pow, monster *mon);
spret_type cast_abjuration(int pow, const coord_def& where, bool fail = false);
spret_type cast_aura_of_abjuration(int pow, bool fail = false);
void do_aura_of_abjuration(int delay);
--
1.8.1.2
|